← all projects
Transactional / streaming · flagship

Banking Fraud Detection Platform

Real-time fraud detection: CDC from Postgres, streaming through Kafka + Flink, indexed into OpenSearch for investigators.

01

Overview

Fraud detection has to be low-latency, resilient, and explainable. This project builds a production-shaped pipeline with CDC, event streaming, complex event processing, and a searchable case store.

02

Architecture

FastAPI
transactions
→
PostgreSQL
SoR
→
Debezium
CDC connector
→
Kafka
topics · partitions
→
Schema Registry
Avro contracts
→
Flink
CEP + windows
→
OpenSearch
cases + search

// interactive diagram coming next — click nodes to inspect

03

End-to-end data flow

  1. 01FastAPI accepts transactions and writes to PostgreSQL.
  2. 02Debezium streams row-level CDC events into a Kafka topic per table.
  3. 03Flink consumes CDC + reference data, applies CEP rules (velocity, geo, amount z-score).
  4. 04Alerts are produced back to Kafka and sunk into OpenSearch per-topic thread-safely.
  5. 05Investigators query cases in OpenSearch Dashboards; feedback loops relabel training data.
04

Hard problems solved

!

Kafka consumer rebalancing storms

Autoscaling Flink workers triggered repeated rebalances. Pinned partition assignment + cooperative-sticky assignor to bound movement.

!

CDC ↔ transaction ordering

Debezium snapshot + streaming handoff caused out-of-order events. Enforced key-based partitioning + Flink event-time watermarks with bounded lateness.

!

Dead-letter queues without silent drops

Bad payloads used to disappear. Every consumer now emits to a DLQ topic with error class + payload, replayed via a Flink job with a retry budget.

!

Thread-per-topic OpenSearch sink

One sink thread for many topics head-of-line-blocked alerts. Split into a thread-per-topic sink with bounded queues per index.

05

Lessons learned

  • →Contracts (Avro + Schema Registry) are the cheapest insurance in streaming.
  • →Event-time > processing-time for anything you want to audit.
  • →DLQ + replay is not optional; it's part of the pipeline.