Files
vmall/openspec/changes/archive/2026-09-17-replace-mock-api-wave-3/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

35 lines
3.9 KiB
Markdown

# Tasks
## 1. Contract and backend cart view
- [x] 1.1 Add `shop_id`, `shop_name` and `stock` to `CartItemView` and to the `cart_view` SELECT in `apps/api/src/cart.rs` (the query already joins `products`, `shops` and `skus`); verified `GET /api/cart` returns a distinct shop and the SKU's stock per line for a two-shop cart
- [x] 1.2 Add `shop_id`, `shop_name` and `stock` to `CartItem` in `packages/shared/src/types.ts`. Also had to teach the fixed-data adapter to construct the new fields (`apps/mall/mock/api.ts`) and bump its persisted-state key to `v2`, because a cart saved by an older build is no longer a valid `CartItem[]`; verified the mall, shop-admin and admin builds all pass
- [x] 1.3 Make `Shipment.items` optional and `Invoice.invoice_no` nullable in `packages/shared/src/types.ts`. `Invoice` was declared twice in that file and TypeScript merges duplicate interfaces, so the duplicate was removed for the change to take effect at all; verified against a live shipment (no `items` key) and a requested invoice (`invoice_no: null`)
- [x] 1.4 Extend the two-shop cart test in `apps/api/tests/orders.rs` to assert each line reports its own shop, a bilingual shop name and the SKU stock; verified `cargo test -p vmall-api --test orders` is green
## 2. Anonymous add-to-cart gate
- [x] 2.1 Send a signed-out shopper to `/login?redirect=<current path>` when `addCartItem` answers 401, accepting only same-origin paths; verified the parameter is dropped for `//host` and absolute URLs
- [x] 2.2 Have `pages/login.vue` return the shopper to a valid `redirect` target after a successful sign-in; verified the round trip from a product page
## 3. Cart surface
- [x] 3.1 Group `pages/cart.vue` by the line's own `shop_id` and label each group with `shop_name`, dropping the `productById`/`storeById` lookups; verified a two-shop cart renders two groups labelled with the live names (`Aurora Digital`, `Demo Store`)
- [x] 3.2 Cap the quantity stepper with the line's `stock` instead of the 999 fallback, and use the line's `image` for the thumbnail; verified the caps read `12` and `25` from the live cart rather than 999
## 4. Transaction surfaces
- [x] 4.1 `pages/checkout/index.vue`: group by the cart line's shop and image rather than the mock catalog, keeping `MOCK_ADDRESSES` as the address source; verified the checkout preview groups correctly and the order submits
- [x] 4.2 `pages/checkout/pay.vue` and `pages/user/orders/index.vue`: drop the `storeById` lookups and keep the existing generic store label until Wave 4; verified order cards render with the placeholder and without errors
- [x] 4.3 `pages/user/invoices.vue`: render a placeholder when `invoice_no` is null, mirroring the existing `order_no` handling; verified the invoices table shows `—` for a requested-but-unissued invoice alongside real `INV…` numbers
## 5. Flip the domains
- [x] 5.1 Add `cart`, `orders`, `shipments` and `invoices` to the default `liveDomains` in `apps/mall/nuxt.config.ts` in one commit with the page changes above; verified every one of those pages now reads from `:8080`
## 6. Verification
- [x] 6.1 Run `pnpm --filter @vmall/mall build` plus the shop-admin and admin builds, since the shared contract changed; all three pass
- [x] 6.2 With the backend seeded, ran one purchase in a browser: signed in, added from a product page, saw a two-shop cart group correctly, checked out, paid, then confirmed the order. The merchant half of the chain (ship → issue invoice) has no mall UI and was driven through the API, after which the order page showed the live shipment, confirming delivery moved the order to `completed`, and the invoices page listed the issued numbers. The only console entries were the header's signed-out `GET /api/cart` 401 (caught, count 0) and no hydration warnings
- [x] 6.3 Verified the rollback: with every domain set to fixed data and the backend stopped, sign-in, add-to-cart, cart grouping, the stock cap and checkout all still work from localStorage