Files
vmall/openspec/specs/customer-accounts/spec.md
T
james 39d0158f29 chore(openspec): archive add-customer-accounts
Sync the customer-accounts capability and the frontend-mall stats requirement
into the main specs, and write the capability Purpose the archive leaves as a
placeholder so strict validation stays green.
2026-09-18 11:55:38 +00:00

2.1 KiB

customer-accounts Specification

Purpose

Hold each customer's monetary and loyalty-points balances with an auditable history. Accounts are keyed by kind and currency, every balance change is a guarded transactional update paired with an immutable entry, and the customer's own summary is the only public surface. Later flows (points redemption, withdrawals, refunds) spend and grant value through this module's internal primitives instead of writing balances directly.

Requirements

Requirement: Customer account summary

Each customer SHALL have available monetary balance, frozen monetary balance, and loyalty-points accounts. An authenticated customer SHALL retrieve a summary containing balance minor, frozen balance minor, their monetary currency, and integer points. Public APIs SHALL NOT list or mutate account entries.

Scenario: new customer summary

  • WHEN a newly registered customer requests account stats
  • THEN the API returns zero balances and zero points without relying on browser fixtures

Scenario: frozen kind exists without a freeze flow

  • WHEN a customer with no freeze events requests account stats
  • THEN frozen_minor is zero and available balance is unchanged

Requirement: Append-only account entries

Every account balance change SHALL create an immutable entry with signed delta, resulting balance, reason, optional business reference, and timestamp in the same transaction. Account entries SHALL NOT be edited or deleted through public APIs.

Scenario: debit records result

  • WHEN an internal business flow debits points successfully
  • THEN the points balance and one entry with the resulting balance commit together

Requirement: Guarded account mutation

A debit or freeze SHALL succeed only when the affected account has sufficient available balance. Concurrent changes SHALL use conditional atomic updates and return 409 rather than create a negative balance.

Scenario: competing debits

  • WHEN two debits together exceed a points balance
  • THEN at most one debit succeeds and the final stored balance is non-negative