Project

Banking Streams

A Kafka deep dive Project

Java 17Spring Boot 3.5PostgreSQLKafka

Overview

A real-time banking event processing system built to learn and implement Kafka concepts from basics to production-grade patterns.

Architecture

transaction-service (port 8090)
  → REST API accepts transaction requests
  → Writes transaction + outbox entry in single DB transaction
  → OutboxPoller publishes to Kafka every 1s with retry (Avro, via Schema Registry)
  → AccountSeeder publishes seed accounts to account.created on startup

Schema Registry (port 8081)
  → Stores Avro schemas for transaction.initiated, account.created, fraud.alert
  → Enforces BACKWARD compatibility on every schema change

Kafka (2-broker cluster)
  kafka1 → controller + broker
  kafka2 → broker only
  Topics: transaction.initiated, account.created, transaction.completed,
          transaction.failed, fraud.alert, transaction.dlq

notification-service (port 8091)
  → Consumes transaction.initiated (typed Avro, specific.avro.reader=true)
  → Manual offset commit (at-least-once)
  → Idempotency guard via processed_events table
  → Retry with exponential backoff (1s, 2s, 4s)
  → Routes to transaction.dlq after 3 failed attempts

fraud-detection-service (port 8092)
  → Kafka Streams topology (spring-kafka @EnableKafkaStreams)
  → Joins transaction.initiated with account.created (GlobalKTable) for tier enrichment
  → HIGH_VALUE: single transaction exceeds tier threshold
  → VELOCITY: 3+ transactions for one account in a 5-min sliding window
  → RAPID_LARGE: total spend for one account exceeds ₹1,00,000 in a 1hr tumbling window
  → Exactly-once processing (EXACTLY_ONCE_V2), state in RocksDB + Kafka changelog topics
  → Produces fraud.alert

Blog / reference

Kafka Deep Dive