What actually runs

Runtime loops

Each loop is implemented, annotated on the source file with @docs, and callable over HTTP.

Click a route to hit the live server. Open the file path in the repo — the comment at the top of that file is the same story in engineer voice.

Loop · Every 3–5s per online driver

GPS ingest

Hot path writes presence only. Postgres is sampled every 30 seconds so 100k drivers do not melt the database.

POST /api/v1/geo/pings
  1. Driver app or socket sends lat/lng.
  2. Cell ids computed with H3 resolution 9 (block) and 8 (neighborhood).
  3. Previous cell membership is removed; new cell set is updated.
  4. A 30s sample flag decides whether to park a durable row in the outbox.

backend/modules/geo/application/ingest.ts

LocationIngest.pingRedis/memory upsert + downsample key

backend/modules/geo/infrastructure/presence-store.ts

PresenceStore.upsertH3 r8/r9 membership sets, 45s TTL

backend/realtime/socket-server.ts

driver:pingSame ingest over WebSocket

$0 demo: Memory hash + sets inside the Next.js process.Scale: REDIS_URL (Upstash). No Kafka required for presence.

Loop · On search / dispatch tick

Proximity lookup

k-ring over H3 cells, then haversine rank. Mapbox/Google/OSRM only if you add keys.

GET /api/v1/geo/drivers
  1. Convert the query point to H3.
  2. Load driver ids from every cell in the radius ring.
  3. Filter by vehicle class and available status.
  4. Attach distance and ETA (haversine in demo).

backend/modules/geo/domain/h3.ts

cellsInRadiusgridDisk for radius

backend/modules/geo/application/routing.ts

estimateEtaProvider chain, haversine last

$0 demo: Pure CPU + memory presence. Public OSRM is optional and unused unless asked.Scale: REDIS_URL, then MAPBOX_ACCESS_TOKEN when you want traffic-aware ETAs.

Loop · Worker every 2s, or POST /dispatch/match

Batch matching

Hungarian assignment over open searching trips vs available drivers in nearby cells.

POST /api/v1/dispatch/match
  1. Group open trips by H3 r8.
  2. Load available drivers in an 8 km ring.
  3. Build a cost matrix; dummy cells are padded so extras stay unmatched.
  4. Transition winners requested/searching → matched with an idempotency key.

backend/modules/dispatch/domain/hungarian.ts

hungarianMin-cost assignment

backend/modules/dispatch/domain/matching.ts

batchMatchDistance, acceptance, class, traffic

backend/modules/dispatch/domain/surge.ts

surgeMultiplierPer-cell EMA surge

backend/workers/index.ts

matchOpenTrips loopPoll + AMQP trip.requested

$0 demo: In-process worker is optional; the demo POST runs one tick.Scale: RABBITMQ_URL or keep the 2s poll. Kafka only after sustained event volume.

Loop · On each state change

Trip lifecycle

Strict FSM with actor checks. Idempotency-Key required on HTTP. Same-state retries are no-ops.

POST /api/v1/trips/:id/transitions
  1. requested → searching (system)
  2. searching → matched (system/admin)
  3. matched → driver_en_route → driver_arrived → in_progress → completed
  4. Cancel is allowed until in_progress; after that only safety/admin.

backend/modules/trips/domain/states.ts

assertTransitionLegal edges + actors

backend/modules/trips/application/lifecycle.ts

TripLifecycle.transitionVersion bump, events, push

app/api/v1/trips/[id]/transitions/route.ts

POSTHeader Idempotency-Key

$0 demo: Memory trip repo. Same code path as Postgres later.Scale: DATABASE_URL so trips survive process restart.

Loop · Booking hold, capture at completion, payout on demand

Escrow & ledger

Double-entry cents. Demo writes the journal without Stripe. Production refuses if GO_LIVE blockers remain.

POST /api/v1/payments/holds
  1. Authorize hold (stripe_pending ↔ platform_clearing).
  2. Capture splits fees, insurance pool, host payable, optional driver share.
  3. Refund reverses clearing to the processor.
  4. Cash-out moves payable to stripe_pending (Connect transfer in production).

