01Problem
On rice-field development contracts, supervisors need daily progress they can trust, weekly reports that are complete for the period, and supervision letters whose progress figures can be traced back to evidence. Reports that arrive late, or cannot be checked against what was actually recorded on site, make all three hard.
02What I built
One web app for desk and field. Site engineers record daily progress against the bill of quantities with photo evidence; the platform rolls it into S-curves, daily and weekly reports and approvals; admins handle contract change orders and push announcements to specific roles and packages.


03How it works
- Layered API. Routes → controllers → 46 domain engines (progress, reporting, approval, S-curve, cost estimate …) → repositories → PostgreSQL. Import direction is checked mechanically.
- Append-only records. Progress, photos, daily reports and approvals are never edited in place, so the history behind a number stays intact.
- Access control on the server. Three gates — authenticated role, project membership, per-action check — for six roles; the interface only mirrors it.
- Honest reports. Weekly reports are DRAFT or FINAL depending on period completeness, and official PDFs carry a DRAFT stamp until published.
- Installable web app (PWA). A service worker keeps field pages available and an offline queue holds progress, photos and daily reports until the signal returns. Retried submissions carry an idempotency key, so nothing is counted twice.
04Results and scale
- In daily use since June 2026 for supervising 7 rice-field development packages in Banyuasin, South Sumatra.
- In the 30 days to mid-September about 70% of progress entries were filed from phones — Android and iPhone — so the separate Android app was shelved in favour of a single installable web app.
- Progress figures for supervision letters are recomputed from daily database backups with the platform's S-curve logic; the recomputation reproduces the plan figures of a previously issued letter to two decimal places.
- More than 940 commits and 560 merged pull requests since April 2026, merged through CI with a post-deploy smoke test and daily database backups; about 125,000 lines of application code across 46 domain engines, 27 controllers and 29 repositories.
- The same codebase runs a second, separate instance for another agricultural programme.
05Try it
The S-curve rule the platform applies, run on a fictitious package: item weights from the bill of quantities, planned progress spread over each item's schedule, actual progress capped at 100% per item, and a status that turns critical when the gap crosses the contract threshold.
S-curve: planned vs actual
Fictitious 18-week canal package. Move the reporting week; the status follows the contract rule (critical when more than 10 points behind while planned ≤ 70%, or more than 5 points behind after that).
Swipe sideways to see the whole chart.
Method: item weight = item amount ÷ contract subtotal; planned = weight spread evenly over the item's scheduled weeks; actual = Σ weight × min(installed ÷ contract quantity, 100%). Package, quantities, dates and actions are fictitious.
06Stack
- Node.js (Express)
- Next.js 16 / React 19
- TypeScript
- PostgreSQL
- Redis
- Cloudflare R2
- Railway
- Vercel
- Sentry
- GitHub Actions
- PWA
07Gallery
Only public pages are shown. Screens inside the live system, and its public progress portal, hold client project data.