System Design: End-to-End Payouts from Order Lifecycle Events
You are designing a system that computes delivery driver (Dasher) payouts from an event stream of order lifecycle events. The stream includes only two event types:
-
ACCEPT(orderId, dasherId, timestamp)
-
FULFILL(orderId, dasherId, timestamp)
Assume the happy path input is valid (each order is accepted then fulfilled by the same dasher exactly once in-order). You must design for scale (high write throughput) and correctness, and proactively address failure modes.
Requirements
-
Event ingestion and semantics
-
Define ingestion semantics for ACCEPT and FULFILL events.
-
Explain idempotency, deduplication, and trade-offs among exactly-once vs at-least-once delivery.
-
Data models and storage
-
Propose data models to support:
-
High write throughput for raw events and derived state.
-
Efficient payout queries per dasher and pay period.
-
Backfills and reprocessing.
-
Specify storage choices (e.g., event log, OLTP/NoSQL, data lake), partitioning, and indexing.
-
Computation of payouts
-
Describe how payouts are computed from the lifecycle (e.g., payout triggered at FULFILL, adjustments, etc.).
-
Outline batch vs streaming computation, how to finalize a pay period, and how to support backfills and reconciliation.
-
Data quality and remediation
-
Proactively detect and remediate data loss/corruption:
-
FULFILL arrives without a prior ACCEPT.
-
ACCEPT has no subsequent FULFILL.
-
Duplicate events.
-
Out-of-order delivery.
-
Define SLAs, dead-letter queues, and correction strategies.
-
APIs
-
Define APIs for:
-
Event ingestion (ACCEPT/FULFILL).
-
Querying a dasher’s payout for a given local pay period.
-
Explain handling of timezone and Daylight Saving Time (DST).
-
Monitoring, alerting, and correctness
-
Define key metrics, alerts, and correctness checks.
-
Be explicit about trade-offs and consistency guarantees.