35 lines
1.3 KiB
Markdown
35 lines
1.3 KiB
Markdown
# Domain: Catalog
|
|
|
|
Products, SKUs, categories, brands (`modules/product/`, `category/`, `brand/`).
|
|
|
|
## Shape
|
|
|
|
- `products`: shop-scoped, bilingual name/description, images JSONB array,
|
|
status draft → published (publish requires ≥1 active SKU with price > 0),
|
|
optional `freight_template_id` (must belong to the same shop).
|
|
- `skus`: per-product purchasable units — code, attributes JSONB,
|
|
`price_minor` + `currency`, guarded `stock`, `weight_grams` (freight).
|
|
- `categories`: tree with subtree CTE for filtering; seeded reference tree.
|
|
- `brands`: platform-managed ordered registry, whole-list replacement via
|
|
`PUT /admin/brands`.
|
|
|
|
## Public reads
|
|
|
|
`GET /products` (published + active shop only; filters: category subtree,
|
|
shop, name ILIKE, brand; sort newest/price/sales) and
|
|
`GET /products/{idOrSlug}`. `sold_count` is computed from paid order items.
|
|
Merchant reads/writes go through `/shop/products*` with `own_shop` scoping.
|
|
|
|
## Conventions
|
|
|
|
- Every Product query uses explicit column lists — when adding a product
|
|
column, update `PRODUCT_COLS` and the literal lists in `service.rs`
|
|
(search: `category_id, brand_id, slug`).
|
|
- SKU upsert is keyed on `(product_id, sku_code)`.
|
|
- Stock is the only concurrently decremented counter today; always the
|
|
guarded-decrement pattern.
|
|
|
|
## Key files
|
|
|
|
See `docs/code_index/catalog.md`.
|