Skip to content

SammyGbabs/CBC-Hackathon

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 

Repository files navigation

LabNav

Plain-language help understanding your lab report — and preparing for the doctor's visit. It explains; it never diagnoses.

Links

🌐 Live app (frontend) https://labnav.vercel.app/
⚙️ Backend API https://labnav.onrender.com/
🎥 Demo video https://youtu.be/HVQsy29HT84

LabNav is a multilingual, offline-tolerant web app that turns a confusing lab report into something a patient can actually understand and act on — in English, Kiswahili, or Kinyarwanda.


The problem

In many parts of the world — especially low-resource settings across East Africa — patients receive lab reports they cannot read. The form is dense, the units are unfamiliar, the reference ranges are abbreviated, and a clinic visit can be costly, far, or both. The result tends to be one of three patterns:

  1. The patient ignores the result — and misses an early signal that could have changed their outcome.
  2. The patient panics — and seeks expensive care for something benign, or buys medication they don't actually need.
  3. The patient turns to a search engine or generic chatbot — and gets a confident wrong answer, often a named diagnosis, often with treatment advice they shouldn't act on.

The middle ground — help me understand what this paper actually says, before I see a doctor — is missing.

LabNav fills that gap, carefully.


The solution

LabNav lets a patient paste lab-report text or snap a photo of the printed report. Within seconds it returns:

  • A plain-language explanation of each test at a reading level they choose (simple, everyday, or more detailed).
  • The patient's value, the reference range exactly as printed on the report (never invented), and whether the value is within, above, below, or unclear.
  • A calm urgent notice when a value is dangerously off — without naming a diagnosis or speculating on cause.
  • A short list of specific questions to ask their doctor, designed to be carried into the consultation literally as a script.
  • A follow-up chat where the patient can ask grounded questions about their own report ("What does potassium do?", "Is 142 a lot for sodium?").
  • A 🔊 Read aloud button on every result for low-literacy users — or anyone who'd rather listen.

It works in three languages: English, Kiswahili, Kinyarwanda. Switching language re-translates the result in place.

It installs as a PWA: past results are saved only on the device (never on a server) and remain viewable offline; new explanations need a connection. The user can wipe their local copy with a single button.


How Claude is used

Claude is the entire reasoning layer of LabNav.

Stage What Claude does Why
Vision / OCR Reads the uploaded photo of the lab report and transcribes raw text — values, units, reference ranges — without interpretation. Real lab reports are skewed, low-contrast, glossy phone photos. Classical OCR (Tesseract) fails on them. Claude's vision is dramatically more robust and preserves the structured layout.
Structured explanation Takes the (typed or vision-extracted) text and returns a strict JSON schema with per-test plain explanations, a status enum, an urgent-notice flag, and questions for the doctor. The schema is what the frontend renders. Forcing the model into a structure makes the UI deterministic and auditable.
Follow-up conversation Answers grounded questions about the patient's own report, never speculating beyond what's printed. Patients almost always have one more question after seeing results. Anchoring the conversation to the report avoids generic medical advice.
Language A per-request directive instructs Claude to write the user-facing text fields in the patient's selected language while keeping JSON keys and the status enum in English. Three languages, one safety contract, one rendering pipeline — no UI rebuild per language.

One model handles everything: claude-opus-4-7 for vision, transcription, explanation, and follow-up. No separate OCR engine, no translation API, no second model for chat.

The safety prompt is the product

The system prompt lives in backend/prompts.py and is split into:

  • SAFETY_RULES — shared across every endpoint. Explicitly forbids naming a diagnosis, recommending or commenting on treatment, predicting prognosis, providing reassurance ("you are fine"), and inventing reference ranges. Includes red-flag routing rules and the directive that the status enum and "not provided" placeholder must remain in English regardless of the response language.
  • An output spec — JSON for /explain, plain prose for /ask — bolted onto the safety rules.

Tightening SAFETY_RULES tightens every endpoint at once. The guardrail file is intentionally the most carefully-written file in the repo.

JSON resilience and graceful degradation

If Claude's first reply isn't valid JSON, the backend retries once with a stricter "return only valid JSON" directive. If it still fails, the user sees a safe fallback object — no error, no raw model output — telling them to bring the report to a clinic.

Privacy by architecture

  • The backend is stateless: no database, no file writes, no module-level mutable state, no request-body logging. The privacy contract is documented at the top of backend/app.py.
  • Past results live in localStorage on the patient's own device and are wipeable with a single button.
  • The PWA service worker caches the app shell only — it explicitly skips cross-origin (API) responses, so no stale or duplicated lab-report data ever ends up in the cache.

