PuskesmasAI: Finishing an Offline AI Triage App for Rural Indonesia A developer has completed PuskesmasAI, an offline-first Progressive Web App that uses AI-powered medical triage to assist community health workers in rural Indonesia. The app runs entirely on-device with no internet connection required after initial setup, using a quantized Gemma 4 E4B model to analyze patient symptoms and return structured triage results (GREEN/YELLOW/ORANGE/RED) with recommended actions and referral notes. The project addresses Indonesia's severe doctor shortage—1 doctor per 5,000 people versus the WHO's recommended 1:600—by equipping non-medical volunteers in remote 3T regions with AI decision support that stores all patient data locally and syncs only when connectivity returns. This is a submission for the GitHub Finish-Up-A-Thon Challenge PuskesmasAI is an offline-first Progressive Web App PWA that brings AI-powered medical triage to community health workers kader in rural Indonesia — no internet connection required after the first setup. Indonesia has 1 doctor per 5,000 people, far below the WHO's recommended 1:600 ratio. In remote 3T regions Tertinggal, Terdepan, Terluar — Underdeveloped, Frontier, and Outermost , over 45% of community health posts lack adequate medical staff. The kader — non-medical volunteers who are often the only frontline health resource for millions — must make triage decisions without doctors nearby, without structured guidance, and frequently without internet. PuskesmasAI solves this. A kader inputs patient symptoms via a simple form in Bahasa Indonesia, and the app returns a structured AI triage result: GREEN / YELLOW / ORANGE / RED — with recommended actions, possible conditions, red flags, and an auto-generated referral note. Patient records are stored locally in IndexedDB and sync to the Puskesmas dashboard when connectivity returns. Built with Next.js 14 PWA + Tailwind CSS on the frontend, Python Flask on the backend, and Gemma 4 E4B GGUF quantized via Ollama as the on-device AI model ~2.5GB, zero cloud dependency . Zero patient data ever leaves the community — privacy by design. This project means a lot to me personally. I'm based in Makassar, South Sulawesi — and the health disparity between urban and rural Indonesia is something I witness firsthand. PuskesmasAI is my attempt to put AI where it's needed most. 🔗 Repository: https://github.com/jefribulomakassar/gemma4 good hackathon https://github.com/jefribulomakassar/gemma4 good hackathon ⚠️ Local-first by design.PuskesmasAI runs entirely on-device — the Next.js frontend port 3000 and Python Flask backend port 5000 are started separately on a local machine, with Gemma 4 E4B served via Ollama. There is no hosted demo because the whole point is offline operation: no cloud, no data leaving the device. To run locally: Terminal 1 — Backend cd backend && pip install -r requirements.txt ollama run gemma4:e4b python app.py runs on :5000 Terminal 2 — Frontend cd frontend && npm install npm run dev runs on :3000 Demo scenario: Phone in airplane mode → open PuskesmasAI → fill triage: 32-year-old female, symptoms: "fever for 3 days, red spots on skin, nausea" → tap Analyze → result: 🟠 ORANGE with action list and referral note → turn WiFi on → patient record auto-syncs to dashboard. This project originally started as my submission for the Kaggle × Google DeepMind Gemma 4 Good Hackathon Health & Sciences track, deadline: May 18, 2026 . I had the full concept, the README, the architecture diagram, and the backend security layers ready — but I ran out of time before finishing the core data files and frontend components that would make the app actually work . Before what existed at the original deadline : TriageResult.tsx , OfflineBanner.tsx , VoiceInput.tsx components medical kb.json — the AI had no medical knowledge base symptom map.json — no symptom-to-condition mapping drug reference.json — no drug dosage reference for kaders SymptomForm.tsx — the main input form was missing db.ts / sync.ts — offline storage and sync not implemented After what was added during the Finish-Up-A-Thon : backend/data/medical kb.json — offline medical knowledge base covering the 10 most prevalent diseases in rural Indonesia Dengue/DBD, Typhoid, Malaria, ARI/ISPA, Diarrhea, Hypertension, Tuberculosis, Malnutrition, Cholera, Pre-eclampsia with symptoms, red flags, triage levels, and actions — all in Bahasa Indonesia backend/data/symptom map.json — 32 symptom groups with Indonesian colloquial keywords, probability weights, and automatic triage escalation rules backend/data/drug reference.json — 10 essential Puskesmas drugs with pediatric dosing per kg body weight, contraindications, and kader-safe drug classification based on Indonesia's National Formulary frontend/src/components/SymptomForm.tsx — mobile-first patient intake form with symptom shortcut buttons, automatic pregnancy detection, temperature indicator, and form validation frontend/src/lib/db.ts — IndexedDB wrapper using Dexie.js for offline patient record storage frontend/src/lib/sync.ts — auto-sync module that uploads pending records to Turso cloud when connectivity returnsThe transformation: from a well-documented skeleton to a genuinely functional offline AI triage tool. GitHub Copilot was central to finishing this project — especially for the data-heavy and boilerplate-heavy files that would have taken hours to write manually. symptom map.json and drug reference.json were generated entirely using GitHub Copilot in the github.dev editor — no local setup needed. I simply pressed . on the repository page to open github.dev, then used Ctrl+I to invoke inline prompts. I provided the full file path, the data structure requirements, and domain-specific context Indonesian rural health context, Formularium Nasional constraints . The results were accurate, well-structured, and included details I hadn't explicitly specified — like colloquial Bahasa Indonesia symptom terms "step" for kejang/seizure, "ngos-ngosan" for rapid breathing and the appropriate kader-safe drug classification tiers. db.ts and sync.ts were scaffolded by Copilot with idiomatic TypeScript and Dexie.js patterns that matched the existing codebase — including the synced boolean field for tracking upload status and the navigator.onLine check in the sync logic. What would have been an hour of boilerplate became a focused 10-minute review and refinement session. What I learned: Copilot works best when you give it full context — the exact file path in the repo, the purpose of the file, the related files it should be aware of, and the domain-specific constraints. A well-crafted prompt saved me hours on each file. "The best AI is not the most complex one. It's the one that works for the people who need it most — even when the internet doesn't."