Files
vmall/openspec/changes/replace-mock-api-wave-6/proposal.md
T
james 65cea42da6 docs(openspec): plan wave 6, brands and real sales
Planning only: proposal, delta specs, design and tasks. No code yet.

This is the last substantive in-scope box in docs/TBD-migrate-wave.md. Wave 1
removed the brand facet and the sales/comments sorts for want of a model; sales
are derivable from order_items and a brand model is a table plus a column, so
both come back for real.

Decisions recorded in the design:

- brands are reference data in their own table with a nullable products.brand_id
  and an ordered replace endpoint, mirroring categories and storefront content
- a "sale" is a unit on an order that reached payment; pending and cancelled
  orders do not count, so an abandoned checkout cannot inflate the figure
- sold_count is computed per read rather than stored, so it cannot drift from
  the orders that produced it
- the review UI is removed rather than relabelled: the mall attributes invented
  comments to named shoppers and shows a "good rate", which a migration that
  makes everything else real has no business keeping on screen. Reviews are
  recorded as a separate future capability

openspec validate --strict passes and the change is ready to apply.
2026-09-17 17:17:52 +00:00

2.1 KiB

Proposal

Why

Wave 1 removed the brand facet and the sales/comments sorts because nothing backed them. Two of those three gaps now close for real: sales derive from order_items, and a brand model is a small table plus a product column.

What Changes

  • Add a brands table (bilingual name, slug) and products.brand_id, with a public GET /api/brands, a brand_id filter on listProducts, and the search page's brand facet restored.
  • Manage brands with PUT /api/admin/brands, a transactional ordered replace like storefront content, and seed the demo products' brands.
  • Add sort=sales to listProducts, computed from order_items over orders that reached payment, and carry a real sold_count on product payloads instead of the mall's hash-derived figure.
  • Show that real sold count on product cards and the product detail page.
  • BREAKING (display): remove the review UI — the card's review figure and the product detail page's reviews tab — because a reviews capability does not exist and the mall currently presents invented reviewers and ratings as fact.
  • Keep the detail page's after-sale tab, which shows the shop's real copy.

Capabilities

New Capabilities

  • brand: the product brand registry — a bilingual, admin-managed list that products reference and shoppers filter by.

Modified Capabilities

  • catalog: public listing filters by brand and can sort by real sales, and product payloads report a sold count.
  • frontend-mall: the search page offers the brand facet and a sales sort again, and the product detail page no longer presents reviews.

Impact

A migration and new route module; packages/shared/src/{api,types}.ts; pages/search.vue, components/ui/ProductCard.vue, pages/goods/[id].vue; scripts/seed-demo.mjs; the mall's fixed-data adapter. The contract change rebuilds all three frontends.

Non-goals

No reviews capability: writing and moderating reviews is a feature, not a migration, and it is recorded as future work. No change to the seckill, collective or integral pages, nor to coupons, favourites, addresses or the cookie.