Prove the Number Is Right

A hard Pipeline Design interview practice problem on DataDriven. Design the pipeline on the canvas: sources, transforms, storage and checks, then get feedback on it.

Domain
Pipeline Design
Difficulty
hard
Seniority
L6

Problem

We show customers one unified view of their spending across their connected bank accounts. The data arrives from dozens of partner integrations, each delivering by webhook, scheduled file, or CDC, and compliance must be able to reproduce every number we serve. Design the data pipeline.

Bad data in fintech is not just messy. It is expensive.

Business requirements

Worked solution and explanation

What this really is

This is a reconciliation pipeline dressed up as a spending dashboard. Anyone can draw partners flowing into a warehouse. What separates candidates is whether proof is a stage in the pipeline or a spreadsheet someone runs afterward. One shared loader on one cadence fails three ways. Balances go stale, one late partner stalls everyone, and when compliance asks why partner X is short this week, nobody can say, because nothing ever compared your totals to theirs.

Walk the requirements

Step 1: Split one feed into two cadences

Balances must land within minutes, and history can lag a couple of hours. Fan out from partner_topics. One branch runs balance_stream in real time into balance_store. The other runs transaction_loader as a batch under a two-hour SLA. A single cadence either pays streaming prices on every historical row or leaves balances stale.

Step 2: Isolate partners, keep the last known balance

per_partner_ingest runs one task per partner, so a late feed stalls only its own task and healthy partners keep flowing. balance_store holds the latest balance per account, so a silent partner's customers still see their last known value instead of an empty page.

Step 3: Gate each batch on partner totals

reconciliation_gate sums each partner's batch and compares it to the total that partner reported. A gap beyond tolerance flags the batch in the run that created it, not a month later.

Step 4: Archive every verdict for seven years

The gate writes one row per check to validation_archive: partner, batch, expected total, actual total, tolerance and result. Keep it queryable for the SEC window, so an auditor's question becomes a query instead of a promise.

Step 5: Serve the customer from both tiers

customer_app reads the balance from balance_store and the history from transaction_warehouse. Drop that second edge and customers see a number with no spending behind it.

The reference design

Per-partner tasks feed two tiers. Balances stream in real time. Transactions batch through `reconciliation_gate` into the warehouse, while every verdict lands in `validation_archive` for compliance.
  • partner_feeds (source, API)
  • per_partner_ingest (transform, Spark); parallelism: 8 tasks
  • partner_topics (queue, Kafka)
  • balance_stream (transform, Flink); freshness: real-time
  • balance_store (storage, PostgreSQL)
  • transaction_loader (transform, Spark); freshness: < 2h
  • reconciliation_gate (quality gate, Great Expectations)
  • transaction_warehouse (storage, warehouse)
  • validation_archive (storage, Iceberg)
  • customer_app (consumer, API)
  • compliance_team (consumer)
  • partner_feeds -> per_partner_ingest
  • per_partner_ingest -> partner_topics
  • partner_topics -> balance_stream
  • partner_topics -> transaction_loader
  • balance_stream -> balance_store
  • transaction_loader -> reconciliation_gate
  • reconciliation_gate -> transaction_warehouse
  • reconciliation_gate -> validation_archive
  • balance_store -> customer_app
  • transaction_warehouse -> customer_app
  • transaction_warehouse -> compliance_team
  • validation_archive -> compliance_team
One shared loader
Every partner shares one job and one cadence. A late partner blocks the run, every balance goes stale, and nobody checks totals against what partners report.
Per-partner ingest
Each partner gets its own task in per_partner_ingest. A late partner stalls only itself, and reconciliation_gate checks each batch against that partner's own reported total.

Common follow-up questions