SRV-11 — Catalog module
Brands, category tree with sub-categories, products, variants, images, specs, per-category filterable attributes, statuses (incl. automatic out-of-stock), visibility, guest-safe search with combinable filters, facets with counts and barcode lookup.
| Field | Details |
|---|---|
| Task code | SRV-11 |
| Phase | P1 — V1 build & integration |
| Product scope | V1 |
| Status | Done (Sun 18 Oct 2026) |
| Start | Sun 18 Oct 2026 |
| Due | Sun 18 Oct 2026 |
| Responsible | Anis — Full-stack developer |
| Co-responsible | — |
| Effort | 1.5 person-day(s) planned · 7 from scratch · size S |
| Area · app | Server · server |
| Depends on | SRV-07 |
| Unblocks | SRV-12, SRV-13, SRV-27, SRV-39, SRV-40 |
| Milestones | — |
Summary
Brands, category tree with sub-categories, products, variants, images, specs, per-category filterable attributes, statuses (incl. automatic out-of-stock), visibility, guest-safe search with combinable filters, facets with counts and barcode lookup.
Description
The catalog is the heart of the reseller experience (cahier §4.3, §5.1, §5.2; CAT-01…CAT-13, AUTH-10). This task builds brands, the category tree with sub-categories, products with variants, images, specifications, barcodes and warranty, the product lifecycle (DRAFT, ACTIVE, HIDDEN, OUT_OF_STOCK set automatically from inventory availability, ARCHIVED), visibility rules per reseller or segment, and the per-category filterable attributes decided on 17 Oct (AttributeDefinition with type, unit and allowed values; VariantAttributeValue validated against it). Reseller-facing procedures are auth: optional and guest-safe: search by name, reference or brand with sort, combinable filters (category and sub-category, brand, attributes, availability, promotion, new arrivals, price range for signed-in users only), catalog.facets with counts, suggestions, barcode lookup, product detail and similar products — prices null with priceLocked for guests and availability only (IN_STOCK/OUT_OF_STOCK), never quantities. Out of scope: price values and resolution (SRV-12), stock quantities (SRV-13), promotions content (SRV-19).
Subtasks
| # | Subtask | Owner |
|---|---|---|
| 1 | Brands and category tree (category → sub-category, ordering via admin.categories.reorder) with admin.brands.crud and admin.categories.crud | Anis |
| 2 | Products and variants (sku, barcode, specs, warranty, images ordering) with admin.products.* and admin.variants.crud | Anis |
| 3 | AttributeDefinition per category (ENUM, NUMBER with unit, BOOLEAN; allowed values; filterable; order) and VariantAttributeValue validation; admin.attributes.crud | Anis |
| 4 | Product lifecycle transitions with permissions and automatic OUT_OF_STOCK ↔ ACTIVE from inventory availability events | Anis |
| 5 | ProductVisibilityRule by reseller or segment applied to every reseller read (CAT-05) | Anis |
| 6 | Search: Postgres full text + pg_trgm + unaccent over name, reference and brand; sorts relevance, newest, popularity, price (signed-in only) | Anis |
| 7 | Combinable filter builder and catalog.facets with multi-select semantics (each facet counted with the other filters applied) for brand, category, sub-category, attribute values, availability, promotion, new arrivals, price range | Anis |
| 8 | Guest-safe response shaping: price null + priceLocked for guests, availability enum only, isFavorite false | Anis |
| 9 | catalog.home, suggest, byBarcode, get, similar (same category/attributes), favorites list/add/remove | Anis |
| 10 | Facet and filter payload review for the mobile filter sheet | Imad |
Deliverables
- apps/server/src/modules/catalog/{brands,categories,products,variants,attributes,search,facets,favorites}.{service,router}.ts
- packages/contracts/src/{catalog.ts,admin/catalog.ts}
- SQL migration for search indexes (GIN tsvector, trigram) and attribute value indexes
Acceptance criteria
- A guest call to catalog.products.list returns products with price null and priceLocked true, and the price-range facet is absent (AUTH-10, PRC-02)
- No catalog response contains a stock quantity; availability is IN_STOCK or OUT_OF_STOCK (STK-07)
- Filtering by sub-category + brand + connector USB-C + power ≥ 20 W returns only matching variants and facet counts reflect the other active filters (CAT-12)
- Setting an attribute value not allowed by its definition returns 422 ATTRIBUTE_VALUE_INVALID (CAT-13)
- A HIDDEN or ARCHIVED product never appears in list, search, facets, favorites or similar products (CAT-04)
- Search and filter p95 under 300 ms server-side on a 5,000-variant dataset (CAT-07, NFR-01)
Requirements covered
| Requirement | Title | Release |
|---|---|---|
| CAT-01 | Brands HOCO, ACEFAST and BOROFONE managed as data | V1 |
| CAT-02 | Category tree (chargers, cables, earphones, power banks, car holders, audio, watches, accessories) | V1 |
| CAT-03 | Product data: brand, reference, name, category, description, characteristics, images, barcode, warranty, variants | V1 |
| CAT-04 | Product lifecycle: draft, active, hidden, out of stock (automatic), archived | V1 |
| CAT-05 | Visibility and activation per reseller or segment | V1 |
| CAT-07 | Catalog browsing and search by name, reference or brand, with sorting; results in under 3 seconds | V1 |
| CAT-08 | Product detail: gallery, specifications, description, prices, availability, quantity limits, similar/complementary products, share | V1 |
| CAT-09 | Favorites | V1 |
| CAT-10 | Barcode scan to find a product | V1 |
| CAT-11 | Home merchandising: popular categories and recommended products (rules-based) | V1 |
| CAT-12 | Advanced, combinable filters on web and mobile: price range, category and sub-category, brand, attributes (power, connector, cable length, colour…), availability, promotion, new arrivals — with result counts | V1 |
| CAT-13 | Filterable product attributes defined per category (type, unit, allowed values) and filled on every variant | V1 |
| AUTH-10 | Guest mode: the reseller app and web can be browsed without an account; prices stay hidden until the visitor signs up and declares a customer type | V1 |
Screens
| Screen | Name | App |
|---|---|---|
| BO-27 | Products list | BO |
| BO-28 | Product editor | BO |
| BO-29 | Brands | BO |
| BO-30 | Categories | BO |
| BO-71 | Product attributes (filters) per category | BO |
API surface
| Endpoint group | Operations |
|---|---|
| Catalog & favorites | 12 |
| Catalog & pricing | 19 |
Test measures
- DB tests for facet counts and filter combinations on a fixed dataset
- Contract test asserting no quantity field in reseller/delegate catalog schemas
- k6 load test of products.list and facets (also reused in SRV-28)
Risks
- Facet queries become slow as attributes grow — materialised attribute value index per variant and caching of facet results per filter hash for 60 s
- Inconsistent attribute data at import — import validation against AttributeDefinition in SRV-27
KPI
- Delivered by Sun 18 Oct 2026 within 1.5 person-day(s).
- Every acceptance criterion above demonstrated before hand-off; linked requirements' acceptance criteria pass.
- Zero open critical defects, permission gaps or data-integrity regressions at sign-off.
Generated from content/plan/tasks.json by scripts/generate-team-tasks.mjs. Dates are computed by the scheduler (Sunday–Thursday weeks, holidays excluded) — change the plan, not this page.
OPS-02 — CI/CD & environments — staging, pre-production, production
GitHub Actions gates, Docker images, Dokploy apps for staging (dev branch) and production (master), domains and TLS, secrets, nightly backups to object storage, docs deployment.
SRV-12 — Pricing engine
Three selling prices per variant (super-gros, demi-gros, détail) chosen by the reseller's customer type, VAT, price history; prices withheld from guests; promotions applied on top by the cart engine.