Files
vmall/openspec/specs/frontend-shop-admin/spec.md
T
james 9904696e76 feat: wave 2 migration (P3, P5, P7 openspec changes)
Implements, verifies, and archives the three remaining Wave 2 changes from
openspec/MIGRATION-PLAN.md.

- add-wallet-settlement (P3): demo recharge, guarded withdrawal freeze and
  one-time admin review, paginated own fund entries, idempotent per-shop
  weekly/monthly settlement statements with commission rate and one-time
  payout confirmation.
- add-merchant-onboarding (P5): personal/enterprise applications with one live
  application per user, guarded review with mandatory rejection reason, and
  transactional shop + owner provisioning returning one-time credentials;
  mall onboarding/status pages and an admin review console.
- add-membership-messaging (P7): platform member levels, append-only growth
  accrual on order completion with guarded one-way leveling, order/shipment/
  refund system messages with unread/read state and soft deletion, plus the
  mall header unread badge.

Backend: migrations 0019-0023, new wallet, settlement, merchant_onboarding,
membership and messaging modules, event hooks in order/fulfillment/aftersale,
and integration suites for each. Shared contract extended and all three
frontends updated; code indexes, domain docs, backend guidelines and the
migration tracker synced.

Verification: cargo test -p vmall-api green twice consecutively; mall, admin
and shop-admin builds pass; browser smoke on every new surface; openspec
validate --all --strict green (33 passed).

The three changes share the @vmall/shared contract, the mall mock adapter and
per-app locale/nav files, so they are committed together to keep every commit
buildable.
2026-09-25 15:25:29 +00:00

157 lines
10 KiB
Markdown