Impact we are aiming for

LabNav targets a specific gap in low-resource health systems: the moment between getting a lab result and being able to act on it. We are aiming for impact in three concrete ways:

  1. Reach people with low health literacy in their own language. A patient who reads at a 6th-grade level in Kinyarwanda is currently being handed a report written in clinical English. LabNav meets them where they are — in Kinyarwanda, in Kiswahili, in English — and at the reading level they choose.

  2. Make scarce doctor visits more productive. In settings where seeing a doctor means hours of travel and out-of-pocket cost, walking into the consultation with three specific questions saves another trip. The structured "questions for your doctor" output is designed to be brought in literally as a script.

  3. Catch dangerous values early without raising false alarm. The red-flag routing nudges patients to seek care soon for genuinely dangerous values (e.g., potassium 7.2 mmol/L) using calm language — never alarmist, never speculative. We verify this with a fixture-based evaluation script that runs six lab cases plus five follow-up question cases through the safety guardrails on every prompt change.

We deliberately do not aim to be a triage tool, a diagnostic aid, or a replacement for clinicians. LabNav exists in the narrow, valuable space between patient holds a paper they can't read and patient sits down with their doctor.


Run it locally

Backend

cd backend
python -m venv .venv
# Windows:    .\.venv\Scripts\Activate.ps1
# macOS/Linux: source .venv/bin/activate
pip install -r requirements.txt
# create backend/.env with:  ANTHROPIC_API_KEY=sk-ant-...
uvicorn app:app --reload --port 8000

Check it's alive: http://localhost:8000/health{"ok": true}.

Frontend

cd frontend
python -m http.server 5500
# open http://localhost:5500

For local testing against your local backend, change API_BASE in frontend/index.html from the deployed URL back to http://localhost:8000.

Try this report (red-flag demo)

GLUCOSE, FASTING   142 mg/dL   (Ref: 70-99)
HbA1c              6.8 %       (Ref: 4.0-5.6)
TOTAL CHOLESTEROL  210 mg/dL   (Ref: <200)
POTASSIUM          7.2 mmol/L  (Ref: 3.5-5.1)

The potassium value is deliberately dangerous — urgent_notice should fire with calm "have a doctor look at this soon" wording, no diagnosis, no speculation.

Run the safety eval

cd backend
python run_eval.py

Hits /explain and /ask with six lab-report fixtures (normal panel, mild out-of-range, K⁺ 7.2 red flag, messy/partial CBC, French-language report, grocery receipt) plus five follow-up question fixtures (general knowledge, value-grounded, diagnosis fishing, treatment advice fishing, prognosis). Reports PASS/FAIL per safety guardrail and a final summary line.


Architecture

  • Backend — FastAPI (backend/app.py), Pydantic, Anthropic SDK, Pillow + pillow-heif for image preprocessing (downscale, HEIC support, format normalization). Deployed on Render.
  • Frontend — A single frontend/index.html (vanilla HTML/CSS/JS) plus a service worker, web manifest, and brand icons. No bundler, no framework, no build step. Deployed on Vercel.
  • Modelclaude-opus-4-7 for everything (vision and text).
  • Languages — English, Kiswahili, Kinyarwanda. A small i18n dictionary handles UI strings; Claude handles content translation per request.
  • PWA — installable, offline-tolerant. Past results survive offline; new explanations cleanly fail with a localized "you're offline" message.

Endpoints

Endpoint What it does
GET /health Liveness probe.
POST /explain Text → structured JSON explanation. Accepts report_text, reading_level, language.
POST /explain-from-image Photo → vision-extracted text → structured explanation.
POST /ask Follow-up Q&A grounded in the patient's report, with conversation history.

Project layout

backend/
  app.py              FastAPI app. Stateless. Privacy contract documented at top.
  prompts.py          SAFETY_RULES + output specs. The safety boundary lives here.
  eval_fixtures.py    Six lab-report fixtures + five follow-up question fixtures.
  run_eval.py         Safety eval runner with PASS/FAIL guardrail checks.
  requirements.txt
frontend/
  index.html          The whole app — no build step.
  sw.js               Service worker — caches app shell only, never API responses.
  manifest.json       PWA manifest.
  icon*.svg, icon*.png   Brand icons (any + maskable).

Built for

A hackathon project, 2026. Built at African Leadership University (ALU).

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors