Case study · № 112026Code for Communities

SwasthyaSetu

A multilingual, real-time platform that gives a District Health Officer a live command view of every PHC and CHC — and puts AI to work on the operational gaps. Its wedge: cross-facility visibility, so a center about to stock out can pull near-expiry surplus from a neighbour before either shortage or wastage happens.

RoleSolo
Data models19
LanguagesEN · हि · ગુ
TrackSmart Health
swasthyasetu · hero
ClientAPIEngineDataReact PWAi18n · EN/HI/GUVoice intakeWeb Speech APINestJS APIdomain modulesSocket.iodistrict roomJWTtenant by districtRedistributionFEFO · HaversineForecastdays-to-stockoutGemininarrate onlyPostgreSQLNeon · StockLedger (append-only)intakelive
Fig. 1 · Smart-health platform — deterministic redistribution & forecast engines over an append-only Postgres ledger; Gemini only narrates; realtime district view; EN/HI/GU.
01

Context

Track 3 of Code for Communities (Google Cloud × Hack2skill): primary and community health centers run daily operations on paper registers and phone calls, with no real-time, cross-facility visibility. The result is medicine stock-outs next to unused surplus expiring a few kilometres away, untracked absenteeism, and bed strain during an outbreak that nobody upstream sees until the monthly paper report lands — weeks late.

I built the whole thing solo — data model, backend, the React PWA, the AI layer, and the docs — modelling a real district hierarchy for Gandhinagar (District → CHC → PHC + drug warehouse).

district · live map
02

The wedge: redistribution

Most dashboards stop at showing you the shortage. The interesting part is doing something about it before it happens. The redistribution engine ranks donor facilities by near-expiry surplus, then by nearest (Haversine distance), then by who can spare the most — sizes a buffer-safe ~30-day transfer, picks the FEFO (first-expiry-first-out) batch, and proposes the move.

The District Admin approves in one tap and stock moves on both ends of the ledger. Shortage and wastage, solved with the same transfer.

surplus → shortage
03

Architecture

A pnpm + Turborepo monorepo: a NestJS API with a Socket.io gateway over Prisma/PostgreSQL (Neon), and a React 19 + Vite PWA. Nineteen Prisma models, built around an append-only StockLedger for audit and idempotency, with on-hand quantity materialized on batches and consumed FEFO by expiry.

The rule I held to: numbers are computed in code and the database; Gemini only reasons and narrates. Days-to-stockout, health scores, transfer sizing — all deterministic. Every Gemini call degrades to null on failure, so the core path never blocks on an AI service being up.

stock ledger · fefo
04

Multilingual, and speakable

Frontline staff don’t type well on a shared tablet, so intake is voice-first: the browser’s Web Speech API captures speech, Gemini parses it into { item, qty, action }, staff confirm, and the ledger appends — with a local fallback that keeps it working if Gemini is down. The whole UI and its alerts run in English, हिंदी, and ગુજરાતી via react-i18next.

05

Decisions & tradeoffs

  • AI narrates, code decides.Keeping every number out of the model’s hands is what makes the output trustworthy for a health officer signing off on a transfer.
  • A dependency-free SVG map.Facilities are colour-coded by alert severity in hand-rolled SVG. Google Maps is a clean drop-in later; I didn’t want a maps key on the critical path for a demo.
  • Honest scope.The design doc specs Redis, BullMQ workers, and Cloud Run. The built version runs realtime in-process on Socket.io with Postgres as the only hard dependency — those are documented as scale paths, not shipped code. I’d rather say that plainly than imply infrastructure that isn’t there.
06

What I would change

The realtime layer should move onto a Redis socket adapter before this runs across more than one API instance — in-process rooms are fine for a district demo, not for a state. And I’d put the health-score and forecast computation behind a job queue rather than computing on read, so the dashboard stays instant as the ledger grows.

Built with
NestJS 11React 19TypeScriptPostgreSQL (Neon)PrismaSocket.ioGemini 2.5 Flashreact-i18nextTailwindPWATurborepo
← PreviousRMC ERPNext →ParikshaMind
You found the trick.
Thanks for
looking closely.
↑ ↑ ↓ ↓ ← → ← → B A · konami