{"slug": "puskesmasai-finishing-an-offline-ai-triage-app-for-rural-indonesia", "title": "PuskesmasAI: Finishing an Offline AI Triage App for Rural Indonesia", "summary": "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.", "body_md": "*This is a submission for the GitHub Finish-Up-A-Thon Challenge*\n\n**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.\n\nIndonesia 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.\n\nPuskesmasAI 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.\n\nBuilt 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.\n\nThis 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.\n\n🔗 **Repository:** [https://github.com/jefribulomakassar/gemma4_good_hackathon](https://github.com/jefribulomakassar/gemma4_good_hackathon)\n\n⚠️\n\nLocal-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.\n\n**To run locally:**\n\n```\n# Terminal 1 — Backend\ncd backend && pip install -r requirements.txt\nollama run gemma4:e4b\npython app.py  # runs on :5000\n\n# Terminal 2 — Frontend\ncd frontend && npm install\nnpm run dev  # runs on :3000\n```\n\n**Demo scenario:**\n\nPhone 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.\n\nThis 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*.\n\n**Before (what existed at the original deadline):**\n\n`TriageResult.tsx`\n\n, `OfflineBanner.tsx`\n\n, `VoiceInput.tsx`\n\ncomponents`medical_kb.json`\n\n— the AI had no medical knowledge base`symptom_map.json`\n\n— no symptom-to-condition mapping`drug_reference.json`\n\n— no drug dosage reference for kaders`SymptomForm.tsx`\n\n— the main input form was missing`db.ts`\n\n/ `sync.ts`\n\n— offline storage and sync not implemented**After (what was added during the Finish-Up-A-Thon):**\n\n`backend/data/medical_kb.json`\n\n— 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`\n\n— 32 symptom groups with Indonesian colloquial keywords, probability weights, and automatic triage escalation rules`backend/data/drug_reference.json`\n\n— 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`\n\n— mobile-first patient intake form with symptom shortcut buttons, automatic pregnancy detection, temperature indicator, and form validation`frontend/src/lib/db.ts`\n\n— IndexedDB wrapper using Dexie.js for offline patient record storage`frontend/src/lib/sync.ts`\n\n— 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.\n\nGitHub Copilot was central to finishing this project — especially for the data-heavy and boilerplate-heavy files that would have taken hours to write manually.\n\n** 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\n\n`.`\n\non the repository page to open github.dev, then used `Ctrl+I`\n\nto 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\"`\n\nfor kejang/seizure, `\"ngos-ngosan\"`\n\nfor 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\n\n`synced`\n\nboolean field for tracking upload status and the `navigator.onLine`\n\ncheck 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.\n\n\"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.\"", "url": "https://wpnews.pro/news/puskesmasai-finishing-an-offline-ai-triage-app-for-rural-indonesia", "canonical_source": "https://dev.to/jefri_bulo/puskesmasai-finishing-an-offline-ai-triage-app-for-rural-indonesia-52da", "published_at": "2026-06-12 02:23:35+00:00", "updated_at": "2026-06-12 02:42:30.297352+00:00", "lang": "en", "topics": ["artificial-intelligence", "machine-learning", "large-language-models", "ai-products", "ai-ethics"], "entities": ["PuskesmasAI", "Gemma 4 E4B", "Ollama", "Next.js", "Tailwind CSS", "Flask", "WHO", "Makassar"], "alternates": {"html": "https://wpnews.pro/news/puskesmasai-finishing-an-offline-ai-triage-app-for-rural-indonesia", "markdown": "https://wpnews.pro/news/puskesmasai-finishing-an-offline-ai-triage-app-for-rural-indonesia.md", "text": "https://wpnews.pro/news/puskesmasai-finishing-an-offline-ai-triage-app-for-rural-indonesia.txt", "jsonld": "https://wpnews.pro/news/puskesmasai-finishing-an-offline-ai-triage-app-for-rural-indonesia.jsonld"}}