Skip to content
dirihoPublic

About

African health site build during the Yale African Innovation Symposium YAIS. Centralised digital health records platform for African healthcare providers.

Topics

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

 
 

Latest commit

 

History

205 Commits

Folders and files

Repository files navigation

MedCore — Centralised digital health records for African healthcare

CI Deploy Demo Node TypeScript License PWA FHIR Yale AIS

MedCore is a centralised digital health records platform for African healthcare providers — a Vite + React PWAfront-end with aNode + Express + SQLite (libSQL) API. It implements the PRD's eight features end-to-end with FHIR-shaped resources, RBAC-gated access, and an AI assist layer that summarises patient context and surfaces risk flags. Every external integration (Daily.co, OpenAI Whisper, Africa's Talking, OpenFDA, Web Push) ships with a working mock so the demo runs offline.

🏆 Recognition

Winner — Yale Africa Innovation Symposium IV (April 16–18, 2026), built within the Technology & AI Innovation Lab track under the symposium's "The Pulse of Progress" theme.

MedCore team presenting at YAIS IV judging — April 18, 2026 Technology & AI Innovation Lab participants at YAIS IV
Final presentation, Yale, April 18, 2026 Technology & AI Innovation Lab participants, YAIS IV

Quick start

git clone https://github.com/Builder106/med-core.git
cd MedCore
npm install
npm --prefix server install
npm run dev

