Skip to content
Β 
Β 

Latest commit

Β 

History

127 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

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

sequenceDiagram
  actor Doctor
  participant PWA as PWA<br/>(Vite + React)
  participant API as Express API
  participant DB as SQLite<br/>(libSQL)
  participant Ext as External APIs<br/>(OpenFDA Β· Daily Β· AT Β· Whisper)
  participant AI as AI Layer<br/>(OpenRouter Β· Groq)

  Doctor->>PWA: Open patient chart
  PWA->>API: GET /api/patients/:id<br/>(session cookie)
  API->>API: requireApiSession + audit
  API->>DB: SELECT patient, meds, labs, encounters
  DB-->>API: rows
  API-->>PWA: 200 JSON
  PWA-->>Doctor: Render chart

  Doctor->>PWA: Request AI summary
  PWA->>API: POST /api/ai/summarize
  API->>AI: Prompt with patient context
  AI-->>API: Summary + risk flags
  API-->>PWA: 200 JSON
  PWA-->>Doctor: Show AI panel

  Doctor->>PWA: Prescribe new drug
  PWA->>API: POST /api/prescriptions
  API->>Ext: OpenFDA interaction check
  Ext-->>API: critical / warning / none
  alt critical, no ack
    API-->>PWA: 409 critical_interaction
    PWA-->>Doctor: Modal: override w/ PIN?
    Doctor->>PWA: Acknowledge + PIN
    PWA->>API: POST /api/prescriptions (ack)
    API->>DB: INSERT prescription + audit
    API-->>PWA: 201 created
  else safe
    API->>DB: INSERT prescription + audit
    API-->>PWA: 201 created
  end
  PWA-->>Doctor: Updated chart
Loading

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://136-117-181-143.nip.io 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://136-117-181-143.nip.io 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

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages