Lunexa
A personal-finance engine built like a bank ledger.
A finance platform where every rupee movement is an immutable, idempotent ledger entry. NestJS and PostgreSQL with integer minor-unit money, a single balance writer and token rotation with reuse detection.
BIGINT
minor-unit money, no floats
1 writer
for every balance change
Immutable
completed transactions

01
Why I built it
Most finance side-projects store balances as floats and update them in place. One retry or race condition later, the numbers are wrong and there's no way to prove why. I wanted to build the opposite: a system where money is always correct, and every change can be traced and reversed.
02
The problem
- Floating-point money drifts; balances must be exact.
- A retried request must never apply the same transaction twice.
- Concurrent writes to the same account must not race.
- Sessions must survive token theft: a reused refresh token has to be detected.
03
System design
- 1
Client
Next.js app with an in-memory access token.
- 2
Auth
JWT access + HttpOnly refresh rotation with reuse detection and family revocation.
- 3
Transactions
Idempotent creation with splits, allocations and reversals.
- 4
Ledger writer
One service locks money sources in a fixed order and applies every balance change.
- 5
PostgreSQL
Integer minor units (BIGINT), migrations only, completed rows immutable.
04
Decisions & trade-offs
A single balance writer with deterministic locking
Why: Every balance change goes through one code path that locks accounts in a fixed order, so concurrent transfers can't deadlock or lose an update.
Trade-off: Feature code can't touch balances directly; everything routes through the ledger service.
Corrections are reversals, never edits
Why: Completed transactions are immutable, so the history always explains the current balance.
Trade-off: More rows and a revert-then-reapply flow instead of a simple update.
05
Backend & frontend
Backend
- NestJS + PostgreSQL (TypeORM, migrations only) with multi-space tenancy.
- Idempotent transactions, splits, allocations and reversals.
- Refresh-token rotation with reuse detection and session-family revocation.
- Cron schedulers that check ledger state before acting, so they can't double-apply.
Frontend
- Next.js client for spaces, money sources and transactions.
06
Design
- Product and brand designed alongside the engine.
07
Results
- In active development.
What's next
- Public demo with sandbox data.