Engineering notes
Under the hood.
This demo is the production codebase — same build, different database. Next.js 16 (App Router, React 19, TypeScript), Tailwind v4, Supabase (Postgres, Auth, Storage), Vercel. ~6,000 lines of TypeScript, 20 SQL migrations, zero UI libraries.
Security model
Every table runs Postgres row-level security with ENABLE + FORCE — the API key alone grants nothing. Sign-up is allow-listed by a database trigger; privileged mutations live in SECURITY DEFINER RPCs that derive org and actor from auth.uid(), never from parameters. The audit log is append-only (no update/delete policies exist), and a 12-check adversarial harness runs against the live database to prove the policies — cross-tenant reads, forged writes, audit tampering, privilege escalation — all denied.
Correctness under money
Voucher numbers are legally significant: they may never gap or duplicate. Numbering happens inside a transactional RPC that row-locks a counter table; deleting is restricted to the newest voucher of its kind ("tear the last page out of the book"), rolls the counter back in the same transaction, and snapshots the full record into the audit log first. Anything older can only be voided — with a reason, a visible stamp on the PDF, and the number retired forever.
The monthly send is idempotent by construction: a claim row guarded by a unique index means two directors tapping "send" at once produce exactly one email, and a crashed send is taken over safely after a stale window. Late entries after a month closes go out as a labelled supplementary pack — the original pack is never rewritten.
Documents pipeline
Vouchers render from typed HTML templates to A4 PDFs via headless Chromium (@sparticuz/chromium on Vercel), with both directors' signature images composited in. Month end builds an Excel ledger (exceljs), attaches every voucher PDF and receipt photo fail-closed — if any attachment can't be fetched, the send aborts rather than deliver an incomplete pack — and archives a ZIP to Google Drive over OAuth with AEAD-encrypted refresh tokens.
Bilingual by type system
The UI is English/Sinhala per device. The Sinhala dictionary is typed si: typeof en, so a missing translation is a build failure, not a runtime fallback. Strings resolve server-side and cross to client components as finished props; documents that leave the company are always English by a hard import rule.
Operations
Error boundaries detect stale-PWA deploys (chunk/server-action skew) and self-heal with a guarded reload. All business dates compute in Asia/Colombo regardless of server region. This demo itself is a production feature: a nightly cron reseeds three months of fictional data through the app's own entry RPC and send action, so what you click through is exactly what real use produces.
Source
The repository is private — it documents a real client. Read access is available to interviewers on request: yenura@themysu.com.
Built by mysu · Yenura Kulatunge