Case study №03
Sehat: built for my parents
A Hindi-first, voice-first health companion — local-first and free to run
- Role
- Solo builder
- Timeline
- 2026 · Personal
- Scale
- 2 apps, 1 codebase
Context
Sehat (सेहत) is the one project on this site where I made every decision — product, design, architecture, copy. It's a health companion for Indian parents aged 50–70 and the adult children who look out for them: parents log meals, water, medicines, mood and sleep; their kids see a live dashboard with trends and alerts.
The problem
Three constraints shaped everything. The users: elders won't use tiny-button English apps — so the parent app is Hindi-first, voice-first, with huge tap targets; you say “aaj do roti aur ek katori dal khayi” instead of filling a form. The network:connectivity can't be assumed — the app must be fully usable offline. The budget: ₹0/month — no paid SMS, no paid hosting, no paid APIs.
The architecture
Local-first, with a strict repository layer. Every screen talks to one data interface; behind it sits IndexedDB (via Dexie) that always works, and Supabase that takes over sync, realtime and server-side alert rules when configured. There are zero direct Supabase calls outside the db layer — the UI is provably backend-agnostic.
On the server, Postgres triggers maintain a pre-aggregated daily_summariestable on every write — the dashboard never scans raw logs, so it stays fast at any history length. The offline client mirrors the same recompute so a parent's streak is correct with no network. A long-press SOS inserts an alert that takes over the family dashboard in realtime and pushes to every child's device.
Key decisions
Chose local-first over backend-required
The honest MVP is one household on one phone. The app is fully functional with no config — IndexedDB is the database. Supabase is an upgrade path, not a dependency, and the repository layer means adopting it changed zero UI code.
Chose family code + PIN over phone OTP
OTP costs money per SMS and assumes elders keep one number. Instead: children authenticate normally; parents join with a 6-digit family code and a 4-digit PIN, and a Supabase edge function mints a custom signed JWT with a 1-year expiry — parents never get logged out.
Chose Postgres trigger pre-aggregation over client-side aggregation
Dashboards read only the trigger-maintained summary table. Queries stay O(days), not O(logs), and the rule logic lives in one place — the server — instead of drifting across clients.
Chose family-alert-only SOS over fake ambulance integration
v1 SOS alerts the family — realtime takeover plus push. Hospital dispatch would be theater without a real integration, so it's explicitly out of scope and the UI copy says so. Honesty is a feature.
Outcomes
- 100%
- functional offline
- ₹0
- monthly infrastructure
- 2
- apps from one codebase
Every tradeoff above is documented in a DECISIONS.md written alongside the build — the reasoning, not just the result.
Next case study
One monorepo, 13 apps