Files
vmall/openspec/changes/replace-mock-api-wave-1/specs/frontend-mall/spec.md
T
james e0e833d0e5 feat(mall): serve catalog and currency from the live API
Wave 1 of replacing the fixed-data mock adapter. The mall now selects its API
adapter per domain, with catalog and currency served live while auth, cart,
orders, shipments and invoices stay on fixed data.

Backend:
- seed the 6 x 2 x 2 category tree as reference data (migration 0005). The API
  exposes no category write route, so this cannot come from the seed script
- filter public product listing by the category subtree with a recursive CTE,
  matching the mock's existing behaviour instead of exact-match
- add sort=price with order=asc|desc, validated by hand so an unsupported value
  returns the project's ApiError 400 shape rather than axum's own rejection

Mall:
- replace the all-or-nothing mockApi boolean with a liveDomains list composed
  through a typed per-domain pick map
- source home floors, the category menu, search and product detail from the
  catalog API; banners, promos, quick links, store card and comment/coupon
  content stay local display-only content
- drop the brand facet and the sales/comments sorts: no backend model backs them
- fix salesOf/commentCountOf, which parsed digits out of the product id and so
  rendered "NaN sold" for live UUID ids; they now hash the id

Seed: 24 products across 4 shops, idempotent on re-run.

Note: the mall defaults to a live catalog, so pnpm dev:mall now expects the API
to be running; set NUXT_PUBLIC_LIVE_DOMAINS to an empty array for all-mock work.

OpenSpec change: openspec/changes/replace-mock-api-wave-1
2026-09-17 15:15:25 +00:00

3.6 KiB

Spec Delta

MODIFIED Requirements

Requirement: Mock API adapter

The mall SHALL select its API adapter per domain, so one domain can be served by the live backend while the others stay on fixed data. The mall SHALL still ship a fixed-data adapter implementing the whole @vmall/shared API client surface, and the live/fixed choice SHALL be configurable per domain without changing page call sites. The fixed-data adapter SHALL remain able to serve every domain when the live backend is unavailable.

Scenario: mall runs without backend

  • WHEN the mall starts with the API service unavailable and every domain configured to fixed data
  • THEN browsing, cart, checkout, payment, orders and invoice pages return deterministic fixed data and remain functional

Scenario: domains migrate independently

  • WHEN the live backend serves the catalog and currency domains while auth, cart, orders, shipments and invoices remain on fixed data
  • THEN browsing and prices come from the backend while those other flows keep working against fixed data

Requirement: Mock PC home page

The mall home page SHALL render a hero row composed of a pinned 240px category sidebar on the left and a hero carousel filling the remainder of the 1200px grid, both 450px tall and occupying layout space (not overlaid). The sidebar SHALL list the catalog's top-level categories with up to three child links each; hovering a top-level category SHALL expand the mega-menu panel to the right over the carousel. Banner images SHALL render at fixed 450px height, center-cropped horizontally to the narrower carousel width. Below the hero, the page SHALL render a six-item quick-link strip with promotion tiles and bilingual product floors, where each floor's products come from the catalog API while the banner, promotion, quick-link and floor advert assets remain local content.

Scenario: shopper lands on home

  • WHEN / loads
  • THEN the category sidebar is visible to the left of the carousel without any hover or click, the carousel renders center-cropped banners at 450px height, and the quick links, promotions and every non-empty product floor render, with floor products sourced from the catalog API

Scenario: sidebar stays while scrolling

  • WHEN a shopper scrolls the home page beyond 200px
  • THEN the category sidebar remains rendered in the hero row and does not auto-hide

Scenario: expand a category

  • WHEN a shopper hovers a top-level category in the pinned sidebar
  • THEN the mega-menu panel expands to the right, overlaying the carousel with that category's child and grandchild links from the catalog API

Requirement: Product discovery pages

The mall SHALL provide /search with breadcrumb, category and sort controls, a five-column desktop product grid, pagination and an empty state, listing products from the catalog API filtered by the selected category's subtree. The sort control SHALL offer newest-first and price ascending/descending only. It SHALL provide /goods/[id] rendering product and SKU data from the catalog API with image gallery/zoom, bilingual name/subtitle, integer-minor-unit prices, attribute and SKU selection, stock-aware quantity, store card, and detail/comments/after-sale tabs whose comment, coupon and sales content stays local display-only content.

Scenario: filter and inspect a product

  • WHEN a shopper filters the search page by a parent category and opens a product
  • THEN products from that category and its descendants are listed, and selecting an in-stock SKU updates the displayed price, stock and cart target from the catalog API