# frontend-shop-admin Specification
## Purpose
The merchant console for managing a shop's products and fulfilling its orders.
## Requirements
### Requirement: Merchant product management
Shop users SHALL manage only their own shop's products: create/edit bilingual content, manage SKUs, publish/unpublish with immediate effect on the storefront.
#### Scenario: publish visible in mall
- **WHEN** a merchant publishes a product in shop-admin
- **THEN** it appears in the mall product list for the matching locale
### Requirement: Merchant fulfillment
Shop users SHALL see incoming orders, create shipments, mark them shipped, and issue requested invoices.
#### Scenario: ship an order
- **WHEN** a merchant creates a shipment for a paid order and marks it shipped
- **THEN** the shopper sees the shipment with tracking info
### Requirement: Merchant coupon management
Shop users SHALL manage only their shop's coupon templates from shop-admin, including localized title, amount and threshold in minor units, currency, claim stock, active window, and enabled state. Shop-admin SHALL expose a coupons navigation entry beside existing shop operations.
#### Scenario: create an active template
- **WHEN** a shop owner creates a valid coupon template
- **THEN** the template is available for eligible customers to claim during its active window
#### Scenario: coupons appear in shop navigation
- **WHEN** an authenticated shop user opens shop-admin
- **THEN** a coupons management entry is reachable without leaving the shop-scoped console
### Requirement: Merchant flash-sale management
Shop users SHALL manage only their flash-sale sessions and items in shop-admin, choosing their own SKU, active window, minor-unit sale price, reserved stock, and per-customer limit. Shop-admin SHALL expose a flash-sale navigation entry beside existing shop operations.
#### Scenario: configure item
- **WHEN** a merchant creates an active valid flash-sale item for its SKU
- **THEN** it appears to customers through active flash-sale discovery
#### Scenario: flash sales appear in shop navigation
- **WHEN** an authenticated shop user opens shop-admin
- **THEN** a flash-sale management entry is reachable without leaving the shop-scoped console
### Requirement: Merchant group-buying management
Shop users SHALL manage only their shop's group-buying activities in shop-admin, configuring an owned SKU, localized display content, minor-unit group price, required paid-member count, active window, and group lifetime. Shop-admin SHALL expose a group-buying navigation entry beside existing shop operations.
#### Scenario: publish activity
- **WHEN** a merchant publishes a valid group-buying activity
- **THEN** shoppers can discover it during its active window
#### Scenario: group buying appears in shop navigation
- **WHEN** an authenticated shop user opens shop-admin
- **THEN** a group-buying management entry is reachable without leaving the shop-scoped console
### Requirement: Shared design system in the merchant console
The shop-admin console SHALL use `@vmall/ui` primitives and `@vmall/shared` theme tokens for chrome (buttons, fields, cards, tables, page headers, nav). It MUST NOT depend on Element Plus or the removed `ui.css` stylesheet.
#### Scenario: console chrome from the kit
- **WHEN** an authenticated shop user opens shop-admin
- **THEN** primary actions and page chrome render through the shared kit with the current accent preset
### Requirement: Accent preset switcher
Shop-admin SHALL expose the shared accent preset control (`red`, `blue`, `teal`, `violet`) in the authenticated shell header.
#### Scenario: switcher visible
- **WHEN** an authenticated shop user opens shop-admin
- **THEN** they can select an accent preset without leaving the current page
### Requirement: Merchant shop profile editing
Shop users SHALL edit their own shop's profile from a shop-admin page reachable from the shop-scoped navigation, through the shared API adapter's shop-scoped profile update. The form SHALL prefill from the shop's current profile and cover the merchant-writable fields only: logo and banner URLs, company, region, and `{ en, zh }` bilingual address, notice and after-sale copy. Bilingual fields SHALL be validated with non-empty `en` and `zh` text before any request is sent, every write SHALL target the caller's own shop, and profile scores SHALL NOT be editable — they remain platform-set and saving never changes them. Saves SHALL give clear success feedback; a refused save SHALL keep the form values and show a visible failure message.
#### Scenario: merchant updates their own profile
- **WHEN** a shop owner edits their notice, saves, and the mall store page reloads
- **THEN** only that shop shows the new notice and no other shop's profile changes
#### Scenario: incomplete bilingual text is blocked before submit
- **WHEN** a shop owner leaves the `zh` after-sale text empty and saves
- **THEN** the field shows an inline error and no update request is sent
#### Scenario: scores are not editable
- **WHEN** the profile page loads and is saved
- **THEN** no score fields are offered and the platform-set scores remain unchanged
#### Scenario: refused save keeps the form
- **WHEN** the API refuses an update
- **THEN** the page keeps the entered values and shows a failure message
### Requirement: Shop-scoped aftersale workspace
Shop-admin SHALL provide an aftersale list and detail workspace filtered to the authenticated shop's `own_shop` resources. Authorized shop users SHALL inspect order-item evidence and messages, approve or reject pending applications, and confirm returned goods with the guarded refund action. The UI SHALL show status transitions, remaining amount, ledger-backed refund result, and stale-action errors through the shared API contract.
#### Scenario: merchant approves a request
- **WHEN** a shop user opens a pending application for an item belonging to their shop and approves it
- **THEN** the status advances according to the selected aftersale type and the customer can see the persisted result
#### Scenario: merchant confirms return and refunds
- **WHEN** a shop user confirms receipt of a buyer-shipped return
- **THEN** the service records merchant confirmation, credits the customer's account once, and displays the refunded status and order total
#### Scenario: shop scope is enforced
- **WHEN** a shop user requests or mutates an aftersale for another shop
- **THEN** the API denies the operation and the workspace exposes no cross-shop data
#### Scenario: merchant messages buyer
- **WHEN** an authorized shop user appends a localized message
- **THEN** the message appears in the same chronological aftersale thread visible to the buyer
### Requirement: Merchant freight template management
Shop-admin SHALL provide a freight template management page for the signed-in shop user's own shop only, listing the shop's templates with their default flag, always-free toggle, pricing method, minor-unit fees, integer unit sizes, free-shipping threshold, and region rules. Create, edit, default-toggle, region-rule editing, and delete SHALL go through the shared `@vmall/shared` contract, and making a template default SHALL reflect the server's single-default outcome. The page SHALL use `@vmall/ui` primitives and shared tokens.
#### Scenario: manage a template and its region rules
- **WHEN** a shop user creates a by-piece template, adds a region rule with higher fees, and saves
- **THEN** reloading the page shows the template and rule from the backend
#### Scenario: default template toggle
- **WHEN** a shop user marks a second template as default
- **THEN** the page shows exactly that template as default after the server confirms
### Requirement: Merchant shipping company selection
When a shop user ships an order from the fulfillment view, shop-admin SHALL offer the shipping companies from the shared dictionary and require a selection before marking the order shipped. The chosen company SHALL reach the backend through the shared contract and appear on the order after shipping.
#### Scenario: ship with a selected company
- **WHEN** a shop user selects a shipping company and confirms shipment
- **THEN** the order shows the shipped state and the selected company
### Requirement: Merchant review management
Shop users SHALL list only their own shop's reviews in shop-admin through the shared API contract, with pagination and visible reply state, and SHALL submit at most one reply per review. Shop-admin SHALL expose a review management entry beside existing shop operations.
#### Scenario: reply to a review
- **WHEN** a merchant opens an unreplied review of their shop and submits a reply
- **THEN** the reply is stored once and the review row shows it as replied
#### Scenario: already replied review offers no second reply
- **WHEN** a merchant opens a review that already carries their shop's reply
- **THEN** no reply submission is offered and other shops' reviews are unreachable
### Requirement: Merchant settlement statements
Shop-admin SHALL list and open the signed-in shop's settlement statements — period, amount snapshot, and status — through the shared API contract, and allow manual generation for a closed period of the own shop. Shop-scoped pages SHALL never expose another shop's statements or their order/refund breakdown.
#### Scenario: statements list and detail
- **WHEN** a merchant opens the settlement page
- **THEN** only their own shop's statements are listed and each opens into its snapshot breakdown of orders, refunds, commission, and payable amount
#### Scenario: generation is idempotent in the UI
- **WHEN** the merchant generates a statement for a period that already has one
- **THEN** the existing statement appears without duplication
### Requirement: Shop-account withdrawal
The shop owner SHALL view the shop account summary (available and frozen balance of the shop owner's account) and apply to withdraw from it through the shared API contract, seeing the request as pending until the platform reviews it.
#### Scenario: shop-account withdrawal freezes funds
- **WHEN** the shop owner submits a withdrawal request from the shop-account page
- **THEN** the summary reflects the frozen amount and the request lists as pending
#### Scenario: reviewed request reflects outcome
- **WHEN** the platform rejects the shop owner's pending withdrawal
- **THEN** the shop-account summary shows the amount returned to available balance and the request shows as rejected