backend/modules/payments/domain/ledger.ts

holdAtBooking / captureAndSplitZero-sum journals

backend/modules/payments/application/escrow.ts

EscrowServiceStripe when keys exist

backend/shared/golive/status.ts

assertProductionMoneyGo-live gate

$0 demo: Simulated PaymentIntent. Ledger still balances to zero.Scale: STRIPE_SECRET_KEY + Stripe Connect. No Adyen required.

Loop · On driver_verified → policy_bound

PVSP per-trip binder

Named insured = driver. Additional insured = host. Lula/Tint/ABI or simulated. Marketplace is never the policyholder.

POST /api/v1/pvsp/leases/:id/transitions
  1. Lease opens requested.
  2. Identity + MVR mark driver_verified.
  3. Binder API: $45k/$90k/$15k, VIN, term.
  4. Eight-angle photos, then key-unlock timestamp.
  5. Post-trip photos terminate the binder. Claims POST to the carrier.

backend/modules/pvsp/domain/states.ts

assertPvspTransitionCRT FSM

backend/modules/pvsp/application/binder.ts

InsuranceBindingService.bindInsurTech or sim_

backend/modules/pvsp/application/agreements.ts

CrtAgreementService.signHold harmless hash

$0 demo: INSURANCE_PROVIDER=simulated (default).Scale: INSURANCE_API_URL + Lula/Tint/ABI keys. Surplus-lines partner license.

Loop · Arrival and return

Keyless access & inspection

Four timestamped photos, then BLE/cellular unlock. Webhook is optional.

POST /api/v1/fleet/unlock
  1. Driver arrives (FSM).
  2. Pre-trip inspection with four photos + odometer.
  3. Unlock command; simulated provider unless IOT_UNLOCK_WEBHOOK is set.
  4. Post-trip inspection closes the evidence pack.

backend/modules/fleet/application/inspection.ts

InspectionService.submit≥4 photos

backend/modules/fleet/application/access.ts

VehicleAccess.unlockArrival-gated

backend/modules/fleet/application/insurance.ts

quoteTripInsurancePeriod 1/2/3

$0 demo: Simulated IoT accept. Photos stored as object ids (memory signed URLs).Scale: IOT_UNLOCK_WEBHOOK and R2/S3 via UPLOAD_DRIVER=s3.

Loop · On trigger / speed anomaly

SOS & telemetry

Share link, dispatch push, live lat/lng. Speed > 40 m/s is flagged.

POST /api/v1/safety/sos
  1. Authenticated actor posts tripId + coordinates.
  2. Share URL minted on the public site.
  3. Push to safety-dispatch (log channel in demo).
  4. Socket rooms trip:{id} and safety-dispatch receive the event.

backend/modules/safety/application/sos.ts

SafetyService.triggerEvent + notify

backend/realtime/socket-server.ts

sos:triggerBroadcast to trip room

$0 demo: In-process events. FCM/APNs URLs optional.Scale: FCM_PUSH_URL / APNS_PUSH_URL when you enroll mobile apps.

Loop · Vendor webhook / on-demand GET

Telematics hook-in

One ping shape. Demo is neighborhood-only simulated. Flip TELEMATICS_PROVIDER when hardware is chosen.

POST /api/v1/fleet/telematics
  1. Vendor POSTs a location payload (or demo writes a simulated ping).
  2. Adapter normalizes to neighborhood + odometer + ignition.
  3. Hosts read /owners/monitor without a street pin.
  4. Desk reads /admin/telematics and may see coordinates.

lib/telematics/vendors.ts

TELEMATICS_VENDORSAPI catalog

lib/telematics/adapter.ts

normalizeVendorPayloadlat/lng/odometer/ignition

app/api/v1/fleet/telematics/route.ts

POSTWebhook + desk secret

$0 demo: Simulated ping in memory / .data/telematics-pings.json.Scale: TELEMATICS_PROVIDER + that vendor’s keys. Hardware install at inspection.