High-Level Architecture


Domain Breakdown

Auth

Tables: users, otp_sessions, user_sessionsPhone OTP → JWT pair. Stateless access token (24h) + rotation-based refresh token (30d). Sessions hashed — never plaintext in DB.

User Profile

Tables: users (shared with Auth)Reads/writes profile fields. phone and aadhaar are immutable via this module. Aadhaar returned masked: XXXX-XXXX-1234.

Wallet

Tables: customer_walletsAuto-created async on first login. Tracks Juspay customer ID + wallet ID. Retry worker handles failures (5 attempts, exponential backoff).

Insurance

Tables: insurance_plans, insurance_policies, policy_dependantsLocal plan catalog + purchased policy references. All purchase/claims delegated to Narayana Health APIs.

Payments

Tables: payment_ordersSingle endpoint for wallet top-up and insurance purchase. Juspay Session API → app opens SDK → poll order status.

Call Doctor

Tables: chat_sessions, chat_messagesNama Agent conversation → clinical summary → Aathma assignment. Session locked after submission.

User Journey — Full Flow


Background Retry Worker

The wallet provisioning worker runs on startup and polls every 10 seconds for stalled wallet creation jobs.

Security Model

JWT Access Token

24-hour expiry. Claims: user_id, phone. Validated on every protected endpoint via middleware.

Refresh Token Rotation

30-day opaque token. Stored as SHA-256 hash only — never plaintext. Old session revoked atomically before new pair issued.

OTP Security

OTP hash stored (never plaintext). Single-use via verified_at. Attempt counter prevents brute force.

PII Protection

Aadhaar stored as last 4 digits only. All PII fields encrypted at rest (application-level). Masked in all API responses.
UAT Note: In UAT/sandbox mode, the OTP is hardcoded as 123456 — no SMS is sent. In production, ValueFirst (or equivalent) SMS provider sends the real OTP.