The Vite dev server proxies /api/*to the Express server on port 3001 and binds to0.0.0.0, so a phone on the same Wi-Fi can open http://<laptop-ip>:5173.

Sign-in (demo)

Role User ID Default PIN
Doctor DOC-001 4242
Patient PAT-001 1212
Admin ADM-001 3434

PINs are configurable in server/.env(seeserver/.env.example). For production, set SESSION_SECRET to a long random string (≥32 characters). If a login fails after editing PINs, restart the API to resync demo PINs — dev does this on every start.

How it works

Doctor opening a patient chart through the PWA, API, and SQLite

AI summary request

Doctor requesting an AI summary with patient context and risk flags

Prescription interaction check

Prescription interaction check through the PWA, API, and OpenFDA

Critical prescription override and accepted prescription save

The doctor opens a chart through a session-guarded API call; SQLite returns patient, medication, lab, and encounter data. An optional summary request sends patient context to the AI layer and returns a summary with risk flags. For a prescription, OpenFDA returns a critical, warning, or no-interaction result. A critical result without acknowledgement returns 409 and asks for a PIN; an acknowledged or noncritical request is written with an audit record and returns 201, then the chart updates. Edit the chart, summary, interaction check, or outcome diagram.

All external integrations fall back to mocks when API keys are absent, so the canonical journey above works offline.

Demo recordings

Core workflow — doctor signs in, opens a patient chart, AI panel auto-loads (≈25s)

Doctor signs in and opens a patient chart

Recorded against the live deploy at https://api.yinkavaughan.me via the e2e/demo/features/01-core.feature Gherkin scenario.

How to regenerate / add more

The Gherkin suite at e2e/demo/features/ drives Playwright with slowmo + a custom video reporter that converts webm → mp4 → gif. Add a 0N-<name>.feature and:

npx playwright install chromium    # one-time
E2E_BASE_URL=https://api.yinkavaughan.me DEMO=1 npm run e2e:demo  # records mp4
npm run e2e:demo:gif               # mp4 -> gif (10 fps, 960px wide)
cp e2e/demo-videos/<slug>.gif assets/<name>.gif

The full mechanics — cursor injection, dwell helpers, the 0-byte first-test workaround — are documented in docs/E2E.md.

Demo on your phone

See docs/DEMO.md for the full phone walkthrough (PWA install, voice, video, push reminders, SMS, Health ID QR, offline/low-bandwidth).

Media APIs (camera, microphone, push) require a secure context:

# Option 1 — tunnel (recommended for dev)

cloudflared tunnel --url http://localhost:5173    # brew install cloudflared

# or

ngrok http 5173

# Option 2 — light cloud deploy (Fly.io / Railway / Render)

docker build -t medcore .

For the Africa's Talking SMS callback, point the inbound webhook at https://<your-public-url>/api/sms/inboundand sendPATIENT PAT-001 PIN:4242from the phone number set asDEMO_DOCTOR_PHONEinserver/.env.

Tests

npm test                    # web (Vitest)
npm --prefix server test    # API + SMS + interaction + FHIR + integrations
npm --prefix server run typecheck
npm run test:all            # web + server

CI runs all of the above on every PR — see .github/workflows/ci.yml.

Docs

File Contents
docs/PRD.md Full product requirements document
docs/DEMO.md Phone walkthrough for all 8 features
docs/ENV_SETUP.md Guide to filling out server/.env
docs/go-to-market.md GTM strategy and pilot roadmap
docs/GUIDELINES.md Development conventions
docs/ATTRIBUTIONS.md Third-party licenses and credits
CONTRIBUTING.md Dev setup, project guardrails, PR convention

Environment variables

Copy server/.env.exampletoserver/.env and fill in only the integrations you need:

Variable Purpose Fallback when empty
OPENROUTER_API_KEY AI summaries and risk flags Returns a deterministic mock summary
GROQ_API_KEY/OPENAI_API_KEY Whisper transcription (F2) Returns realistic mock transcripts
DAILY_API_KEY/DAILY_DOMAIN Video rooms (F3) Falls back to a public Jitsi room
AT_API_KEY SMS send (F4 & F5) Logs to a mock outbox
WEB_PUSH_PUBLIC_KEY/WEB_PUSH_PRIVATE_KEY Push reminders (F5) In-memory fake send
DATABASE_ENCRYPTION_KEY AES-256-GCM PII column encryption Disabled (plaintext) — set before real PII
DEMO_DOCTOR_PHONE/DEMO_PATIENT_PHONE Route SMS / reminders to your real number —

Generate VAPID keys: npx web-push generate-vapid-keys. Generate an encryption key: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))".

PRD features implemented

  1. Multilingual (i18next, 5 languages + RTL Arabic) — src/locales/
  2. Voice recording + AI transcription — src/app/components/clinical/VoiceConsultPanel.tsx and server/src/routes/voice.ts
  3. Video consulting (Daily.co + Jitsi fallback) — src/app/pages/VideoConsultPage.tsx and server/src/routes/video.ts
  4. SMS offline system — server/src/routes/sms.ts + doctor inbox at src/app/pages/SmsInboxPage.tsx
  5. Medication reminders + adherence — server/src/routes/reminders.ts + doctor/patient UIs
  6. Drug interaction checker — server/src/routes/interactions.ts + server/src/routes/prescriptions.ts with PIN override
  7. EHR domain — appointments, labs, vaccinations, referrals, encounters, inventory, staff, consent, audit — server/src/routes/*
  8. AI assist + FHIR export — server/src/routes/ai.ts, server/src/routes/fhir.ts, server/src/lib/fhir-mappers.ts

Postgres (production option)

docker compose up -d postgres

# then set DATABASE_URL in server/.env to a Postgres URL

The SQLite schema in server/src/db/migrations.sql is portable; switching dialects only requires updating the Drizzle client.

Contributing

PRs welcome. See CONTRIBUTING.md for dev setup, project guardrails (PHI safety, offline-first, mock-friendly integrations, RBAC), commit convention, and the out-of-scope list. CI must stay green.

License

MedCore is released under the MIT License. © 2026 Yinka Vaughan.

Third-party licenses and asset attributions are tracked in docs/ATTRIBUTIONS.md.

About

African health site build during the Yale African Innovation Symposium YAIS. Centralised digital health records platform for African healthcare providers.

Topics

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages