❯ AI · Health · 2025
Med-Clarity
A pan-African web app that turns photographed medical paperwork into plain-language, drug-grounded, multilingual explanations — explicitly non-diagnostic.
The problem
A patient leaves a hospital with a discharge sheet written in dense medical English and no one to translate it. In a pan-African context the problem compounds: dozens of languages, many of them low-resource, and very few people between the patient and the paper. The design constraint is that this tool is explanatory, not diagnostic, and that line has to hold in every language and every output.
The approach
The capture-to-explanation pipeline is service-oriented: document processing, drug grounding, a guardrail, explanation, translation and audio, account, and reporting, seven independent FastAPI services behind a single GCP API Gateway. OCR is self-hosted Tesseract; structured extraction runs through an LLM with per-field confidence, and low-confidence fields are disclosed to the user with a correction flow. The explanation itself is grounded in drug reference data (RxNorm, openFDA, the WHO Essential Medicines List); when a drug has no match or only a partial one, the tool says so instead of guessing.
Architecture
- Web App (Next.js)
- GCP API Gateway
- Document Processing (Tesseract)
- Drug Grounding
- Gemini + Claude Guardrail
- Translation + TTS
FLOWS
- Web App (Next.js)capture paperGCP API Gateway
- GCP API Gatewayimage + textDocument Processing (Tesseract)
- Document Processing (Tesseract)extracted fieldsGemini + Claude Guardrail
- Gemini + Claude Guardraildrug lookupDrug Grounding
- Drug Groundinggrounded factsGemini + Claude Guardrail
- Gemini + Claude Guardrailexplain + translateTranslation + TTS
- Translation + TTStext + audioWeb App (Next.js)
The LLM setup is deliberately two-tier. Google Gemini handles routine
generation where cost matters; Anthropic Claude runs guardrail-critical
post-checks that enforce the non-diagnostic scope boundary, so the cheaper
model never gets the last word. Multilingual and audio output split the same
way: Google Cloud Translation and Cloud TTS cover high-resource languages, and
self-hosted OmniVoice TTS covers 600+ languages, including low-resource African
ones. Infrastructure is Terraform on Cloud Run and GKE with per-environment
state, GitHub Actions CI/CD, Docker Compose for local development, and Neon
serverless PostgreSQL with five schemas including a jsonb event log. Auth is
Firebase phone OTP with a guest-first core flow and role-based pharmacy staff
access. Monetization is a free core, a Paystack B2B2C tier for institutions,
and API licensing.
Key decisions
Claude only where it matters
Gemini for volume, Claude for the guardrail. Cost stayed sane and the safety-critical path got the stronger model.
Grounded drug data with disclosed gaps
A no-match answer is shown as a gap, never filled in by the model.
Per-field confidence to the user
The correction flow exists because extraction errors are not rare, and hiding them is worse.
Guest-first auth
The first explanation should take under a minute; accounts come later.
What I'd do differently
Seven services was the right shape but too many for the first release; account and reporting could have waited. I would also publish the non-diagnostic contract as a versioned document the guardrail checks against, instead of encoding it only in prompts, so a scope change is a data change rather than a prompt rewrite.