Files
vmall/openspec/changes/add-points-mall/design.md
T
Chengdong ZhangandCursor 53548196f8 docs(openspec): plan shop coupons, accounts, points, flash sales, and group buying
Capture exclusive promotion composition, empty-group cancel, and mall surface scope so the five marketing changes can be implemented without stacking or lifecycle ambiguity.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-18 17:32:08 +08:00

33 lines
2.7 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.
## Context
The Mall has a fixture-only points catalog and points balance. Customer accounts will provide an atomic, append-only points ledger. Cash orders, payment, and shipments have a separate lifecycle, so a redemption should not be represented as a zero-value normal order.
## Goals / Non-Goals
**Goals:**
- Offer live points products and a customer redemption flow.
- Atomically debit points, reserve product stock, and create an immutable redemption order.
- Give platform operators product and redemption-order management.
**Non-Goals:**
- Point earning, cash co-payment, normal SKU inventory sharing, coupons, withdrawals, or full shipping integration.
## Decisions
### Points catalog is platform-owned and distinct
`integral_products` holds localized name/subtitle/content, images, integer `points_price`, stock, publish state, and sort/recommend fields. It is not a SKU and never joins merchant catalog inventory. Platform admins own CRUD; customers can read published products only.
### Redemptions have their own order snapshot
`integral_orders` stores customer, order number, state, address JSON snapshot, total points, and timestamps. `integral_order_items` snapshots product identity, localized name, image, point price, and quantity. States are `pending_fulfillment`, `fulfilled`, and `cancelled`; cancellation policy is platform-only until a future refund flow defines customer-initiated returns.
### Redeem atomically against accounts and stock
The service begins one transaction, locks the published product, conditionally decrements stock, debits the points account through customer-accounts, appends its entry with the redemption order reference, then inserts the order and line. Failures leave no order, stock change, or ledger entry. Point price and stock are never accepted from the client.
### UI replaces fixture-only behavior
Mall loads points balance and catalog through the shared client, submits a product/quantity/address redemption, and lists the customers redemption history on the points mall (not a cash-order list). Admin manages products and updates fulfillment state. Seed/demo data credits enough points for at least one redemption via the customer-accounts service with reason `seed`; it never assigns `balance_minor` by absolute overwrite.
## Risks / Trade-offs
- Redemption fulfillment initially stores only an address snapshot and status; carrier tracking can be integrated later with a dedicated model.
- The prerequisite customer-accounts change must archive first. This preserves a small, testable accounting boundary rather than duplicating balance mutation here.
- Without a seed credit, live redemption cannot be demonstrated; seed is an operator fixture, not a customer earn API.