Persist the modular-monolith decision (ADR 0001 handler/service/repo, ADR 0002 keep REST) with the companion tech spec and the api-architecture OpenSpec capability. Replace the finished mock-migration tracker with docs/TBD-marketing.md listing the backend-less marketing domains still on fixtures (coupons, favorites, account stats, seckill, collective, integral, reviews). README and AGENTS.md point at the new docs.
4.8 KiB
TBD — marketing capabilities with no backend (mall mock holdouts)
The mock→live migration finished at replace-mock-api-wave-7 (address book, 2026-09-18).
Every domain that has an API is live; what follows is what still renders from
apps/mall/mock/data.ts because no backend capability exists for it. Each entry is a
new capability (schema + routes + contract + pages), not a domain flip — pick one up by
opening an OpenSpec change, the same way waves 1–7 did.
How to use: check a box only once the behaviour is implemented and verified against
the live backend (cargo run -p vmall-api, node scripts/seed-demo.mjs), then remove the
mock data and the page's ~/mock/data import in the same change.
Delete this file once every box is checked, or consciously dropped and recorded. The "deliberately out of scope" list at the bottom does not block deleting it.
Mock holdouts with a mall UI today
- Coupons —
user/coupons.vuelistsMOCK_COUPONS;goods/[id].vueshows a claim strip off the same fixture. Missing:coupon_templates(shop-issued: amount/threshold/window/stock),coupons(user-held, order-bound status). APIs:GET /api/coupons(mine),POST /api/coupons/claim(from a template), shop-admin template CRUD, and checkout application (select → discount minor → bind to order). Money math stays minor units. - Favorites —
user/favorites.vuelistsMOCK_FAVORITES(products tab + stores tab);user/index.vuederives counts from it. Missing:favorites(user_id, product_id | shop_id)with a partial unique index per target kind. APIs:GET/POST/DELETE /api/favorites(product & shop variants). - Account stats —
user/index.vueshowsUSER_STATS(balance 128.00, points 2680, frozen 0) andintegral.vuereuses the points figure. Missing: balance/points accounts and ledgers (money_logsin the reference). MVP shape:GET /api/me/statsreturning{ balance_minor, points, frozen_minor }; real ledgers only when a flow (recharge, refund-to-balance, points earn/spend) needs them.
Marketing pages that are display-only mock
These exist as full pages (seckill.vue, collective.vue, integral.vue) linked from
the home navigation; all three read fixtures directly.
- Seckill (秒杀) —
SECKILL_SESSIONS+seckillProducts()(price override, sold %). Missing:seckill_sessions,seckill_products(activity price, isolated stock),GET /api/seckill/sessions, and checkout price resolution honouring the active session. - Collective / 拼团 —
collectiveProducts()(need/joined counts). Missing:collective_activities,collective_groups(open/join/expire, success on fill); orders bind to a group; refund/rollback policy on expiry. - Integral mall / 积分商城 —
INTEGRAL_PRODUCTS+ points fromUSER_STATS. Missing: points ledger (earn/spend),integral_products, points-denominated checkout (integral/ordersin the reference).
Domains the reference has and this MVP does not (no UI here)
Recorded so the gap is explicit, not because all of them belong in scope:
- Reviews / 评价 — no model; the mall presents none (review counts, the detail
page's review tab/summary/replies were removed in wave 6 rather than kept invented).
Missing:
order_comments(order-item bound, rated, replyable), public read on product pages, shop reply, admin moderation. Writing/moderating/displaying reviews is a feature with its own lifecycle. - Distribution / 分销, cashes / 提现, money logs — qwshop user-center modules; no mock, no UI, no model here.
- Help center / articles — nav links exist in the footer (
帮助中心); no article model. Cheap version: static content pages; full version: admin-managed articles. - OAuth login, SMS/captcha — reference
users/oauth+ captcha plugin; here auth is email+password only. - Freight templates / 运费模板 — shop-side shipping-fee rules; checkout currently charges no shipping at all.
Deliberately out of scope — does not block deleting this file
- The fixed-data adapter itself (
apps/mall/mock/api.ts,~/mock/data): the Mock API adapter spec requires it to keep serving every domain as the rollback path. Removing the fixtures above means pages stop reading them; the adapter stays.
Invariants to keep when implementing any box
- Money is
i64minor units + currency code; no float math anywhere. - New user-facing content fields are
{en, zh}JSONB; UI copy goes through$t(). - Contract changes land only in
packages/sharedand all three frontends must still build. - State transitions validate preconditions (
UPDATE ... WHERE status = ...pattern). - Each capability gets its own
openspec/changes/<name>/and archives green.