fivenines
12/38

Guided Problem

YourRide Build 10: Serve History Without Joining Production

Time
20m
Level
foundation
Artifacts
not specified
Progress0%
Lesson 1.10 99.9%

Ratings, history, support, and admin

Everything here consumes the records earlier lessons produce: trip events (1.7), ledger entries (1.8), onboarding states (1.2). These are the "supporting" services of 1.1 — lower stakes, but they carry the trust of the marketplace.

The simplest version would build history by joining every authoritative service at read time and let support repair exceptional rows directly. The better question is what survives when that assumption fails. Read models must be rebuildable from owned facts, and every support mutation must pass through the service that protects the relevant invariant.

Ratings: after completion, each party rates the other (1–5 + tags) within a window; a driver's public rating is the mean of the last 500 trips, recomputed asynchronously, with low ratings feeding quality review. Ratings are double-blind until both submit or the window closes — this measurably reduces retaliation bias. Trip history is a read-optimized, denormalized view: the trip row joined with fare, receipt URL, and route thumbnail is precomputed at completion into a history table, because riders read history thousands of times more often than trips write to it. This read/write asymmetry — build the view at write time, serve reads cheaply — is CQRS in miniature and returns at full scale in 2.10.

Support gets a ticket system linked to trips: an operator sees the trip timeline (every state transition, with timestamps and GPS), the ledger entries, and comms history in one console — the payoff for all that immutable event recording. Scoped tools (refund up to a limit, adjust a fare, ban a user) are audited actions, not database pokes. Safety: share-trip links (a signed, expiring URL to a live trip view) and an SOS button that snapshots trip + location and escalates. Admin/city-ops: manage rates, surge caps, driver approvals per city.

flowchart LR
  subgraph SRC ["Systems of record"]
    T[("Trip events")]
    L[("Ledger")]
    ID[("Identity")]
    CM[("Comms log")]
  end
  T --> HV["History view builder — denormalize at completion"]
  HV --> H[("History table — read optimized")]
  H --> RA["📱 Rider: trip history"]
  T --> RS["Ratings service"]
  RS --> DQ["Driver quality pipeline"]
  SRC --> CONSOLE["🖥️ Support console — one trip, whole story"]
  CONSOLE --> ACT["Audited actions — refund, adjust, ban"]
  ACT --> L
  ACT --> ID
Supporting services are mostly views over the systems of record, plus a small set of audited write-back actions.

Now consider what happens when a projection is corrupted while a support operator needs to correct a completed trip. If the central guarantee disappears here, the design has confused an optimization with a correctness boundary.

Next step

See what actually stuck.

Take the practice scenarios now.