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.
3.9 KiB
3.9 KiB
Tasks
1. Contract and backend cart view
- 1.1 Add
shop_id,shop_nameandstocktoCartItemViewand to thecart_viewSELECT inapps/api/src/cart.rs(the query already joinsproducts,shopsandskus); verifiedGET /api/cartreturns a distinct shop and the SKU's stock per line for a two-shop cart - 1.2 Add
shop_id,shop_nameandstocktoCartIteminpackages/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 tov2, because a cart saved by an older build is no longer a validCartItem[]; verified the mall, shop-admin and admin builds all pass - 1.3 Make
Shipment.itemsoptional andInvoice.invoice_nonullable inpackages/shared/src/types.ts.Invoicewas 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 (noitemskey) and a requested invoice (invoice_no: null) - 1.4 Extend the two-shop cart test in
apps/api/tests/orders.rsto assert each line reports its own shop, a bilingual shop name and the SKU stock; verifiedcargo test -p vmall-api --test ordersis green
2. Anonymous add-to-cart gate
- 2.1 Send a signed-out shopper to
/login?redirect=<current path>whenaddCartItemanswers 401, accepting only same-origin paths; verified the parameter is dropped for//hostand absolute URLs - 2.2 Have
pages/login.vuereturn the shopper to a validredirecttarget after a successful sign-in; verified the round trip from a product page
3. Cart surface
- 3.1 Group
pages/cart.vueby the line's ownshop_idand label each group withshop_name, dropping theproductById/storeByIdlookups; verified a two-shop cart renders two groups labelled with the live names (Aurora Digital,Demo Store) - 3.2 Cap the quantity stepper with the line's
stockinstead of the 999 fallback, and use the line'simagefor the thumbnail; verified the caps read12and25from the live cart rather than 999
4. Transaction surfaces
- 4.1
pages/checkout/index.vue: group by the cart line's shop and image rather than the mock catalog, keepingMOCK_ADDRESSESas the address source; verified the checkout preview groups correctly and the order submits - 4.2
pages/checkout/pay.vueandpages/user/orders/index.vue: drop thestoreByIdlookups and keep the existing generic store label until Wave 4; verified order cards render with the placeholder and without errors - 4.3
pages/user/invoices.vue: render a placeholder wheninvoice_nois null, mirroring the existingorder_nohandling; verified the invoices table shows—for a requested-but-unissued invoice alongside realINV…numbers
5. Flip the domains
- 5.1 Add
cart,orders,shipmentsandinvoicesto the defaultliveDomainsinapps/mall/nuxt.config.tsin one commit with the page changes above; verified every one of those pages now reads from:8080
6. Verification
- 6.1 Run
pnpm --filter @vmall/mall buildplus the shop-admin and admin builds, since the shared contract changed; all three pass - 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-outGET /api/cart401 (caught, count 0) and no hydration warnings - 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