What problem did it solve?
A tuition centre ran classes, fees and parent updates through WhatsApp groups and spreadsheets, so every term meant manual enrolment and chasing payments.
What was built?
- Four roles, one product: students, parents, teachers and admins each get their own view of live classes, assessments, timetable and billing.
- Logins that match real families: phone and password sign-in with scoped identities, so a parent and child can share one number without sharing an account.
- Migration as a feature: 841 students, 734 parents, 25 teachers, 304 classes and about 1,536 enrolments moved in from the legacy system.
How is it engineered?
Measured from the source repository, not estimated. As of Oct 2026.
Architecture
React 19 single-page PWA built with Vite and deployed on Vercel, with Vercel serverless functions for payments, PDFs, e-invoicing, AI and notifications, over Supabase Postgres, Auth and Realtime.
Data and isolation
Postgres with 269 migrations, 346 row-level security policies over 123 RLS-enabled tables, four-role access (student, parent, teacher, admin), money stored as integer sen, and a double-entry general ledger with journal entries and lines in integer cents.
Security and privacy
- Payment webhook rejects any request whose signature does not verify against the gateway public key over the raw body
- Every scheduled endpoint requires a cron secret; user-facing API routes require a verified bearer token
- A guard script fails any migration that leaves an API-reachable table without row-level security, added after a real incident
- E-invoice client secret read only server-side with the service role, never sent to the browser
Regulatory rules in code
Submits monthly consolidated e-invoices to LHDN MyInvois (UBL 2.1, submit and status), stores SSM and SST registration fields, and scopes profile columns so contact details are not exposed to peers under PDPA.
Quality evidence
| Billing self-check | 33 assertions, all passing | Regression check on shared money and invoice-status logic |
|---|---|---|
| Ledger integrity checks | 32 named invariants | Named invariants in the ledger integrity gate (run against the live database) |
| Cross-user sync test | 6 end-to-end flows incl. RLS isolation | Harness signs in as different roles and checks what each can see (run against the live database) |
| Commits | 436 (9 Jun to 18 Sep 2026) | Git history of the main branch |
Operations
Vercel deploys with five scheduled jobs (daily charging of due invoices, reminders, email and push queues, trial expiry), a post-build guard that makes staging builds non-indexable, and an activity log table for staff actions.
What was my role?
Designer, architect and full-stack builder, including the migration of real data from the legacy system.
What else shaped the build?
- Payments in Malaysian rails. A parent shop and fee payments built on CHIP.
- Respect for families. A hard rule that the platform never messages families without an explicit request.
Where does it stand now?
StudyBuddy has been live at www.studybuddy.my since 24 September 2026 as an installable PWA, with more than 1,600 real accounts migrated. CHIP payments are built and awaiting sandbox verification.


