❯ cat /work/el-carril.case
el-carril
Real-money betting platform for Mexican parejeras horse racing — wallet, ledger, live events
stack: NestJS · Prisma · PostgreSQL · Redis · React · k6
situation
Parejeras (match-race) betting in Mexico runs on cash, paper notebooks, and trust. I designed and built a platform that moves real money between real people: deposits, bet matching, settlement, withdrawals. In a system like this a rounding error is not a bug, it is someone's money.
evidence
- Exhibit 1
- floats are forbidden
every monetary value is Decimal/NUMERIC end-to-end; serialization boundaries audited for precision loss
- Exhibit 2
- one write path
a single LedgerService owns every balance mutation; no other code path can touch money
- Exhibit 3
- spike: 200 VUs
k6 load tests against production-shaped data found the CPU ceiling at password hashing (argon2), not the ledger
diagnosis
Financial integrity cannot be a code-review convention; it has to be structural. The design makes incorrect money handling unrepresentable: append-only ledger, idempotency keys on every mutation, serializable isolation on settlement, and balance snapshots that are recomputable from the ledger at any time.
intervention
- 01
Double-entry, append-only ledger on PostgreSQL with serializable transactions for settlement and idempotency keys for every money mutation.
- 02
Admin cannot grant balance by design: the only money entry point is a deposit with a verified receipt — an invariant, not a policy.
- 03
Audit log scoped to what matters (money movements, race results, identity changes) and partitioned by month with cold-storage archival, after costing the naive log-everything approach.
- 04
Load-tested with k6 against a production-shaped dataset using a backup → prepare → throttle-off → test → restore runbook; established a capacity ceiling (~100 sustained VUs on current infra) and the upgrade path beyond it.
- 05
Redis for session and hot-path caching; rate limiting on auth and money endpoints.
outcome · verified
- Exhibit 1
- 100% reconcilable
balances recomputable from the ledger at any point in time
- Exhibit 2
- ~100 VUs
sustained load on minimal infra, with a measured (not guessed) ceiling
- Exhibit 3
- argon2
identified as the true CPU bottleneck via load forensics, not assumption
The most valuable line of code in this project is the one that makes admin balance grants impossible.