Catalog and products (Admin)
Executive summary
Section titled “Executive summary”Admin catalog covers list, create, edit, and detail for products with zone/store scoping, status/stock tabs, and module guard item. This page is the operator-facing map; API enums and guards are documented in backend code and Swagger—see API conventions.
Goals and non-goals
Section titled “Goals and non-goals”| Goals | Non-goals |
|---|---|
| Enable consistent product CRUD within allowed zone/store | Replace the OpenAPI schema for field-level validation |
| Surface list/detail UX (tabs, JSON blocks) | Cover vendor catalog parity line-by-line |
Current platform behavior
Section titled “Current platform behavior”- Routes under
/dashboard/products; list supports filters/tabs; detail may show JSON/metadata blocks where implemented. - Access requires JWT
modulescontaining catalogitem(ornull= full)—else 403 from API (Roles). - Admin products list query
admin_catalog_scope: whenonly, the API returnsadmin_onlyitems across the platform and does not applyvendor_id,store_id, ortemplates_onlynarrowing (vendor/store remain meaningful on writes and on other list modes).
Sequence: happy path
Section titled “Sequence: happy path”- Open Products list → search/filter → open row.
- Create → fill form → save → redirect to detail or list.
- Edit → update fields → save; status changes per business rules.
Security and operations
Section titled “Security and operations”- Zone admins must only attach products to stores in zone—backend enforces; UI should not expose out-of-zone store IDs.
- Large JSON or media fields: follow ops policy for PII and asset storage.
Test scenarios (UAT / QA)
Section titled “Test scenarios (UAT / QA)”| ID | Scenario | Expected |
|---|---|---|
| CP1 | List with permission | Rows load; pagination works |
| CP2 | Create product in allowed store | Success; visible in list |
| CP3 | User without item | API 403 or UI block |
Routes
Section titled “Routes”| Path | Purpose |
|---|---|
/dashboard/products | Product list |
/dashboard/products/create | Create product |
/dashboard/products/:id | Product detail |
/dashboard/products/:id/edit | Edit product |
List (/dashboard/products)
Section titled “List (/dashboard/products)”Status and stock tabs
Section titled “Status and stock tabs”The UI combines record status and stock state filters (aligned with admin catalog API tuples):
Status (record)
| Filter | Meaning |
|---|---|
all | Any status |
active | Published / active items |
draft | Draft items |
archived | Archived items |
Stock
| Filter | Meaning |
|---|---|
all | Any stock state |
in_stock | In stock |
low_stock | Low stock |
out_of_stock | Out of stock |
Search, filters, actions
Section titled “Search, filters, actions”- Search — debounced (400ms).
- Filters — additional list filters (vendor, store, category, sort, etc.) via the filters popover; active filter count is shown on the toolbar.
- Pagination — 10 items per page; changing tab, search, or filters resets the page.
- Row actions — view, edit, duplicate, delete (with confirmation modals for duplicate/delete).
Overview stats
Section titled “Overview stats”Stat cards summarize list KPIs from fetchAdminProductsOverview (counts and stock-related figures as returned by the API).
Record status (database)
Section titled “Record status (database)”The legacy items.status column uses integer values mapped in the backend as AdminItemRecordStatus:
| Value | Enum | Typical label |
|---|---|---|
0 | Draft | draft |
1 | Active | active |
2 | Archived | archived |
See apps/backend/src/modules/admin/enums/admin-product.enums.ts (mapAdminItemStatusToLabel).
Create, detail, and edit
Section titled “Create, detail, and edit”Create and edit flows use the shared dashboard form patterns (validation, store assignment, pricing, JSON blocks where exposed). Store and module rules for writes are enforced in the backend; see Tenancy — stores and outlets and Admin panel overview.
On create/edit, the form uses tabs synced to the URL query tab (basic, pricing, inventory, variants, meta). Refreshing or sharing the link restores the active section. Tab panels stay mounted (hidden with CSS) so warehouse stock fields are not dropped on submit when another tab is selected.
For admin-only items, platform warehouse stock is edited on the Stores & inventory tab. Each warehouse × variant row has stock quantity, optional stock alert (stocks.low_stock_threshold), and location (bin/shelf). Alerts are independent per row (not one shared field). Submit sends product_warehouse_stocks for a single default catalog SKU, or variation_warehouse_stocks when multiple catalog variants exist (conversion unit rows are excluded from that branch).
Detail pages follow the shared StatTile / DashboardPanel / DetailField layout used across admin and vendor where applicable.
Variations — unit, pack, and base SKU (API vs admin UI)
Section titled “Variations — unit, pack, and base SKU (API vs admin UI)”The backend persists per-variation fields on item_variations (sell unit_id override, units_per_pack, optional base_variation_id / API base_variant). Admin and vendor product detail APIs expose these on each object in variations when rebuilt from persisted rows.
- Admin web form: catalog variant rows are generated as the Cartesian product of sell units (base
unit_idplus optional conversion unit rows) and attribute value groups (choice_options). When only the base unit applies, variant keys stay attribute-only (e.g.Red-S). With multiple sell units, keys are prefixed with the unit label (e.g.Case×24-Red-S). Conversion unit rows are edited in a separate section and are not listed in the SKU/price/stock tables. - Vendor catalog edit still offers additional per-line controls (e.g. base variant pickers) where admin UI is not yet line-for-line.
- Deep dive: Catalog — variant sell unit and pack.
Module access
Section titled “Module access”Catalog APIs expect the item module key for non–Master Admin roles (modules on the admin JWT). Master Admin uses modules === null. See Roles.