Lecture 10 · Module 2 Capstone

Banking Fraud Detection
End-to-End

Multi-Producer · Kafka · MongoDB · Enrichment · 3 Fraud Rules · Live Alerts

📅 Module 2 — Making Kafka Work
90 min Workshop
🏦 We build it live, together
02 / 10 Agenda

Today's 90 Minutes

TimeWhat We DoFormat
0 – 10Module 2 recap — full path from L6 → L9Discussion
10 – 20Why fraud detection? Architecture overviewLecture
20 – 30The dataset — 2000 synthetic transactions, 3 fraud patterns plantedDemo
30 – 45Step 1 — Generate data + Run producerLive build
45 – 60Step 2 — consumer_store.py (save + user profiles)Live build
60 – 80Step 3 — consumer_fraud.py (3 rules + MongoDB enrichment)Live build
80 – 90See fraud alerts fire, discuss extensions, module wrap-upDiscussion
03 / 10 Context

Why Fraud Detection?

Every card swipe triggers a real-time decision. Banks have milliseconds — not hours — to approve or hold.

Batch System (Old)Streaming System (Now)
Check transactions overnightCheck every transaction as it arrives
Fraud flagged next morningFraud flagged before transaction clears
Customer already abroad, card maxedTransaction held, customer called instantly
No geographic contextKnows where card was used 3 minutes ago

The pattern we use today: Kafka brings the current signal (this transaction). MongoDB holds the historical context (last known location, average spend). The consumer combines both to decide.

Scale Reference

NetworkPeak Transactions/sec
Visa65,000
Mastercard50,000+
NPCI / UPI10,000+

None of these run on batch. All use streaming architectures similar to what you're building today.

04 / 10 Architecture

What We Build Today

generate_transactions.py
2000 rows · 3 fraud patterns
transactions.csv
synthetic dataset
transaction_producer.py
0.3s per message
transactions-topic
Kafka
consumer_store.py
saves every transaction
updates user_profiles
consumer_fraud.py
queries MongoDB
applies 3 fraud rules
MongoDB
transactions
user_profiles
🚨 Fraud Alerts
Impossible Travel
Unusual Amount · Rapid Fire

Key insight: consumer_store.py runs first — it builds the historical record that consumer_fraud.py relies on. Storage and enrichment are inseparable.

05 / 10 Dataset

The Synthetic Dataset

Run generate_transactions.py to create transactions.csv — 2000 rows, 50 fake users, 8 Indian cities.

FieldExampleNotes
transaction_idTXN-00847Unique per row
user_idUSR-04250 synthetic users
user_nameBhavna ThakurRealistic Indian names
amount4500.00INR, varies by merchant type
merchantSwiggy30 merchant types
city / lat / lonMumbai / 19.076 / 72.877Real GPS coordinates
timestamp2025-08-01 10:00:00Spread over 30 days

Planted Fraud Patterns (~5% of rows)

Pattern 1
Impossible Travel
Mumbai 10:00 → London 10:45 (7,189 km in 45 min)
10 users affected
Pattern 2
Amount Spike
User avg ₹800 → single txn ₹92,000 at jeweller
15 users affected
Pattern 3
Rapid Fire
4 transactions in 88 seconds (card cloning test)
17 users affected
06 / 10 Step 1 — Terminal 1

Generate Data & Run Producer

bash · Terminal 1
python generate_transactions.py
# ✅ Generated 2000 transactions → transactions.csv
#    Legitimate: 1903  |  Fraud planted: 97

python transaction_producer.py

You'll see the live feed:

→ [0001] Aarav Sharma Mumbai ₹ 4,500.00 Swiggy → [0002] Priya Mehta Delhi ₹ 1,250.00 Amazon 🚨 [0847] Bhavna Thakur London ₹ 38,200.00 Duty Free → [0848] Aarav Sharma Bengaluru ₹ 890.00 Zomato

Notice: The producer marks fraud rows with 🚨 in its own output — but the consumer doesn't know this yet. It's discovering fraud independently from Kafka + MongoDB. Leave this running and open Terminal 2.

07 / 10 Step 2 — Terminal 2

consumer_store.py — Persist & Profile

Two MongoDB writes on every message:

python · consumer_store.py — key logic
# 1. Append raw transaction to audit log
txns.insert_one({**txn, "ingested_at": datetime.utcnow()})

# 2. Upsert user_profiles — freshest location + running totals
profiles.update_one(
    {"user_id": txn["user_id"]},
    {
        "$set": {"last_city": txn["city"], "last_lat": lat, "last_lon": lon, ...},
        "$inc": {"total_spend": amount, "txn_count": 1}
    },
    upsert=True
)

What upsert=True means

SituationBehaviour
User seen for the first timeCreates a new document in user_profiles
User seen beforeUpdates only the specified fields — no duplicate

Check Atlas: After 30 seconds, open MongoDB Atlas → Browse Collections → sda_course. You'll see user_profiles filling up with one document per user, each showing their latest city and cumulative spend.

08 / 10 Step 3 — Terminal 3

consumer_fraud.py — 3 Fraud Rules

For every Kafka message, query MongoDB for the user's history — then apply rules:

Rule 1
🌍 Impossible Travel
Haversine distance from last_lat/lon (MongoDB) to current > 500 km AND time diff < 60 min
Enrichment from MongoDB required
Rule 2
💸 Unusual Amount
Current amount > 3× (total_spend ÷ txn_count) — requires at least 5 prior transactions
Historical avg from MongoDB required
Rule 3
⚡ Rapid Fire
3+ transactions from same user in last 60 seconds — query transactions collection by timestamp
Recent history from MongoDB required

All three rules need MongoDB. None of them can fire on Kafka data alone — they need context that only the storage consumer has been building.

09 / 10 Discussion

What Good Output Looks Like

Legitimate transactions

✅ [0001] APPROVED TXN-00001 Aarav Sharma Mumbai ₹ 4,500.00 ✅ [0002] APPROVED TXN-00002 Priya Mehta Delhi ₹ 1,250.00

Impossible Travel alert

🚨 IMPOSSIBLE TRAVEL Transaction : TXN-00847 User : Bhavna Thakur (USR-042) · card ···5530 Amount : ₹38,200.00 at Duty Free [IMPOSSIBLE TRAVEL] Last seen in Mumbai (19.07°, 72.87°) at 2025-08-14 10:00:22 Now at London (51.50°, -0.12°) at 2025-08-14 10:45:18 Distance 7,189 km in 44 min ⛔ ACTION : HOLD TRANSACTION

Discussion Questions

  1. Change IMPOSSIBLE_TRAVEL_KM = 100. What new alerts fire? Are any of them false positives?
  2. A customer genuinely flies Mumbai → Dubai (2,200 km, 3.5 hr flight). Your rule would have blocked their arrival transaction. How do you solve this?
  3. Rule 2 requires 5+ past transactions. A customer's first big purchase is always suspicious. What would you do for new users?
10 / 10 Takeaways

Module 2 Complete

Downloads

1 / 10