Uber Clone Example

Deep dive into modeling a ride-hailing system (Uber-like) using Domain-Driven Design, Event Storming, CQRS, and Event Sourcing. No JavaScript; semantic HTML only.

Overview

Model a ride-hailing platform with Riders, Drivers, Trips, Vehicles, and Payments. The goal is to show a complete lifecycle from ride request to payment, with domain-driven boundaries and event-sourced history.

Domain Model

  • Aggregates: Ride
  • Entities: Rider, Driver (with Vehicle), Ride, Payment
  • Value Objects: Location, GeoPoint, Fare, Currency
  • Domain Events: RideRequested, DriverAssigned, RideStarted, RideEnded, RideCancelled, PaymentProcessed

Commands

  • RequestRide
  • AcceptRide
  • StartRide
  • EndRide
  • CancelRide
  • UpdateLocation
  • ProcessPayment

Domain Events

  • RideRequested
  • DriverAssigned
  • RideStarted
  • RideEnded
  • RideCancelled
  • PaymentProcessed

Aggregates & Rules

Ride is the aggregate boundary. It enforces business rules like driver availability, surge pricing, ETA calculations, and safety checks (e.g., rider must be within service area, driver must be online).

Read Models & Projections

  • RideDetails
  • DriverAvailability
  • RideHistory
  • RevenuePerCity

Policies & Business Rules

  • SurgePricingPolicy: increase fare during demand spikes.
  • CancellationPolicy: time-based penalties and refunds.
  • DriverAcceptancePolicy: ensure driver can accept within allowed window.
  • RoutingPolicy: optimize ETA with real-time traffic data.

Integrations

  • Maps/Geocoding: pickup/dropoff coordinates
  • Routing: compute optimal routes
  • PaymentGateway: process fare
  • Notifications: push/SMS updates

Lifecycle Walkthrough

  1. Rider requests a ride (RequestRide).
  2. System matches with a nearby Driver (DriverAssigned).
  3. Driver starts the ride (RideStarted); location updates stream in.
  4. Ride ends at destination (RideEnded); fare calculated (Fare, PaymentProcessed).
  5. Ride history is stored and read models updated.

Sample Payloads

RideRequested payload example (conceptual JSON):


{
  "rideId": "ride_12345",
  "riderId": "rider_9876",
  "pickup": { "lat": 37.7749, "lng": -122.4194 },
  "dropoff": { "lat": 37.8044, "lng": -122.2711 },
  "requestedAt": "2026-04-30T12:34:56Z"
}
        

Diagram & Illustration

Ride-hailing architecture diagram
High-level Uber-like architecture: rider, driver, ride, payments, and maps services.

Data & APIs (Conceptual)

Provide data contracts for core ride flows. All payloads shown are conceptual and for modeling only.

  • RideRequest: riderId, pickup, dropoff, requestedAt
  • RideAssignment: rideId, driverId, estimatedEta
  • RideUpdate: rideId, location, status
  • PaymentIntent: rideId, amount, currency, method

Example payload (RideRequest):

{
  "rideId": "ride_9876",
  "riderId": "rider_1122",
  "pickup": {"lat": 37.7749, "lng": -122.4194},
  "dropoff": {"lat": 37.8715, "lng": -122.2730},
  "requestedAt": "2026-04-30T12:34:56Z"
}

Edge Cases

  • Driver unavailability during surge; rescheduling.
  • Rider cancels after a driver is assigned; cancellation fee rules.
  • Multi-city trips; regional pricing considerations.

Testing & Validation (Conceptual)

  • Event history verifications: ensure all domain events are emitted in order.
  • Read model projections reflect event stream accurately.
  • Policy gate checks (surge, cancellation) are enforced before command execution.