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>
This commit is contained in:
co-authored by
Cursor
parent
e10cae5789
commit
53548196f8
@@ -0,0 +1,26 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Shop flash-sale configuration
|
||||
Shop users SHALL manage only their own timed flash-sale sessions and SKU activity items. An item SHALL have a fixed minor-unit sale price, currency, reserved stock, per-customer limit, and belong to an active SKU owned by the session shop. The service SHALL reject a SKU that already has an overlapping active group-buying activity.
|
||||
|
||||
#### Scenario: cross-shop SKU rejected
|
||||
- **WHEN** a merchant adds another shop's SKU to a flash-sale session
|
||||
- **THEN** the API rejects it without creating an activity item
|
||||
|
||||
#### Scenario: overlapping group-buy SKU rejected
|
||||
- **WHEN** a merchant adds a SKU that already has an overlapping active group-buying activity
|
||||
- **THEN** the API rejects it without creating an activity item
|
||||
|
||||
### Requirement: Public active flash-sale discovery
|
||||
Customers SHALL list active sessions and their eligible products with current sale price, remaining activity stock, and sell-through information. Inactive, disabled, or elapsed items SHALL not be purchasable as flash-sale items.
|
||||
|
||||
#### Scenario: window closes
|
||||
- **WHEN** a session end time has passed
|
||||
- **THEN** it is absent from active discovery and checkout applies the normal SKU price
|
||||
|
||||
### Requirement: Flash-sale purchase limit and inventory
|
||||
Checkout SHALL enforce the activity's remaining stock and each customer's purchase limit atomically with normal SKU stock. A successful order SHALL retain the applied activity item and final price snapshot.
|
||||
|
||||
#### Scenario: quantity exceeds limit
|
||||
- **WHEN** a customer checks out a flash-sale SKU above the remaining per-customer allowance
|
||||
- **THEN** only eligible activity quantity receives the activity price and any other quantity follows normal availability and price
|
||||
@@ -0,0 +1,16 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Live flash-sale page
|
||||
The mall SHALL render active flash-sale sessions and activity products from the shared API client, including authoritative activity price, remaining stock, and sell-through. It SHALL replace `SECKILL_SESSIONS` and derived fixed product data. Shoppers SHALL purchase through the existing cart and checkout; payment and order-detail views SHALL show the snapshotted activity unit price from the order payload. This change SHALL NOT add flash-sale prices, badges, or claim CTAs to the catalog product-detail page (`/goods/[id]`); that page keeps catalog SKU pricing.
|
||||
|
||||
#### Scenario: choose live session
|
||||
- **WHEN** a shopper selects an active flash-sale session
|
||||
- **THEN** its live eligible products and countdown render without direct fixture imports
|
||||
|
||||
#### Scenario: order shows flash snapshot
|
||||
- **WHEN** checkout applies a flash-sale price
|
||||
- **THEN** payment and order-detail views show that unit price from the order payload
|
||||
|
||||
#### Scenario: product detail stays on catalog price
|
||||
- **WHEN** a shopper opens a catalog product that is also in an active flash-sale session
|
||||
- **THEN** the product-detail page still shows catalog SKU prices and does not require a flash-sale overlay in this change
|
||||
@@ -0,0 +1,12 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### 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
|
||||
@@ -0,0 +1,39 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Checkout splits by shop
|
||||
`POST /api/orders/checkout` SHALL create one order per distinct shop in the cart, in a single database transaction: stock decrement, order + item insert with price snapshots, cart clear, active flash-sale resolution, and requested coupon redemption when eligible. All amounts use the cart's SKU currencies converted into the buyer-chosen display currency at checkout time. For each cart line the server SHALL resolve an eligible active flash-sale item, enforce its remaining stock and customer limit, snapshot the final unit price and applied activity identity, and charge standard price for quantity not eligible for the activity. A SKU that is also eligible for group-buying in an overlapping window SHALL cause checkout to return 409. The request MAY select at most one owned coupon per generated shop order; the server SHALL validate ownership, shop, status, validity window, threshold, and converted amount, then persist `coupon_id`, `discount_minor`, and the post-discount `total_minor`. The client SHALL NOT provide a discount amount. If any line on that shop order applied flash-sale pricing, the server SHALL reject a coupon for that shop with 409.
|
||||
|
||||
#### Scenario: two shops → two orders
|
||||
- **WHEN** the cart contains SKUs from shops A and B
|
||||
- **THEN** two orders are created, each with only its shop's items, and the cart is empty
|
||||
|
||||
#### Scenario: insufficient stock
|
||||
- **WHEN** any line's qty exceeds SKU stock or applicable flash-sale stock
|
||||
- **THEN** the whole checkout returns 409 and no order is created and stock is unchanged
|
||||
|
||||
#### Scenario: active flash price applied
|
||||
- **WHEN** checkout contains a SKU with an active eligible flash-sale item
|
||||
- **THEN** the order item records the server-calculated flash-sale price and activity identity
|
||||
|
||||
#### Scenario: coupon applies to a shop without flash lines
|
||||
- **WHEN** the customer selects an eligible shop coupon and that shop's generated order has no flash-priced lines
|
||||
- **THEN** the order records that coupon and its server-calculated discount
|
||||
|
||||
#### Scenario: coupon rejected on a flash-priced shop order
|
||||
- **WHEN** the customer selects a coupon for a shop whose generated order applied flash-sale pricing on any line
|
||||
- **THEN** checkout returns 409 and creates no orders
|
||||
|
||||
### Requirement: Order lifecycle
|
||||
Status transitions SHALL be: pending_payment → paid → fulfilling → shipped → completed; cancellable only from pending_payment, which MUST restore SKU stock, any reserved flash-sale activity stock consumed by the order, and a redeemed coupon to claimed status when the order has one.
|
||||
|
||||
#### Scenario: cancel restores stock
|
||||
- **WHEN** a customer cancels a pending_payment order
|
||||
- **THEN** stock of each SKU and its applied flash-sale activity increases by the ordered qty and status is cancelled
|
||||
|
||||
#### Scenario: cancel restores coupon
|
||||
- **WHEN** a customer cancels a pending_payment order with a redeemed coupon
|
||||
- **THEN** the coupon is detached from the order and becomes claimed
|
||||
|
||||
#### Scenario: illegal transition rejected
|
||||
- **WHEN** cancelling a paid order via the customer endpoint
|
||||
- **THEN** the API returns 409
|
||||
Reference in New Issue
Block a user