Built for The ZerOps Challenge (@WeMakeDevs Γ @zeropsio)
π’ Live: https://web-2c8a.prg1.zerops.app/ π» Code: https://github.com/bhuvaneshmp15-glitch/ayursutra

Panchakarma Clinical Dashboard
The problem nobody's solving
Panchakarma β traditional Ayurvedic detoxification therapy β isn't a single appointment. A patient undergoing Basti therapy goes through 7 sessions across 3 distinct clinical stages (Purvakarma preparation, Pradhankarma primary treatment, Paschatkarma recovery) spread over 2+ weeks.
The problem nobody's solving
Panchakarma β traditional Ayurvedic detoxification therapy β isn't a single appointment. A patient undergoing Basti therapy goes through 7 sessions across 3 distinct clinical stages (Purvakarma preparation, Pradhankarma primary treatment, Paschatkarma recovery) spread over 2+ weeks.
Yet almost every clinic manages this using tools built for booking a haircut: pick a date, pick a time, done. That mismatch causes real problems:
-->No protocol memory β the system has no idea Session 4 depends on Session 3 being completed
-->No conflict prevention β practitioners and treatment rooms get double-booked across overlapping sessions
-->Broken continuity β vitals, pulse diagnostics, and clinical notes end up scattered across paper files instead of tied to a specific treatment stage
So I built AyurSutra β a system that treats Panchakarma as what it actually is: a stateful, multi-stage clinical protocol.
What it actually does
When a practitioner selects a therapy type (Vamana, Virechana, Basti, Nasya, or Raktamokshana), AyurSutra:
1.Auto-generates the complete session sequence across all three stages
Assigns a practitioner and checks for scheduling conflicts at the database transaction level
2.Auto-shifts any colliding session to the next open time slot, instead of just rejecting the booking
3.Tracks stage-linked vitals (Nadi pulse, BP, weight) as structured data, not loose notes
4.Serves the daily schedule from a Valkey cache so the dashboard loads instantly, even under load

Pick a therapy type β the backend generates the entire multi-week protocol automatically.

Every patient's journey is tracked stage by stage β not just as a list of appointments.
Architecture β built to actually use Zerops, not just deploy on it
I wanted this to genuinely demonstrate multi-service infrastructure, not a single monolith with a database bolted on. Here's the full stack, all running on Zerops:
Client Browser
β
βΌ
web (nginx) ββ serves React frontend, proxies /api to β
β
βΌ
api (Bun + Hono) ββ the core engine
β
ββββΊ db (PostgreSQL) ββ patients, plans, sessions, vitals
ββββΊ cache (Valkey) ββ today's schedule, sub-ms reads
ββββΊ storage (S3) ββ clinical documents, progress photos
worker (Node.js) ββ runs every 2 minutes:
re-audits conflicts, syncs Valkey cache, logs reminders
Six services, one project, wired entirely through Zerops' internal networking β no manual VPC config, no separate hosting for each piece.

All six services, one Zerops project, zero manual networking config.
The interesting engineering bit: conflict auto-shifting
Most booking systems just reject a request if there's a conflict. I didn't want that β a practitioner shouldn't have to manually retry five times to book a valid slot. Instead, the scheduling engine runs inside a Postgres transaction, checks for interval overlaps against existing sessions:
ts
candidateStart < slot.end && candidateEnd > slot.start
If it finds a collision, it automatically walks forward through the day's slot grid (09:00, 10:30, 12:00, 14:00, 15:30, 17:00) until it finds one that's free β and logs the shift so it's fully auditable.
Why Valkey matters here
The clinical dashboard needs to load instantly β a practitioner glancing at "who's next" shouldn't wait on a SQL query. The background worker recomputes and writes today's full schedule into Valkey every 2 minutes (ayursutra:today_schedule), and the dashboard reads from there first, falling back to Postgres only if the cache is cold. That's the difference between a demo that feels production-grade and one that doesn't.
"Live schedule, served from cache β not a database query on every page load."
What's next
If I keep building on this: WhatsApp/SMS reminders triggered off the worker's queue, multi-clinic support for practitioner networks, and a mobile companion app for practitioners to log Nadi diagnostics hands-free during a session.

Top comments (0)