← Coursework

FLM Haiti Capstone: an EMR That Works Offline

An offline first medical record for a rural clinic in Haiti: a small server inside the clinic holds the record on its own network, one tablet app covers the clinic's day, and an assessment of open source EMRs charts the long term.

Course
Capstone Project
School
Carnegie Mellon University
Term
Fall 2025
Role
Software Engineer
Stack
  • Flutter
  • Dart
  • Supabase
  • PostgreSQL
  • Docker
  • Raspberry Pi
  • Android
  • Material Design
Code
Links
FLM Haiti EMRHouse of DavidEN · FR · HT
DashboardEnglish
House of David · Welcome Back!Developed by CMU Heinz College Capstone Team
PatientsManage patient recordsAppointmentsSchedule & manageForm TemplatesManage questionnairesPrescriptionsCreate & manage prescriptionsPharmacyInventory & stockReports (In progress)Analytics & insights
Recent ActivityToday's Appointments8Pending Reviews3New Patients This Week5
The clinic's app laid out landscape, as on a tablet, drawn from its code: the dashboard that opens every module, a dental visit with its tooth map, and billing. As in the app, the Encounters and Billing cards open their screens and the back arrow returns to the dashboard. Patients appear by number, and the visit and the invoices are samples.

Problem

FLM Haiti is a nonprofit that has worked in Haiti for over 40 years, and its House of David clinic, founded in 2009, is the primary long term care provider for four rural communities, serving a population of over 30,000. The clinic keeps every record on paper, with very few staff registering patients, booking visits, counting stock and billing by hand, while power and internet fail often. Records are slow to find when a decision is waiting and easy to lose to misplacement, damage or local incidents. The clinic needed one record system that replaces the paper and keeps working under any of those conditions, without counting on the internet being there.

Solution

The record lives in the clinic, not in the cloud: a Raspberry Pi runs the whole backend in containers (the database, its API and sign in) and broadcasts its own Wi-Fi, so the clinic's tablets, phones and laptops share one record with no internet at all. One Flutter app covers the clinic's day from a single dashboard: patients, appointments, visits recorded by department with visual tools such as a tooth map, intake forms, billing, prescriptions and the pharmacy, in English, French and Haitian Creole, each module following what established EMRs already do. The internet is kept for what can wait: encrypted off site backups, planned for whenever a connection exists, and the digitisation of old paper records, prototyped with one OCR model per form type. For this testing phase the app ran against a hosted copy of the same backend, and in parallel the team assessed six open source EMRs to decide what the clinic should run for the long term.

On the Raspberry Pi 5On the deviceEMR apptablet, phone and laptop7 modules, reports in progressEnglish, French, Haitian CreoleFlutter · Dart · one codebaseLocal copy, change queueworks away from the serversyncs, resolves conflictsplannedworking copy, synced laterjoins the clinic networktesting phase: same app, hostedIn the clinicWhen onlineClinic Wi-Fithe server's own access pointdevices join with no internetRaspberry Pi 5 · its own hotspotSign in and row rulesemail sign in and tokensrow rules in the databaseSupabase Auth · RLSHosted test backendthe same backend, hostedwhat the app used this phaseSupabase cloudrequests on the local networkchecks token and row rulesData APIevery read and writeover the local networkSupabase REST · 10.42.0.1:8000reads and writes every recordClinic recordone database for every devicethe system of recordPostgreSQL · Supabase in DockerEncrypted off site backupcompressed, AES-256 encryptedsent only when onlineplanned · about $2.30 a month per 100 GBencrypted copy when onlinedaily dumpextracted records, loading plannedDaily local backupa dump each day to USB or NAS7 to 14 days keptplanned · pg_dump, cronPaper record digitisationone OCR model per form type15 to 100 samples a formprototype · Azure OCR, needs internet
The record lives on a small server inside the clinic, so no device waits for the internet; what needs a connection, backups and digitising paper, waits until one exists. Dashed parts are planned.

Decisions and learnings

  • Architecture decision

    Offline first, all the way down

    The clinic loses power and internet often, so no part of the record could depend on a connection. A Raspberry Pi in the clinic runs Supabase in Docker and broadcasts its own Wi-Fi, so every device reads and writes one shared record over the local network and the internet becomes optional, needed only for off site backups. The whole kit costs under $120 and about $1 a month in power, against $25 to $200 a month for hosting.

  • Architecture decision

    A proof of concept, on purpose

    This phase built a minimum viable product the clinic can test, not a finished system: one Flutter app over Supabase, chosen because it runs on every device the clinic has and because the same backend runs hosted or on the clinic's own server. For the trial the team recommended the hosted copy, faster to iterate on and free of early hardware risk, with the local server and its hardening as the next step. The team said plainly that the MVP carries shortcuts and is not yet compliant or production ready.

  • Architecture decision

    Standards over invention

    The clinical modules follow what established EMRs do rather than invent new workflows: registration with a duplicate check, visits recorded by department, versioned intake forms, appointments with a status workflow, invoices, and prescriptions dispensed from stock lots tracked by expiry. The data model is patient centred and, in the team's words, FHIR inspired, without claiming full interoperability. Effort went where the clinic is unusual: its power, its connectivity and its languages.

  • Learning

    From Supabase first to AI enabled development

    Earlier phases built the app in a low code builder over Supabase; this phase moved it to plain Flutter code written with LLM assistance, which is what made a multi module MVP possible in fourteen weeks. It also produced debt: no automated tests, configuration written into the code, and multi step writes that are not one transaction. Speed from LLMs has to be paid back on purpose, which is why the report asks the next phase to assess, refactor and harden that code first.

  • Learning

    Recommend open source for the long term

    The team assessed six open source EMRs (OpenEMR, OpenMRS, Bahmni, GNU Health, Open Hospital and Medplum) on clinical coverage, community, mobile and offline support. OpenMRS extended through Bahmni came out strongest, yet none works fully offline across every workflow and the usability test with staff was still to do, so the advice was to adopt and adapt an open source EMR in phases rather than migrate at once. An open source record is maintained by a global community and outlives any one team of developers, which a custom system handed from one student team to the next cannot promise; the MVP is the bridge, and the evidence for that choice.

  • Learning

    The hard problems were technical, not clinical

    The clinical workflows were already known; what decides whether the record survives is infrastructure: one small server that is a single point of failure, power that needs a battery or solar buffer for a clean shutdown, backups kept on site and off, sync without conflicts, and access rules the database enforces. The report's first lesson says the same, so the next phases need software, architecture and infrastructure skills alongside UX more than new clinical features.

← Back to coursework