Jaipur--°C
Back to Projects
In-progressTypeScriptNode.jsFastify+5 more

Rova (Chalo-X) — Real-Time Ride Sharing

A real-time ride-hailing monorepo engineered around dynamic negotiated pricing: Fastify backend with WebSocket gateway, double-entry ledger accounting, finite state machine ride lifecycle, PGlite/PostgreSQL persistence, and dual React 18 SPAs for riders and drivers.

Timeline

2026

Role

Solo — full stack architecture, real-time WebSocket protocol, double-entry ledger, rider & driver web apps

Status
In-progress

Technology Stack

TypeScript
Node.js
Fastify
WebSocket
PostgreSQL
React
Tailwind CSS
Turborepo

Key Challenges

  • Architecting a bounded 3-round negotiation state machine between riders and multiple candidate drivers with sub-second WebSocket synchronization
  • Guaranteeing financial integrity and zero money leaks when riders negotiate fares down to ₹0 while drivers receive 100% take-home pay
  • Preventing race conditions and stale ride state transitions across distributed rider and driver client connections
  • Maintaining zero-Docker instant local development ergonomics using embedded PGlite WASM alongside production PostgreSQL 16 compatibility

Key Learnings

  • Double-entry ledger accounting with immutable transaction entries ensures auditability and guarantees that platform promotional subsidies balance to zero
  • Strict finite state machine (FSM) validation in a shared TypeScript contracts package blocks illegal out-of-order ride transitions across all clients
  • Decoupling the rider-side platform fee from driver compensation eliminates gross-vs-net confusion and transparently communicates platform sustainability
  • Embedded PGlite running in-process eliminates container overhead during development while maintaining bit-level PostgreSQL SQL and migration parity

Overview

Traditional ride-hailing platforms enforce centralized algorithmic surge pricing where both riders and drivers have no agency over the fare. Drivers lose up to 30% in platform commissions, while riders face unpredictable price spikes.

Rova (Chalo-X) is a real-time ride-hailing platform engineered around dynamic negotiated pricing:

  • Riders negotiate: Passengers propose what they are willing to pay for a trip (even down to ₹0).
  • 100% Driver Take-Home: A driver's counteroffer or accepted fare is their exact take-home pay; no platform commission is ever deducted from the driver.
  • Transparent Platform Fee: The platform fee is billed separately on the rider's invoice with an upfront explanation of how infrastructure and safety costs are funded.

The platform is structured as a high-performance Turborepo monorepo featuring dual React 18 web apps (rider and driver), an asynchronous Fastify WebSocket core, and a shared TypeScript protocol layer.

System Architecture

The monorepo separates real-time negotiation and trip coordination into dedicated packages and client applications:

WebSocket & RESTWebSocket & REST

Rider Web App (React 18 + Leaflet)

Real-Time Gateway (Fastify)

Driver Web App (React 18 + Leaflet)

Ride Lifecycle Finite State Machine

Double-Entry Accounting Ledger

PostgreSQL 16 / PGlite WASM

@chalo/protocol (Shared Contracts & Money Math)

Monorepo Structure

Package / AppStackCore Responsibility
apps/rider-webReact 18, Vite, Tailwind CSS, LeafletRide booking, live fare negotiation UI, route tracking, digital invoice
apps/driver-webReact 18, Vite, Tailwind CSS, LeafletLive broadcast radar, counteroffer controls, turn-by-turn navigation, wallet payouts
services/coreFastify, WebSocket, Drizzle ORMSession auth, real-time dispatch, state machine enforcement, ledger accounting
packages/protocolTypeScriptSingle source of truth: Zod schemas, FSM definitions, integer money math

Key Technical Decisions

1. Bounded Negotiation State Machine

Unconstrained bidding loops lead to infinite haggling and user drop-off. Rova implements a strictly bounded 3-round negotiation state machine:

Rider sets custom offerDispatched to nearbydrivers (45s window)Driver accepts offerDriver counters fareRider accepts counter (20swindow)Rider submits final counterDriver acceptsDriver declines or timerexpiresNegotiation window expires(120s)Fallback to standard listpriceOTP verified at pickupDestination reached &Ledger settled

RIDER_OFFER

BROADCAST

ACCEPTED

DRIVER_COUNTER

FINAL_OFFER

FALLBACK

STANDARD_DISPATCH

TRIP_STARTED

COMPLETED

Every stage has enforced timeouts (45s initial broadcast, 20s counter responses, 120s global negotiation window). If negotiation lapses, the rider is offered a fallback dispatch at standard algorithmic list price.

2. Double-Entry Accounting Ledger

When riders negotiate fares below operational costs (down to ₹0), financial consistency cannot rely on naive balance updates. Rova enforces strict double-entry bookkeeping with immutable journal lines:

RiderPayment = NegotiatedOffer + PlatformFee + GST + Tolls
  • Every transaction creates paired debit and credit entries in integer currency units (paise/cents) to eliminate IEEE-754 floating-point drift.
  • If a rider offers ₹0, the driver's negotiated payout is balanced via an internal platform PROMO_EXPENSE equity account, ensuring the balance sheet always sums to zero.

3. Sub-100ms Dev Loop with Embedded PGlite

To avoid heavy Docker Compose startup overhead and slow container rebuilds during development, the backend leverages PGlite (PostgreSQL compiled to WebAssembly) running directly in the Node.js process. It supports full PostgreSQL SQL syntax, triggers, and migrations with zero setup, booting in under 100ms while retaining bit-level parity with production PostgreSQL 16.

4. Shared Protocol & Invariant Verification

All WebSocket payloads, REST DTOs, and state machine transitions are defined once in @chalo/protocol. A comprehensive 64-assertion verification suite simulates multi-client concurrent bidding wars, ensuring that no race condition can double-assign a ride or violate ledger balancing invariants.

Tech Stack Summary

  • Monorepo: Turborepo, pnpm workspaces, TypeScript
  • Backend & Realtime: Node.js 20, Fastify, @fastify/websocket, Drizzle ORM
  • Database: PostgreSQL 16 (production) / PGlite WASM (development)
  • Frontend: React 18, Vite, Tailwind CSS, Leaflet (OpenStreetMap)
  • Testing: Vitest, Invariant Verification Test Suite

built by shiv ratan
© 2026. All rights reserved.