Case Study · Consumer Health

ClinCalc

Consumer health self-check & multimodal interpretation platform

Role: Solo developer
Timeline: 2025–2026
Status: Live, open source
Monthly cost: $0 (free tier)
45Lab indicators
17Body regions
44Symptom categories
G1–G5KDIGO 2024 staging
ClinCalc home
ClinCalc home — three entry points to interpretation: lab values, image scan, body map.

Pain points

Many people get a lab report full of numbers and jargon and don't know which values are concerning and which can wait. The default behaviors are: Google it, ask family, or ignore. Two structural problems sit underneath:

  1. Information asymmetry — medical terminology is hostile to non-experts
  2. Privacy concerns — pasting lab values into ChatGPT isn't safe

System architecture

"Rules-first, then LLM" three-layer architecture: local interpretation → structured injection → LLM translation. Raw patient data never leaves the device.

  1. 1 · User input

    Enter 45 lab indicators, upload a lab-report photo, or click symptoms on the body map.

  2. 2 · In-browser local rules engine

    Queries the referenceRanges.ts knowledge base; each indicator is interpreted in real time as "normal / mildly high / mildly low / severely high / severely low". Raw values never leave the browser.

  3. 3 · Cloudflare Worker (edge)

    Receives the structured interpretation (not raw values), composes the Gemini prompt. Free tier 100K req/day is enough for expected traffic.

  4. 4 · Google Gemini 1.5 Flash

    Translates medical terms, OCRs images. The LLM sees "CKD G3a" — not "Mr. Chiang's eGFR=45".

  5. 5 · Supabase (PostgreSQL + Auth)

    User accounts, medication reminders, health record history — all protected by RLS.

Design highlight 1 — Rules first, then LLM

ClinCalc integrates Gemini using a "query the knowledge base first, then hand off to the LLM" pattern: after the user fills in 45 indicators, the frontend looks up referenceRanges.ts per field and calls checkAbnormal() for a 5-level verdict, then composes the structured interpretation as the prompt to Gemini. Gemini doesn't need to memorize each indicator's normal range — that reduces hallucination.

KDIGO staging card
KDIGO 2024 staging card. CKD-EPI 2021 formula + dual-axis (GFR + albuminuria) staging — all computed locally in the browser.

Trade-off

  • Limited rule coverage: fuzzy holistic judgments ("how does my report look overall?") aren't handled by the rules engine, and the LLM is constrained from free generation → users feel "it doesn't do much"
  • Knowledge base is manually maintained: upgrading from KDIGO 2012 to 2024 meant hand-editing the reference table

Design highlight 2 — Where multimodal models actually help

Gemini 1.5 Flash's multimodal capability is restricted to two well-defined "translation" tasks — never clinical decisions:

Medical image OCR
Photo a lab report → image recognition extracts indicator names, values, units.
Bilingual medical translation
Bidirectional zh/en translation of medical terms; technical terms underlined and bolded.

Trade-off

OCR accuracy on handwritten reports is still low (< 70%); translation occasionally misfires on uncommon abbreviations. The frontend validates citations from the model output and shows a "physician confirmation needed" tag on anomalies.

Design highlight 3 — Interactive symptom exploration

Conventional symptom search is keyword-typing. ClinCalc switches to a visual map: click a body region → expand common symptoms in that region → Gemini provides preliminary differential ranking and red-flag prompts.

Interactive body map
17-region body map, 44 symptom categories. Lowers the barrier to query for users without medical background.

Derived feature: personal health tracking

After interpretation, the system stores results in Supabase (RLS-protected), forming a personal time series. Users can track 9-month trends per indicator, set medication reminders, and issue one-time tokens for a physician's temporary access.

Health record main view
Health record main view; trend-analysis chips toggle which indicators are charted.
HbA1c 9-month trend
Time-series modal — e.g., HbA1c over 9 months.

Security & privacy design

Four layers of protection, browser → backend:

  1. Local-first computation

    All 45-indicator interpretation logic and KDIGO staging compute entirely in the browser; raw lab values never leave the device. Only structured interpretations go to the backend.

  2. LLM only sees structured data

    Gemini prompts contain only de-identified strings like "CKD G3a", never raw patient numbers. Reduces both hallucination risk and privacy risk.

  3. Storage-layer RLS isolation

    User accounts, medication reminders, and health-record history live in Supabase, with PostgreSQL RLS on every table ensuring users can only read/write their own rows. Cross-account data won't leak even if the application layer is breached.

  4. Edge secret isolation + standard web security

    Gemini API key and Supabase service-role key live only in Cloudflare Worker runtime secrets — never exposed to the frontend bundle. Combined with HTTPS only, Secret Scanning, Push Protection, and Dependabot for supply-chain defense.

Evaluation

The rules engine (KDIGO staging) was tested end-to-end: KDIGO 2024 international guideline cases as ground truth, compared against system output via confusion matrix and ROC curve.

KDIGO staging confusion matrix and ROC curve
Confusion matrix and ROC curve for the rules engine on KDIGO staging.

Note: this evaluation covers only the rules engine (not LLM output). Safety on the LLM side comes from structured injection + citation validation as preventive control; no public accuracy claim is made.

Tech stack

Next.js 16React 19TypeScriptTailwind v4 SupabasePostgreSQL RLSCloudflare WorkersGoogle Gemini 1.5 Flash GitHub ActionsWranglerOpenNext

Research questions surfaced

  1. Can the "rules-first, then LLM" strategy generalize to fuzzy domains? The strategy works well on KDIGO staging, but rule coverage is insufficient for "holistic judgment" tasks. How do you design a graded "rules ↔ LLM" intervention ratio?
  2. How do clinical guideline updates propagate into a CDSS? KDIGO updates every few years; manually updating rule bases isn't sustainable. Could RAG turn clinical guidelines into a dynamic knowledge base?
  3. Limits of multimodal systems in non-expert user contexts — for users without medical training, how much algorithmic error is tolerable? How do you design disclosure and fallbacks?

Further reading