The Boutique That Sold in Six Currencies
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
- L5
- Asked in
- Farfetch
Problem
Your luxury marketplace processes sales events from thousands of seller boutiques across multiple countries and currencies. Each sale must be attributed to the selling boutique in real time, normalized to a common currency, and stored in a compliant data lake that protects buyer identity. Design the pipeline.
Every sale is real. The rate it was converted at depends on who is asking.
Business requirements
- Boutique owners watch their revenue in real time during the day; a sale has to show up within roughly a minute.
- The dashboard uses live FX rates while finance reconciles using end-of-day official rates; each sale has to carry both so neither consumer reprocesses history.
- Buyer identity is regulated; deletion has to complete within the regulatory window, but historical sale amounts and boutique attribution should remain.
Worked solution and explanation
This is a rate-as-of-when problem and a key-separation problem wearing a luxury-marketplace costume. Anyone can draw Kafka into a stream into a dashboard. What separates candidates is seeing that one sale needs two different FX rates for two different readers, and that buyer identity has to live somewhere deletion can reach without touching the sale. Pick one rate and finance drifts from the official report. Store the buyer on the sale row and every deletion request becomes a rewrite of history you still owe finance.
Walking the requirements
Step 1: Tokenize before anything fans out
The tokenizer sits directly behind sale events. It writes the buyer-to-token mapping to the tokenization vault and forwards only the token. If identity reaches the stream or the lake even once, you have copies you cannot find at deletion time.
Step 2: Stamp the live rate in the stream
The Flink fx enrichment stream adds the spot rate at the sale's moment to each event, then feeds the boutique store and the lake. That one stage carries the real-time requirement, so the boutique dashboard stays inside its minute.
Step 3: Add the official rate in a slower batch
The end-of-day rate does not exist when the sale happens. The eod fx backfill reads the lake overnight, adds the official rate for the sale's date, and loads the finance warehouse. Each sale ends up holding both rates, so neither consumer reprocesses history.
Step 4: Run deletion against the vault only
The deletion orchestrator removes the buyer's mapping inside the regulatory window. Lake partitions hold tokens, not people, so no historical partition is rewritten and the non-PII parts of every sale stay intact.
- sale events (source, Kafka)
- tokenizer (transform, Spark)
- tokenization vault (storage, PostgreSQL)
- fx enrichment stream (transform, Flink); freshness: real-time
- boutique store (storage, PostgreSQL)
- sales data lake (storage, object storage)
- eod fx backfill (transform, Spark); freshness: < 24h
- finance warehouse (storage, warehouse)
- deletion orchestrator (transform, Airflow)
- boutique dashboard (consumer, Grafana); freshness: < 1min
- finance reporting (consumer, Metabase)
- sale events -> tokenizer
- tokenizer -> tokenization vault
- tokenizer -> fx enrichment stream
- fx enrichment stream -> boutique store
- fx enrichment stream -> sales data lake
- sales data lake -> eod fx backfill
- eod fx backfill -> finance warehouse
- boutique store -> boutique dashboard
- finance warehouse -> finance reporting
- deletion orchestrator -> tokenization vault
- Source + tokenize: sale events, tokenizer, tokenization vault
- Streaming + lake: fx enrichment stream, boutique store, sales data lake
- Finance + deletion: eod fx backfill, finance warehouse, deletion orchestrator
- Consumers: boutique dashboard, finance reporting
- One rate, buyer on the row
- The dashboard is right and finance disagrees with the official report. Deleting a buyer means rewriting lake partitions or dropping sales finance still needs.
- Both rates, buyer behind a token
- Each reader gets its own rate from the same row. Deletion is a single-row removal in the
tokenization vault, and the sale, amount and boutique attribution survive.
Common follow-up questions
- End-of-day rates get restated after the fact. What lets finance pick up the correction? (Tests whether the candidate re-runs the `eod fx backfill` for the affected dates and overwrites those partitions, leaving the live path alone.)
- A buyer asks for deletion but has an open dispute on a recent sale. What does the design do? (Tests legal-hold thinking: the vault mapping stays until the hold clears, and the sale row keeps its token.)