docs(openspec): plan wave 5, the store directory

Planning only: proposal, delta specs, design and tasks for replacing the
store surfaces. No code yet.

The batch adds a public shop read (profile + products) so the store directory,
store home and product-page store card stop reading MOCK_STORES, and so the
cart, payment and order surfaces can name a shop instead of printing "Shop".

Decisions recorded in the design:

- a `shop_profiles` table beside `shops`, so the existing admin and
  shop-admin contracts are untouched
- the four store scores stay stored profile values, because there is no review
  model and deriving them would dress fabricated numbers as computed ones
- `distanceKm` is dropped rather than faked: there is no geo model behind it
- profiles are filled by seed-demo.mjs, since they hang off shops that script
  creates
- order surfaces resolve names from one cached shop read rather than growing a
  denormalised shop name on every order payload

openspec validate --strict passes and the change is ready to apply.
This commit is contained in:
2026-09-17 16:54:22 +00:00
parent f6ddfd21cb
commit 51f8bb7c1d
6 changed files with 177 additions and 0 deletions
@@ -0,0 +1,31 @@
# Proposal
## Why
The store directory and store home still render four hard-coded shops, and the cart, payment and order surfaces fall back to a generic "Shop" label because nothing exposes a buyer-facing shop read. Products already carry `shop_id`; the missing piece is the profile.
## What Changes
- Add a `shop_profiles` table keyed to shops — logo, banner, company, region, address, notice, after-sale text and four scores — kept separate from `shops` so the admin and shop-admin contracts do not change.
- Add public `GET /api/shops` and `GET /api/shops/{slug}` returning a profile composed with its shop; the store directory, store home and product-page store card read them, taking products from the catalog API by `shop_id`.
- Add `PUT /api/admin/shops/{id}/profile` for platform admins, and fill the four demo shops from `seed-demo.mjs`, which is the only place that knows the shops exist.
- Retire the mock's `distanceKm`: there is no geo model behind it, so the distance column and its sort are removed rather than filled with an invented number.
- Let the cart, payment and order surfaces resolve `shop_id` to a real name from that read, retiring the generic "Shop" label.
## Capabilities
### New Capabilities
- `store-directory`: the buyer-facing view of a shop — its profile and its products — read publicly and maintained by platform admins.
### Modified Capabilities
- `frontend-mall`: the store directory and store home read live shops instead of fixed mock content, and order surfaces show real shop names.
## Impact
A new migration and route module; `packages/shared/src/{api,types}.ts`; `pages/stores/{index,[id]}.vue`, the store card in `pages/goods/[id].vue`, `pages/checkout/pay.vue` and `pages/user/orders/index.vue`; `scripts/seed-demo.mjs`; the mall's fixed-data adapter. The contract change rebuilds all three frontends.
## Non-goals
No reviews model: the four scores stay stored profile values, not derived ratings. No geo data or distance. No merchant self-service editing — platform admin only. No work on the seckill, collective or integral pages, nor coupons, favourites or addresses.