System Architecture
How the apps, the Go backend, the Cloudflare edge, the data stores and the third-party integrations fit together β optimized for low cost, offline-first villages, and scale to millions.
1. Architectural principles
Platform holds no money
All funds sit in the payment gateway's escrow and split directly to partners/Points. No RBI nodal account.
Offline-first
Apps queue actions locally and sync; the network is treated as unreliable by default.
Modular monolith first
One Go binary with clean module boundaries; extract services (match/geo) only when scale demands.
Push work to the edge
Cloudflare Workers terminate static, cache, rate-limit and auth-precheck before origin.
Money is an append-only ledger
Every rupee movement is an immutable event; balances are projections. Auditable by design.
Idempotent & event-driven
Every external call (PG, SMS, KYC) is idempotent and webhook-reconciled; nothing assumes a single happy reply.
2. High-level topology
flowchart TB
subgraph Clients["Client surfaces (Flutter + Web)"]
PA["π± Partner app"]
BA["π± Book app"]
DA["π± Dispatch / Hub"]
WEB["π» Next.js PWA
web booking + admin"]
WA["π¬ WhatsApp bot / IVR"]
end
subgraph Edge["Cloudflare edge"]
CF["CDN Β· WAF Β· DNS
Workers (auth precheck, cache, rate-limit)"]
R2["R2 object store
POD photos Β· KYC docs (no egress fee)"]
end
subgraph Core["Go backend (modular monolith)"]
GW["API gateway / BFF
REST + WebSocket"]
AUTH["Auth + KYC module"]
BOOK["Booking + state machine"]
MATCH["Matching engine"]
GEO["Geo + routing"]
PAY["Payments + escrow + ledger"]
NOTIF["Notifications"]
FRAUD["Fraud / trust scoring"]
end
subgraph Data["Data stores"]
PG["π PostgreSQL + PostGIS
(ACID core, ledger, geo)"]
REDIS["β‘ Redis
live locations Β· ETA Β· surge Β· queues"]
end
subgraph Ext["Third-party"]
RZP["Razorpay (primary)"]
CFP["Cashfree (fallback + Easy KYC)"]
VAHAN["VAHAN / Sarathi"]
MAPS["Maps + OSRM"]
SMS["SMS / IVR / WhatsApp API"]
FCM["FCM push"]
end
PA & BA & DA & WEB --> CF
WA --> NOTIF
CF --> GW
CF --- R2
GW --> AUTH & BOOK & MATCH & GEO & PAY & NOTIF & FRAUD
AUTH --> CFP & VAHAN
PAY --> RZP & CFP
GEO --> MAPS
NOTIF --> SMS & FCM
Core --> PG & REDIS
classDef e fill:#fff3e0,stroke:#f4920b,color:#8a5200;
classDef c fill:#e7f4ec,stroke:#1b7f4b,color:#115c36;
classDef d fill:#e8f0fb,stroke:#1f5fae,color:#143d6e;
class CF,R2 e; class GW,AUTH,BOOK,MATCH,GEO,PAY,NOTIF,FRAUD c; class PG,REDIS d;
3. Client architecture (Flutter + Next.js)
One Flutter codebase produces three flavors (Partner / Book / Dispatch) β shared design system, i18n, maps, networking and an offline sync layer; role-gated screens differ. The Next.js PWA serves public web booking + the ops/admin console.
| Layer | Choice | Why |
|---|---|---|
| App framework | Flutter (Material 3) | One team, small APK for low-RAM devices, great offline + maps |
| State | Riverpod / Bloc | Predictable, testable, survives process death |
| Local store | Drift (SQLite) + outbox queue | Offline-first: actions persist and replay on reconnect |
| Realtime | WebSocket (live track) + FCM (push) | Battery-aware location streaming; push for offline jobs |
| Web | Next.js PWA | Public booking without an app + admin dashboards; installable |
| i18n | Hindi-first, vernacular + audio | Low-literacy users; icon/photo-led UI |
4. Backend modules (Go)
A single deployable Go binary, internally partitioned into modules with explicit interfaces so the hottest ones (matching, geo) can be peeled into their own services later without rewrites.
| Module | Responsibility | Deep-dive |
|---|---|---|
auth | Phone-OTP, sessions, RBAC, Cashfree Easy KYC, VAHAN/Sarathi, liveness, trust tiers | Onboarding & KYC |
booking | Booking lifecycle & state machine, parcels, legs, OTP/POD, cancellation/refund | Booking flow |
matching | Eligibility matrix, scoring, dispatch cascade, bundling-first, fairness | Matching |
geo | Live locations, geofencing, addressing, routing (OSRM), VRP batching, ETA | Geo Β· Routing |
payments | Gateway abstraction (RZPβCF), escrow hold/release, append-only ledger, split, payouts, reconciliation | Payments Β· Split |
pricing | Fare formula, vehicle rates, tiers, surge, commission/take-rate | Commission |
notify | FCM, SMS, IVR, WhatsApp; templated multilingual messages | β |
fraud | Device/SIM fingerprint, mock-location, velocity & graph anomaly, trust scoring | Edge cases |
5. Data stores
PostgreSQL + PostGIS is the ACID system of record β transactional bookings, the append-only money ledger, and geospatial queries (nearest partner, geofence containment). Redis holds hot/ephemeral state: live partner GPS (geo sets), ETAs, surge multipliers, OTP caches, dispatch queues, rate-limit counters. Cloudflare R2 stores POD photos and KYC documents (no egress fee β a real saving at scale).
escrow_ledger, payout, wallet_txn are never updated in place β balances are computed projections. This makes reconciliation and audit deterministic. See Split-Money Settlement.6. Core data model
erDiagram
USER ||--o| PARTNER_PROFILE : has
USER ||--o{ BOOKING : books
PARTNER_PROFILE ||--o{ VEHICLE : owns
PARTNER_PROFILE ||--o{ KYC_DOCUMENT : submits
PARTNER_PROFILE }o--o{ RIDECHAIN_POINT : serves
BOOKING ||--|{ PARCEL : contains
BOOKING ||--|{ LEG : "splits into"
LEG }o--|| PARTNER_PROFILE : "assigned to"
LEG }o--o| RIDECHAIN_POINT : "from/to"
BOOKING ||--|| PAYMENT : "paid by"
PAYMENT ||--|{ ESCROW_LEDGER : records
LEG ||--o| PAYOUT : "releases"
BOOKING ||--o{ RATING : rated
BOOKING ||--o{ FRAUD_SIGNAL : flags
USER {
uuid id
string phone
enum role
string lang
}
BOOKING {
uuid id
enum status
enum pickup_mode
enum drop_mode
enum speed_tier
int total_fare_paise
}
PARCEL {
enum category
enum size_bucket
enum weight_bucket
int declared_value_paise
bool fragile
}
LEG {
int seq
enum status
string pickup_otp
string drop_otp
int payout_paise
}
ESCROW_LEDGER {
uuid id
enum entry_type
int amount_paise
string gateway_ref
}
Booking decomposes into ordered Legs (one for direct, many for relay/milk-run); money splits per leg via the escrow ledger. Partners serve many Points (coverage) but each parcel is custody-locked to one Point + one partner per leg.7. Anatomy of a booking request
sequenceDiagram
autonumber
participant App as Book app
participant CF as Cloudflare edge
participant GW as Go API
participant PR as Pricing
participant PAY as Payments
participant MA as Matching
participant PT as Partner app
App->>CF: POST /bookings (params)
CF->>GW: forward (auth prechecked)
GW->>PR: quote(size,weight,vehicle,geo,tier)
PR-->>GW: fare + breakdown
GW->>PAY: create escrow order (Razorpay β fallback Cashfree)
PAY-->>App: payment intent
App->>PAY: pay (UPI/wallet)
PAY-->>GW: webhook: captured (idempotent)
GW->>MA: dispatch (bundling-first β on-demand)
MA->>PT: offer leg(s)
PT-->>MA: accept
MA-->>App: partner + ETA (live track begins)
8. Third-party integrations
| Concern | Provider | Notes |
|---|---|---|
| Payments + split | Razorpay Route (primary) Β· Cashfree Easy Split (fallback) | Success-rate routing behind a thin gateway interface; escrow + per-leg split |
| KYC | Cashfree Easy KYC | Aadhaar OKYC, PAN, bank/UPI penny-drop, name/face match |
| Vehicle | VAHAN (RC) Β· Sarathi (DL) | Motorized partners only; cycle/cart skip |
| Maps / routing | Maps SDK + self-hosted OSRM | OSRM on rural OSM extracts keeps routing cost ~0 |
| Messaging | SMS Β· IVR Β· WhatsApp Business API Β· FCM | No-app booking + OTP + status; multilingual templates |
| Object storage | Cloudflare R2 | POD photos, KYC docs β no egress fees |
9. Security & compliance posture
- Aadhaar never stored raw β tokenized + masked; KYC docs encrypted at rest in R2.
- PCI-safe β no card data touches our servers; gateway tokenization only.
- Transport security β TLS everywhere (Cloudflare-terminated), mTLS to sensitive internal services.
- RBAC + audit log on every money and KYC event.
- DPDP Act 2023 β explicit consent, purpose limitation, data-retention & breach handling.
- Masked calling so partner/customer numbers are never exposed.
10. Deployment & environments
Containerized Go binary on low-cost compute behind Cloudflare; managed Postgres with read replicas and Redis. Three environments (dev / staging / prod) with separate Razorpay & Cashfree test vs live keys (both already held under Wetware). CI runs go vet, race tests, and the docs publish-doc link/asset checks. Detailed cost & scaling model in Scale & Low-Cost.