Files
vmall/openspec/changes/archive/2026-09-17-replace-mock-api-wave-1/tasks.md
T
james 2136a48fbe chore(openspec): archive the mock-migration waves and green the spec set
Archive the three completed changes behind replace-mock-api-wave-1/2/3. Each
merge applied cleanly to the main specs:

- catalog gains the Public product browse requirement (subtree filtering and
  price sort)
- frontend-mall picks up the per-domain adapter, the pinned home page, the
  discovery-page changes, the live auth panels and the live transaction flows
- cart's Server-side cart requirement now documents the shop and stock carried
  by every line

Also replace the TBD Purpose placeholder in all eleven specs with a one-line
description of what each capability covers. Those placeholders predate this
work and were the only reason `openspec validate --all --strict` reported
0 passed / 11 failed; it now reports 11 passed / 0 failed.
2026-09-17 16:36:10 +00:00

3.9 KiB

Tasks

1. Backend: catalog browse

  • 1.1 Add an append-only migration seeding child and grandchild categories under the existing electronics, fashion and home-living rows, matching the mock's 3-level shape; verify GET /api/categories returns more than 3 rows with populated parent_id
  • 1.2 Replace the exact p.category_id = $1 filter in apps/api/src/routes/catalog.rs with a WITH RECURSIVE subtree CTE shared by the count and page queries; verify a parent-category request returns its descendants' products
  • 1.3 Add optional sort=price and order=asc|desc to list_products, ordering by each product's lowest active SKU price with NULLS LAST, and reject any other value with an ApiError 400 whose body is {"error":{"code","message"}}; verify the 400 shape with curl
  • 1.4 Extend apps/api/tests/catalog.rs with cases for subtree listing, ascending/descending price order and the rejected-sort 400; verify cargo test -p vmall-api is green and repeatable

2. Shared contract

  • 2.1 Add optional sort and order to ProductListQuery in packages/shared/src/api.ts and pass them through in createApi.listProducts; verify pnpm --filter @vmall/mall build still type-checks

3. Demo data

  • 3.1 Grow scripts/seed-demo.mjs to roughly 24 bilingual products spread across the new category tree plus 4 shops, keeping the slug-lookup idempotency; verify a second run reports no duplicate creates and GET /api/products?per_page=100 returns a full first page

4. Mall: per-domain adapter switch

  • 4.1 Replace the mockApi boolean in apps/mall/plugins/api.ts with a liveDomains list defaulting to ["catalog", "currency"], composing the live client over the fixed-data base through a typed per-domain pick map (no any); verify catalog requests hit :8080 while getCart still resolves from fixed data with the backend stopped

5. Mall: rewire browse surfaces

  • 5.1 apps/mall/pages/index.vue: build floors from listCategories plus listProducts per category, leaving banners, promos, quick links and floor advert art local; verify every non-empty floor renders live products
  • 5.2 apps/mall/components/shell/CategoryMenu.vue: source the tree from listCategories, keeping the header dropdown mode and the pinned home mode intact; verify the pinned sidebar shows children from the API
  • 5.3 apps/mall/pages/search.vue: list through listProducts with the selected category's subtree and the new sort, and delete the brand facet plus the sales/comments sort options; verify filtering by a parent category lists descendant products
  • 5.4 apps/mall/pages/goods/[id].vue: load the product and SKUs through getProduct, keeping the comment, coupon and sales-rail sections on local display-only content; verify an in-stock SKU selection updates price, stock and the cart target
  • 5.5 Remove only the catalog helpers that lost their last consumer (topCategories, childCategories, homeFloors, MOCK_BRANDS, brandOf, HomeFloor, MockBrand) from apps/mall/mock/data.ts; amended from the original wording, which also removed MOCK_PRODUCTS and would have broken the rollback the Mock API adapter requirement promises, so MOCK_PRODUCTS/searchMockProducts/productById stay; verify pnpm --filter @vmall/mall build passes with no page importing a removed symbol

6. Verification

  • 6.1 Run pnpm --filter @vmall/mall build, pnpm --filter @vmall/shop-admin build and pnpm --filter @vmall/admin build, since the shared contract changed; verify all three pass
  • 6.2 With the live backend and seeds running, verify in a browser that home, search, product detail and the pinned category menu render live data, and that no console errors appear
  • 6.3 Stop the backend and confirm the mall still starts and the unmigrated domains (auth, cart, orders, invoices) keep working from fixed data; verify the browse pages degrade without crashing