4.6 KiB
ADDED Requirements
Requirement: Member level catalog
The platform SHALL manage member levels through admin-only APIs. Each level SHALL carry a bilingual name ({en, zh}), an icon key, an integer growth-value threshold, and a bilingual benefits description ({en, zh}). Growth thresholds SHALL be unique across levels, and the effective ordering of levels SHALL follow the threshold. Deleting a level that any customer currently holds SHALL be rejected instead of reassigning or orphaning members.
Scenario: create a level
- WHEN a platform admin creates a level with name, icon, growth threshold, and benefits in both locales
- THEN the level is listed with its bilingual content and threshold ordering
Scenario: duplicate threshold is rejected
- WHEN a platform admin creates or edits a level to reuse another level's growth threshold
- THEN the request is rejected and the existing levels are unchanged
Scenario: deleting a level in use is rejected
- WHEN a platform admin deletes a level that at least one customer holds
- THEN the request is rejected and no customer's level changes
Requirement: Growth value accrual ledger
When a customer confirms receipt and an order reaches completed, the customer SHALL earn growth value equal to that order's realized paid amount converted to the base currency and truncated to whole units through integer minor-unit arithmetic using the base currency exponent, with no floating-point computation. Accrual SHALL append exactly one entry per order to a growth ledger that, like the points ledger, is append-only and records the delta, running growth total, reason, and order reference. Retried or repeated completion events SHALL NOT create a second entry or a second accrual.
Scenario: confirm receipt accrues growth
- WHEN a customer confirms receipt of an order whose realized paid amount converts to 120 whole base-currency units
- THEN the growth ledger gains one entry with delta 120 referencing that order and the customer's growth total rises by 120
Scenario: repeated completion is idempotent
- WHEN the completion handling for the same order runs again
- THEN no second ledger entry exists and the growth total is unchanged
Scenario: ledger entries are immutable
- WHEN any code path handles growth after an entry was written
- THEN the entry is only ever appended to, never updated or deleted
Requirement: Automatic level upgrade
Inside the growth accrual transaction, the customer's level SHALL be re-derived as the level with the highest growth threshold less than or equal to the customer's growth total and written to users.level with a guarded update. Leveling SHALL be one-way: a customer is only ever moved to a level with a strictly higher threshold than the current one, and never demoted automatically. A growth total exactly at a threshold qualifies for that level, and when several thresholds are passed the highest qualifying level wins. A customer below every threshold SHALL hold no level.
Scenario: growth at the threshold upgrades
- WHEN an accrual brings a customer's growth total exactly to a level's threshold
- THEN the customer's level becomes that level in the same transaction as the ledger entry
Scenario: jumping past intermediate levels
- WHEN an accrual passes two levels' thresholds at once
- THEN the customer holds the highest qualifying level, not the intermediate one
Scenario: no level below every threshold
- WHEN a customer's growth total is below the lowest defined threshold
- THEN the customer holds no level and a later qualifying accrual assigns one
Requirement: Level benefits display
An authenticated customer SHALL read their own membership status: current level with name, icon, and benefits, total growth value, the next level's threshold and remaining growth to reach it, and a paginated view of their own growth ledger. The status SHALL re-derive the displayed level against current thresholds, and one customer SHALL never read another customer's growth history.
Scenario: progress to the next level
- WHEN a customer between two thresholds opens their membership status
- THEN the response shows the current level's benefits and the exact growth remaining to the next level
Scenario: top level has no next level
- WHEN a customer at or above the highest threshold reads their membership status
- THEN the response contains no next level and no remaining growth target
Scenario: growth history is own-only
- WHEN a customer requests their growth ledger
- THEN only entries of the authenticated customer are returned, newest first and paginated