Esports tournament platform
Integer money. Balanced entries. Corrections that leave an audit trail.

Minor units avoid floating-point amount representation.
Corrections use compensating entries.
The challenge.
Tournament entry fees and prizes need a durable record of where value moves. Mutable balance columns alone cannot provide that record.
This is an architecture and implementation in development, not a claim of live payment processing.
The boundaries.
- Store amounts as integer minor units.
- Use append-only, balanced entries protected by database invariants.
- Use serializable transactions, deterministic row locking, and idempotency keys.
- Correct errors through compensating entries, not edits to history.
How it fits
together.
A NestJS and Drizzle backend uses PostgreSQL invariants around paired ledger entries. Serializable transactions and deterministic lock ordering handle concurrent changes. Identity uses phone-first OTP, refresh-token rotation, and token-family reuse detection.
The decisions
behind the details.
Append-only financial history
A correction should explain what changed without erasing the original transaction.
TradeoffReading a balance requires interpreting ledger entries rather than trusting a mutable field.
Deterministic locking and idempotency
Retries and concurrent writes must not create a duplicate movement of value.
TradeoffTransaction design is more involved and must account for contention.