I co-built Ulat with Team ByteSized for the App Builders PH Hackathon 2026 theme: Local AI . I built the family side: the phone app families use to report damage, and the reports API behind it.
Documentation block 1
I co-built Ulat with Team ByteSized for the App Builders PH Hackathon 2026 (theme: Local AI). I built the family side: the phone app families use to report damage, and the reports API behind it.
Project overview
Ulat is an offline damage reporting kit for Philippine LGUs. It runs on one laptop and one Wi-Fi router, with nothing plugged into the internet port. The laptop runs the web app, the database and a local AI model, Gemma 4 through Ollama. Families, responders and MDRRMO staff join the Wi-Fi and use Ulat in their phone’s browser, with no app to install.
The problem
After a disaster, every LGU has to count who got hit and what they need, usually within 72 hours. That is the same window when power and signal are down. Photos can’t upload, cloud tools can’t load, and the data maps injured people and vulnerable families, so it shouldn’t leave the town anyway. The system had to keep working with no internet, and it had to stay accurate when anyone can submit a report.
How it works
- A family reports from their own phone with a short form and a photo, then checks status with a four-character code.
- The laptop reads each family photo with the local model. It returns a damage class, the visible hazards and a one-line reason.
- Code turns that reading, plus who is hurt or missing, into an urgency. Responders get a to-visit list sorted by urgency or distance, an offline map, and a form to confirm the damage on site.
- MDRRMO staff watch the totals update live and print the situation report.
- Help desk staff can record a voice note in Bisaya, Tagalog, Taglish or English for families without a phone, and the model turns it into the report form.
Trust and privacy checks
One rule holds it together: families report, responders verify, and only verified entries count. Family reports set the order of visits. They never change the totals. The model reads one photo or one note at a time. It never counts, ranks or adds anything up, because code computes every total. Every model output is checked against a strict schema. If one fails, the photo becomes “unclear” and staff can run it again. Names, injuries and home locations sit behind a PIN or responder sign-in.
What I built
- The family report flow: household details, neighbor reports, home location on an offline map, and a photo shrunk on the phone before it sends.
- The status check by report code, plus the family home, updates, map and “I’m safe” screens.
- An offline queue: if a phone drops off the Wi-Fi, the report waits on the phone and sends once it’s back in range.
- The reports API, including the photo upload route and its storage limits.
- The responder email and password sign-in.
Tools and implementation
- Next.js, TypeScript and Tailwind
- SQLite with Drizzle, Zod for every boundary
- Ollama running Gemma 4 on the laptop
- MapLibre with a local PMTiles map
- Service worker and IndexedDB for the phone queue
- Caddy for HTTPS, so phone cameras and GPS work with no internet
- Server-sent events for live updates
Related credentials
Published credentials connected to this project.