chore(openspec): archive add-flash-sales
Sync the flash-sales capability plus the order, frontend-mall, and frontend-shop-admin requirements into the main specs, and write the capability Purpose the archive leaves as a placeholder. Restate the flash-price and coupon-exclusion scenarios in the group-buying order delta, since its MODIFIED checkout block must carry the scenarios the main order spec now has.
This commit is contained in:
@@ -6,26 +6,34 @@ Checkout splitting a cart into per-shop orders, plus order lifecycle and ownersh
|
||||
## 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, and requested coupon redemption. All amounts use the cart's SKU currencies converted into the buyer-chosen display currency at checkout time. The request MAY select at most one owned coupon per generated shop order; the server SHALL validate its 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. This requirement does not define activity prices; a later flash-sale or group-buying change that rewrites checkout SHALL restate these coupon clauses and SHALL reject a coupon on any shop order that applied an activity price.
|
||||
`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
|
||||
- **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 one matching shop
|
||||
- **WHEN** the customer selects an eligible coupon issued by shop A for a cart containing shops A and B
|
||||
- **THEN** only shop A's order records that coupon and its server-calculated discount
|
||||
- **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 stock and restore a redeemed coupon to claimed status when the order has one.
|
||||
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 increases by the ordered qty and status is cancelled
|
||||
- **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
|
||||
|
||||
Reference in New Issue
Block a user