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:
@@ -0,0 +1,18 @@
|
||||
# Spec Delta
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Store and marketing pages
|
||||
The mall SHALL provide a store directory and store home reading live shops from the shop API, with each store's products coming from the catalog API, and SHALL keep the timed seckill page, collective-buy list and points-mall home on fixed bilingual content for now. The cart, payment and order surfaces SHALL show each order's shop by name from the shop API rather than a generic label. Marketing pages MAY be display-only except navigation to product detail.
|
||||
|
||||
#### Scenario: navigate storefront discovery channels
|
||||
- **WHEN** a shopper opens stores, seckill, collective or integral routes
|
||||
- **THEN** each page renders the appropriate B2B2C mall-style banner/filter/session/card layout, the store directory and store home list real shops, and product links resolve to product detail
|
||||
|
||||
#### Scenario: order surfaces name the shop
|
||||
- **WHEN** a shopper views a cart line, a payment group or an order card
|
||||
- **THEN** the shop is shown by its name, not a placeholder
|
||||
|
||||
#### Scenario: a shop without a profile still renders
|
||||
- **WHEN** a shop has no profile row
|
||||
- **THEN** the directory and store home render it without inventing logo, scores or copy
|
||||
@@ -0,0 +1,37 @@
|
||||
# Spec Delta
|
||||
|
||||
## Purpose
|
||||
|
||||
The buyer-facing view of a shop: its public profile — identity, contact and service copy — alongside the products it sells, so the store directory, a store's home page and the store card on a product page all read real shops.
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Public shop directory
|
||||
`GET /api/shops` SHALL list the active shops without authentication, and `GET /api/shops/{slug}` SHALL return one shop by slug, answering 404 for an unknown slug or a suspended shop. Each entry SHALL carry the shop's id, slug, bilingual name and its profile: logo and banner URLs, company, region, bilingual address, bilingual notice and after-sale copy, and four score values. A shop with no profile row SHALL still be returned, with the profile fields absent rather than invented.
|
||||
|
||||
#### Scenario: directory lists active shops only
|
||||
- **WHEN** a suspended shop exists alongside active ones
|
||||
- **THEN** the directory lists only the active shops
|
||||
|
||||
#### Scenario: store home by slug
|
||||
- **WHEN** a shopper opens a shop's slug
|
||||
- **THEN** the profile and the shop's products are available, with the products filtered by that shop through the catalog API
|
||||
|
||||
#### Scenario: unknown slug is a 404
|
||||
- **WHEN** a shopper opens a slug that does not exist
|
||||
- **THEN** the API answers 404 rather than an empty profile
|
||||
|
||||
### Requirement: Shop profile management
|
||||
A platform admin SHALL set a shop's profile with `PUT /api/admin/shops/{id}/profile`, which upserts the profile row and returns the composed shop. Bilingual fields SHALL carry non-empty `en` and `zh` text, and the write SHALL require the `platform_admin` role.
|
||||
|
||||
#### Scenario: profile upsert round-trips
|
||||
- **WHEN** an admin sets a profile and then reads the shop publicly
|
||||
- **THEN** the public read returns those values
|
||||
|
||||
#### Scenario: incomplete bilingual text is refused
|
||||
- **WHEN** an admin submits a notice with only `en` text
|
||||
- **THEN** the request is refused and the stored profile is unchanged
|
||||
|
||||
#### Scenario: only platform admins may write
|
||||
- **WHEN** a shop owner or customer submits a profile
|
||||
- **THEN** the API refuses the write
|
||||
Reference in New Issue
Block a user