Ship Before Fraud Finishes Checking

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

Replacement phones are going out on claims the fraud team only reviews the next morning, from a nightly batch over yesterday's data. We insure over 300 million devices and take tens of thousands of claims a day: design a pipeline that scores each claim for fraud at submission time.

The claim looks clean. The fraud model disagrees.

Business requirements

Worked solution and explanation

What this really is

This is a feature-serving problem dressed up as insurance fraud. The skill is splitting device history into two tiers: an online store the scorer reads in milliseconds, fed by CDC, and a warehouse that keeps every owner, plan and repair with effective dates. You also decide in advance what happens when scoring fails. Anyone can draw a stream. The trap is a scorer that reaches back into the operational database for history. Tens of thousands of claims a day become tens of thousands of lookups against a 300-million-device system, and operations throttles it. Then the day the scorer times out, someone adds auto-approve and ineligible replacements start shipping.

Walk the requirements

Step 1: Put scoring on a sub-minute path

The claim lands on Kafka, and scoring_stream (Flink, 'real-time') joins it to features and emits a decision in seconds. Shipping waits on that decision. Any design where fraud reads last night's warehouse fails the one requirement the business actually named.

Step 2: Keep the chain with effective dates

Model device history as a slowly changing dimension keyed on (device_id, valid_from, valid_to), with one row per ownership transfer, plan switch or repair. 'Same device claimed under two plans' is then an as-of join. A table that stores only the latest state per device erases the exact evidence fraud is looking for.

Step 3: Feed features off CDC, not live reads

cdc_from_ops_db streams changes into feature_builder, which upserts device-keyed rows into feature_store. The upsert is idempotent, so a replay after a restart cannot double-count repairs. The operational DB sees zero traffic from scoring.

Step 4: Make manual review a designed path

When the scorer errors or feature lag crosses its budget, scoring_stream routes the claim to manual_review_queue and alerts. It does not approve the claim and it does not hold it. The business already chose this trade, so the canvas should draw it.

The reference design

Claims are scored in Flink against a CDC-fed `feature_store`. `history_warehouse` keeps the dated chain for investigators. If scoring fails, the claim goes to `manual_review_queue`.
  • claim_stream (source, Kafka)
  • cdc_from_ops_db (source, CDC)
  • feature_builder (transform, Flink)
  • feature_store (storage, Redis)
  • history_warehouse (storage, warehouse)
  • scoring_stream (transform, Flink)
  • manual_review_queue (queue, Kafka)
  • shipping_system (consumer, API)
  • manual_reviewer (consumer, Grafana)
  • fraud_investigator (consumer, Jupyter)
  • claim_stream -> scoring_stream
  • cdc_from_ops_db -> feature_builder
  • feature_builder -> feature_store
  • feature_builder -> history_warehouse
  • feature_store -> scoring_stream
  • scoring_stream -> shipping_system
  • scoring_stream -> manual_review_queue
  • manual_review_queue -> manual_reviewer
  • history_warehouse -> fraud_investigator
  • Sources: claim_stream, cdc_from_ops_db
  • Feature pipeline: feature_builder, feature_store, history_warehouse
  • Scoring and fallback: scoring_stream, manual_review_queue
  • Consumers: shipping_system, manual_reviewer, fraud_investigator
Live lookup at scoring time
scoring_stream queries the ops DB per claim. Its load scales with claim volume, latency depends on someone else's system, and an ops outage blocks every claim.
CDC-fed online store
scoring_stream reads feature_store by device_id. Ops load comes from change volume only, lookups take milliseconds, and staleness is a number you can measure and route on.

Common follow-up questions