Files
vmall/docs/TBD-marketing.md
T
Chengdong Zhang e10cae5789 docs: API architecture ADRs, tech spec, and marketing capability tracker
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.
2026-09-18 16:00:31 +08:00

83 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 17 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.vue` lists `MOCK_COUPONS`; `goods/[id].vue` shows 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.vue` lists `MOCK_FAVORITES` (products tab +
stores tab); `user/index.vue` derives 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.vue` shows `USER_STATS` (balance 128.00, points
2680, frozen 0) and `integral.vue` reuses the points figure.
Missing: balance/points accounts and ledgers (`money_logs` in the reference).
MVP shape: `GET /api/me/stats` returning `{ 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 from `USER_STATS`.
Missing: points ledger (earn/spend), `integral_products`, points-denominated checkout
(`integral/orders` in 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 `i64` minor 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/shared` and 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.