Hostel meal billing runs on trust and mental math — and it fails the way every unverified system fails: quietly. Special-day exceptions nobody wrote down, arguments at month-end, and tracking apps that store money as floating point — so the bill itself can be wrong by a paisa, and no one would ever know.
I treated a meal bill the way a security engineer treats a hash — something that must be exact and verifiable by construction. Meal Ledger never touches floats: money lives as integer paisa, meals as integer half-units, and every hostel rule is encoded in a locked, tested rulebook. Isolation isn't a UI promise either — each resident's ledger sits under their own UID, enforced server-side by Firestore Security Rules. Even the ৳52 → ৳55 rate change ships with tests that walk every month boundary — and fail the build if a stale rate is ever hardcoded back.
A zero-dependency PWA in production: offline-capable, installable, real-time synced, with CSV/JSON exports and a rules-guarded admin workspace. 20 automated tests guard the arithmetic, and the entire app weighs ~250 KB — less than one stock photo. The ledger is now mathematically incapable of being wrong.
▶ core · 15 passing ✔ rate schedule preserves ৳52 history → ৳55 from Sep 2026 ✔ every supported month follows the exact rate boundary ✔ calendar handles normal and leap years ✔ breakfast is always one half-unit (0.5 meal) ✔ Friday lunch ×2 · Tuesday dinner ×2 · Sunday dinner ×1.5 ▶ rate-integrity · 5 passing ✔ core rate constants are internally exact ✔ no stale hard-coded ৳52 multiplier in app.js Tests 20 · Failures 0 · Math exact ✓
Money lives as integer paisa, meals as exact half-units, and the whole engine is a dependency-free module that knows nothing about the DOM. That is why 15 of the 20 tests can be plain unit tests on node --test — the arithmetic is verifiable without a browser in the room.
The schedule moved from ৳52 to ৳55, and a test walks every supported month boundary to prove which rate applies. A second, static-analysis test reads app.js and fails the build if a stale ৳52 multiplier ever sneaks back in. Rates are history, not constants.
Firestore security rules scope every ledger to its own UID with an allowlisted field set, so one resident's data is invisible to another — enforced server-side. The admin workspace is a separate, guarded surface rather than a hidden flag.
Versioned app-shell precache, offline-first behaviour, home-screen install and self-hosted fonts. No framework, no build step, no analytics — the entire app is smaller than a single stock photograph.
CSV statements and full JSON backups per month, generated on the device. If a resident ever wants to leave, the data leaves with them — no lock-in and no support ticket required.
Served from GitHub Pages under /meal/; the test suite runs locally before every deploy. Resident data stays inside Firebase, guarded by the published rules.