4.2 KiB
ADDED Requirements
Requirement: Idempotent periodic statement generation
A settlement statement SHALL be generated manually for one shop, one period kind (week or month), and one closed period. For the same shop, period kind, and period start at most one statement SHALL exist, enforced by the database. A repeated generation request SHALL return the existing statement unchanged instead of recomputing or duplicating it. No scheduled batch job SHALL generate statements.
Scenario: repeat generation is idempotent
- WHEN a statement already exists for a shop and period and generation is requested again
- THEN the existing statement is returned unchanged and no second row is created
Scenario: generation is manual only
- WHEN no generation request is made for a closed period
- THEN no statement exists for that period
Requirement: Immutable amount snapshot
A generated statement SHALL snapshot the contributing order count, the gross total of confirmed-received orders in the period, the deduction total of completed refunds against those orders (aftersales rows with status refunded, per-order totals from add-aftersale-refunds), the platform commission rate at generation time, the commission amount, and the payable amount where payable = gross − refunds − commission. All amounts SHALL be integer minor units computed with integer arithmetic, and the commission rate SHALL be an integer basis-point value. The snapshot SHALL NOT change after generation even when later orders, refunds, or commission-rate changes occur.
Scenario: refunds reduce the payable amount
- WHEN a confirmed-received order in the period has a completed refund of 2000 minor units
- THEN the statement's refund deduction includes those 2000 minor units and the payable amount is reduced accordingly
Scenario: commission arithmetic is integral
- WHEN the commission rate is 500 basis points and gross minus refunds is 10000 minor units
- THEN the commission snapshot is 500 minor units and the payable snapshot is 9500 minor units with no floating-point arithmetic
Scenario: snapshot survives rate changes
- WHEN the platform commission rate changes after a statement was generated
- THEN the generated statement keeps its snapshotted rate and amounts
Requirement: Platform commission rate configuration
The commission rate SHALL be a single platform-level setting stored as integer basis points and readable and editable by platform admins. A rate change SHALL affect only statements generated after the change.
Scenario: new rate applies to new statements
- WHEN an admin sets the commission rate and a statement is generated afterwards
- THEN that statement snapshots the new rate
Requirement: One-time payout confirmation
A statement SHALL transition exactly once from pending to confirmed through a guarded status transition requiring the pending status, triggered by a platform admin confirming the payout; a repeated confirmation SHALL return 409. Confirmation SHALL record the confirming admin and timestamp and SHALL credit the payable amount to the shop owner's available account with exactly one ledger entry referencing the statement.
Scenario: confirm pays out once
- WHEN an admin confirms a pending statement
- THEN the statement becomes confirmed and the shop owner's available balance increases by the payable amount with one ledger entry referencing the statement
Scenario: double confirmation conflicts
- WHEN an admin confirms an already confirmed statement
- THEN the API returns 409 and no second ledger entry is written
Requirement: Shop-scoped statement visibility
Statements and their breakdown SHALL be scoped to one shop. Through the shop's own-shop scope, shop users SHALL read and generate statements only for their own shop and SHALL never observe another shop's statements, contributing orders, or refund lines; platform admins SHALL observe every shop.
Scenario: merchant sees own shop only
- WHEN a shop user lists settlement statements
- THEN only statements of their own shop appear
Scenario: detail breakdown is shop-scoped
- WHEN a shop user opens a statement detail
- THEN the contributing orders and refunded amounts are visible for that shop only