Design delivery driver payment system
Company: Rippling
Role: Software Engineer
Category: System Design
Difficulty: medium
Interview Round: Technical Screen
##### Question
Design and implement an in-memory, object-oriented service to track delivery-driver work and compute their payroll. The service must support the following operations (method names vary by interviewer, but the semantics are the same):
1. **add_driver(driver_id, usd_hourly_rate)** — register a driver with an hourly rate.
2. **record_delivery(driver_id, start_time, end_time)** — log a completed delivery work interval for a driver. Times have at least 1-second precision; a single delivery is at most ~3 hours and is recorded only after it has completed.
3. **get_total_cost()** — return the total accrued labor cost across all drivers and all recorded deliveries (independent of what has been paid).
4. **pay_up_to(pay_time)** — settle/mark wages as paid for all work performed up to the given timestamp. Calling it repeatedly with the same (or earlier) time must not double-pay.
5. **get_total_cost_unpaid()** — return the total unsettled wages remaining after payouts.
In your design, discuss and justify:
- **Data models and persistence** — how drivers, delivery intervals, and payout state are stored (in-memory maps for the interview; relational tables for production).
- **Time handling** — units, timezone, endpoint inclusivity, and validation of start/end ordering.
- **Money handling** — avoiding floating-point error, the cost formula, and the rounding strategy.
- **Payout semantics** — whether `pay_up_to` settles a whole delivery (mark-paid when `end_time <= pay_time`) or a partial slice of an in-progress interval (settle up to `min(end_time, pay_time)`), and how idempotency / monotonicity is guaranteed.
- **Overlapping and back-to-back intervals** — how to avoid double-paying overlapping work, and that adjacent (`end == next start`) intervals are not overlaps.
- **Late / back-dated deliveries, edits, and cancellations** — how the system stays correct when a delivery is added or changed after a payout already ran.
- **Performance** — expected time/space complexity of each operation and which indexes/aggregates make them fast.
Provide a clean object-oriented implementation and call out any simplifications you make for the interview versus what a production system would require.
Quick Answer: A Rippling software-engineer system-design screen: build an in-memory, object-oriented driver-payroll service with add_driver, record_delivery, get_total_cost, pay_up_to, and get_total_cost_unpaid. It tests time-interval accounting, integer-cents money math, idempotent partial-vs-whole payout state, double-pay prevention for overlapping work, and a clean path from prototype to a transactional, indexed production design.