Extract the public catalog contract into a shared package (#7) #11

Merged
yuris merged 1 commit from issue-7-shared-catalog into main 2026-07-17 20:25:35 +00:00
Owner

Closes #7.

What

Creates packages/catalog (@garage/catalog) as the single, versioned, runtime-validated catalog contract consumed by both apps.

  • Moves the zod schema (PublicCatalogSchema/PublicCatalogItemSchema), product/response types, and the strict parseCatalog parser into the package.
  • Management produces the public catalog response via the shared zod schema (lib/catalog.ts, API route, tests import from @garage/catalog).
  • Store validates responses at the HTTP trust boundary via the shared strict parser; fetchCatalog stays app-local.
  • Both apps depend via workspace:* and declare transpilePackages: ["@garage/catalog"].
  • Strict validation preserved verbatim: exact fields, schema version 1, ISO timestamps, slug pattern, product types, non-empty image strings, duplicate-slug rejection, slug-sorted output.
  • Parser tests moved into the package; app-specific fetch (store) and API/auth (management) tests retained.

Acceptance criteria

  • No duplicate catalog response or product type definitions remain in either app.
  • Invalid/incompatible responses rejected by the store (package parser tests).
  • Management output validates against the same contract (shared schema).
  • A change to packages/catalog marks both apps affected (both list it as a workspace:* dependency).
  • Schema version 1 remains compatible.

Verification

  • @garage/catalog tests: 5 passed.
  • Store tests: 6 passed. Management tests: 30 passed.
  • Store production build (static export) and management build (standalone) both succeed with the shared package transpiled/traced.
Closes #7. ## What Creates `packages/catalog` (`@garage/catalog`) as the single, versioned, runtime-validated catalog contract consumed by both apps. - Moves the zod schema (`PublicCatalogSchema`/`PublicCatalogItemSchema`), product/response types, and the strict `parseCatalog` parser into the package. - **Management** produces the public catalog response via the shared zod schema (`lib/catalog.ts`, API route, tests import from `@garage/catalog`). - **Store** validates responses at the HTTP trust boundary via the shared strict parser; `fetchCatalog` stays app-local. - Both apps depend via `workspace:*` and declare `transpilePackages: ["@garage/catalog"]`. - Strict validation preserved verbatim: exact fields, schema version 1, ISO timestamps, slug pattern, product types, non-empty image strings, duplicate-slug rejection, slug-sorted output. - Parser tests moved into the package; app-specific fetch (store) and API/auth (management) tests retained. ## Acceptance criteria - [x] No duplicate catalog response or product type definitions remain in either app. - [x] Invalid/incompatible responses rejected by the store (package parser tests). - [x] Management output validates against the same contract (shared schema). - [x] A change to `packages/catalog` marks both apps affected (both list it as a `workspace:*` dependency). - [x] Schema version 1 remains compatible. ## Verification - `@garage/catalog` tests: 5 passed. - Store tests: 6 passed. Management tests: 30 passed. - Store production build (static export) and management build (standalone) both succeed with the shared package transpiled/traced.
Move the versioned public catalog schema, product types, and the strict
response parser into a shared workspace package consumed by both apps:

- Management produces the public catalog response via the shared zod schema.
- Store validates responses at the HTTP trust boundary via the shared strict
  parser (exact fields, schema version, timestamps, slugs, types, images,
  duplicate-slug rejection preserved).
- Both apps depend on @garage/catalog via workspace:* and transpilePackages.
- Parser tests move to the package; app-specific fetch/API tests stay put.
yuris merged commit 9abbe8327d into main 2026-07-17 20:25:35 +00:00
yuris deleted branch issue-7-shared-catalog 2026-07-17 20:25:35 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
yuris/garage!11
No description provided.