Accounts, Transactioins and Ledger Implementatioin
1.
Tech Stack & InfrastructurePostgreSQL (13+), with plpgsql triggers
TypeORM (or Prisma) for ORM + migrations
Flyway or Liquibase as an alternative for DDL versioning
decimal.js for all money fields
2.
Zod (or AJV) for JSONB schemas
class-validator + class-transformer for entity‐level checks
3.
Jest + TestContainers to spin up real Postgres in CI
Supertest for HTTP/integration tests
GitHub Actions (or equivalent) for linting, migrations, tests
4.
Winston / Pino for structured logs
Sentry for error tracking
Prometheus + Grafana for metrics
Phase 1: Core Account Model#
| Table | Purpose |
|---|
account_types | Defines “kinds” (e.g. SAVINGS, CHECKING) |
account_balances | Real-time running balance per account |
account_type_transaction | Which transaction types each account type is allowed to perform |
accounts | Actual account record (FK → type, country, currency, status) |
Unique index on account_types.code
Trigger on ledger_entries to update account_balances
Pessimistic‐locking methods in service to avoid race conditions
Phase 2: Transaction Type Configuration#
| Table | Purpose |
|---|
transaction_types | Master list (code, description, requires_two_factor, JSONB) |
transaction_type_postings | (Optional) normalized posting templates per transaction type |
JSONB or separate table for posting templates
Zod/AJV schema to validate that postings sum to 100% and refer to valid account types
Phase 3: Domain Transactions#
| Table | Purpose |
|---|
domain_transactions | Business-level record (payer, payee, amount, status, etc.) |
domain_transaction_history | Audit of status changes, attachments, idempotency keys |
Status enum transitions (PENDING → POSTED → FAILED)
FK to transaction_types, optional idempotency_key
| Table | Purpose |
|---|
ledger_transactions | “Header” linking back to a domain txn, with metadata & reference |
ledger_entries | Individual debit/credit lines (FK → ledger_transaction, account, side, amount) |
Trigger: enforce_double_entry() to ensure Σ(debits) = Σ(credits)
Trigger: adjust_account_balance() to maintain account_balances
Unique or partial‐unique constraints on reference, domain_txn_id
Phase 5: Audit, Idempotency & Outbox#
| Table | Purpose |
|---|
ledger_transaction_history | Immutable record of every header change |
idempotency_keys | Global registry of idempotency tokens to prevent duplicates |
outbox_events | For reliable pub/sub / eventing (e.g. notify downstream) |
Phase 6: Service Layer & Orchestration#
Atomic “Post Transaction” with TypeORM QueryRunner at SERIALIZABLE
1.
Create & validate DomainTransaction
2.
Instantiate LedgerTransaction + LedgerEntry[] via template
3.
Save header (cascades to entries) → triggers fire → balances update
4.
Record in outbox_events if needed
5.
Commit or rollback on any error (unbalanced, constraint, validation)
Fetching balances with FOR UPDATE lock
Searching transactions by date/account/status
Phase 7: Validation, Testing & CI#
Unit Tests: JSONB schemas, service error paths
Triggers (unbalanced entries must fail)
Concurrency (two debits at once update account_balances correctly)
CI Pipeline: lint → build → migrations → tests
Phase 8: Security & Hardening#
DB roles & permissions (readonly vs write)
Audit logging at service layer
2FA enforcement for high-risk transaction types
Phase 9: Scaling & Partitioning#
Partition ledger_entries by date (e.g. monthly) for very large volumes
Archival process to move old partitions to cheaper storage
Phase 10: Monitoring & Maintenance#
Regular drift checks (Flyway)
Health checks on balances vs trial-balance reports
Alerts if any trigger failures or balance mismatches
account_types
account_balances
account_type_transaction
accounts
transaction_types
transaction_type_postings
domain_transactions
domain_transaction_history
ledger_transactions
ledger_entries
ledger_transaction_history
idempotency_keys
outbox_events
➡️ Next: Phase 1, implement account_types + its migration, entity, indexes, metadata schema, and triggers for balance adjustments. Shall we dive into that?Modified at 2025-07-14 12:42:46