P / 05 · Microservices · Event-driven banking

E-Bank

A digital bank built the way a real one is structured: five Spring Boot services behind a gateway, Kafka events between them, and a double-entry ledger that reconciles live. Runs with one Docker Compose command.

Working demo · One-command start

Explore repository

Problem & users

Moving money across separate services is where distributed systems break: a retried transfer can apply twice, a slow reporting service can block payments, and a broker outage can lose events. The goal was a bank where balances stay correct under retries, concurrency and failures, and anyone can see it working.

Implementation

Customer, account, transaction and reporting services each own their database, registered in Eureka and reached through a Spring Cloud Gateway that handles JWT roles, rate limiting and routing. Requests a user waits on (login, transfers) run synchronously over HTTP and Feign; everything downstream flows through Kafka topics that the reporting service projects into dashboards, PDF and CSV reports, a customer activity feed and a live reconciliation check. The Angular app covers both a customer portal and an admin back office, seeded with 50 customers and seven months of reconciled history.

Engineering decision

Make correctness structural, not hopeful. Money commands take an Idempotency-Key: the account service stores a balance receipt per operation and the ledger has a database unique constraint, so eight truly concurrent retries still apply once. Events go through a transactional outbox so a paused broker never blocks a payment, malformed events land on a dead-letter topic, and reporting deduplicates by event ID and rejects stale snapshots so replaying topics never double-counts.

Evidence

The admin dashboard shows every account BALANCED against its own ledger. Python scripts verify the seeded data reconciles, that a Kafka outage never blocks or loses a money command, that bad events reach the dead-letter topic, and measure p50/p95 latency under load. JUnit, Mockito and Playwright tests on desktop and mobile cover services and UI; Kafka UI shows topics filling in real time.

Current limitations

  • A demo with seeded accounts, not a live bank. Services use file-backed H2 databases, and the local Kafka runs one broker with single-replica topics.
  • Outbox relays wait for broker acknowledgements inside database transactions. Reporting concurrency, database migrations and broker redundancy need work before scaling; the recovery checks are local runs, not production capacity evidence.

On GitHub

E-Bank
  • TypeScript
  • 0 stars
  • Updated

Sources

Reviewed at revision f63e847.