Project archive
SOBAT HEBAT
بِسْمِ اللَّهِ الرَّحْمَٰنِ الرَّحِيمِ
SOBAT HEBAT
Puskesmas Pangkalbalam reached out because they had a growing problem. TB patients need six to twelve months of consistent medication, and missing doses leads to drug resistance — which means longer treatment, higher costs, and risk of transmission. Their entire workflow ran on paper: patient folders, manual attendance logs, phone calls for follow-up. It worked when the patient count was small. As numbers grew, patients started slipping through.
My job was to replace that paper trail with something digital. Nothing more, nothing less. The constraint was real: the system had to work for two very different groups of people. Patients who just need to know whether they took their medication today and when their next visit is. Puskesmas staff who need to scan across dozens of patients and spot who needs attention. I decided on a single platform with role-based dashboards — same database, different views. Building two separate apps would have meant more maintenance, more surface area for bugs, and no real benefit since the data was shared anyway.
Something I noticed during the first few weeks of working with the Puskesmas: many patients had limited health literacy. A date on a screen meant less to them than a color or an icon. I adjusted the patient dashboard to lean on visual status indicators — green for taken, red for missed, gray for upcoming. It was a small change, but the staff told me patients started engaging with the app more after that. I did not run an A/B test or collect metrics on it. I just observed the shift and adjusted.
The data model ended up being more involved than I expected. A simple attendance record is not very useful on its own — “patient visited Tuesday” does not tell you whether they took their morning dose, their evening dose, or both. TB regimens have multiple medications per day. I modeled attendance as linked to specific medication slots, not just calendar dates. That way the system can flag “attended but missed evening dose” separately from “missed the entire day.” Staff told me this distinction mattered for follow-up decisions, and that was the validation.
On the frontend I used Next.js with TypeScript. Patient-facing pages are server-rendered because many patients access the site from budget Android phones on slow connections — the faster the first paint, the more likely they are to use it. The admin dashboard fetches from the client because staff need updates in near real-time as they process patients. The backend is NestJS, organized into separate modules per domain: patients, attendance, medications, lab results. I drew those boundaries early, which paid off later when I needed to refactor the attendance logic without touching anything else.
One decision I spent time on: offline support. I chose not to build it. The Puskesmas provides WiFi on-site, patients mostly interact during visits, and keeping data consistent across the dashboard was higher priority than working without a connection. It was the right call for this project, but I would approach it differently for a system deployed across multiple Puskesmas with varying infrastructure.