management: produce catalog v3 — columns, form fields, export mapping #42

Closed
opened 2026-08-27 06:35:51 +00:00 by yuris · 0 comments
Owner

Producer side of #41. apps/management/lib/db/schema.ts inventory already has brand, part_number, category, weight_grams, shippable, install_service (migration drizzle/0010_new_frog_thor.sql), so this adds the four remaining pieces and rewires the export.

Schema

Generated, committed migration adding to inventory, all nullable or defaulted so existing rows are safe:

  • oem_numbers text[] not null default '{}' — mirror the existing images column pattern.
  • fitment text[] not null default '{}'.
  • price_updated_at timestamp — set it in updateInventory whenever sellPrice changes, so the storefront date is real rather than operator-maintained.
  • availability: derive, do not store a third state naively. habis and ready already fall out of stock > 0. indent is the new information, so add allow_indent boolean not null default false meaning "orderable when out of stock". Export then maps stock > 0 ? "ready" : allowIndent ? "indent" : "habis". One boolean column, no dual source of truth against stock, and no way for availability to contradict the stock ledger.

Wiring

  • lib/db/validators.ts — InventoryItemSchema, CreateInventorySchema, UpdateInventorySchema.
  • lib/catalog.ts#getPublicCatalog — select and map the new columns, emit availability per the rule above, drop inStock. buyPrice, avgCost, suppliers and the raw stock number stay out of the payload.
  • lib/store/deploy.ts — add the new columns to STOREFRONT_COLUMNS so edits actually trigger a republish.
  • Forms: app/(dashboard)/stok/add-inventory-modal.tsx and inventory-edit-form.tsx — repeatable-row inputs for fitment and oemNumbers (same shape as the existing images URL rows) and an allow_indent checkbox. Read-only display in inventory-details-sheet.tsx.
  • MCP: lib/mcp/tools/inventory.ts create/update mirror the new fields.

Acceptance

pnpm --filter garage test passes with lib/catalog.test.ts extended: stock: 0 + allowIndent: true → "indent"; stock: 0 + false → "habis"; stock > 0 → "ready" regardless of the flag; price_updated_at is emitted as an ISO date and is null when sell_price is 0; oem_numbers/fitment round-trip and default to []. lib/store/deploy.test.ts asserts the new columns are storefront-affecting. Ship together with #41 — the strict contract means a half-landed bump breaks the store build.

Producer side of #41. `apps/management/lib/db/schema.ts` `inventory` already has `brand`, `part_number`, `category`, `weight_grams`, `shippable`, `install_service` (migration `drizzle/0010_new_frog_thor.sql`), so this adds the four remaining pieces and rewires the export. ### Schema Generated, committed migration adding to `inventory`, all nullable or defaulted so existing rows are safe: - `oem_numbers text[] not null default '{}'` — mirror the existing `images` column pattern. - `fitment text[] not null default '{}'`. - `price_updated_at timestamp` — set it in `updateInventory` whenever `sellPrice` changes, so the storefront date is real rather than operator-maintained. - availability: **derive, do not store a third state naively.** `habis` and `ready` already fall out of `stock > 0`. `indent` is the new information, so add `allow_indent boolean not null default false` meaning "orderable when out of stock". Export then maps `stock > 0 ? "ready" : allowIndent ? "indent" : "habis"`. One boolean column, no dual source of truth against `stock`, and no way for availability to contradict the stock ledger. ### Wiring - `lib/db/validators.ts` — `InventoryItemSchema`, `CreateInventorySchema`, `UpdateInventorySchema`. - `lib/catalog.ts#getPublicCatalog` — select and map the new columns, emit `availability` per the rule above, drop `inStock`. `buyPrice`, `avgCost`, suppliers and the raw `stock` number stay out of the payload. - `lib/store/deploy.ts` — add the new columns to `STOREFRONT_COLUMNS` so edits actually trigger a republish. - Forms: `app/(dashboard)/stok/add-inventory-modal.tsx` and `inventory-edit-form.tsx` — repeatable-row inputs for `fitment` and `oemNumbers` (same shape as the existing `images` URL rows) and an `allow_indent` checkbox. Read-only display in `inventory-details-sheet.tsx`. - MCP: `lib/mcp/tools/inventory.ts` create/update mirror the new fields. ### Acceptance `pnpm --filter garage test` passes with `lib/catalog.test.ts` extended: `stock: 0` + `allowIndent: true` → `"indent"`; `stock: 0` + false → `"habis"`; `stock > 0` → `"ready"` regardless of the flag; `price_updated_at` is emitted as an ISO date and is null when `sell_price` is 0; `oem_numbers`/`fitment` round-trip and default to `[]`. `lib/store/deploy.test.ts` asserts the new columns are storefront-affecting. Ship together with #41 — the strict contract means a half-landed bump breaks the store build.
yuris closed this issue 2026-08-27 11:18:25 +00:00
Sign in to join this conversation.
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#42
No description provided.