Skip to content

School management ERP with permissions enforced per branch

Students, fees, payments, payroll and accounting across multiple branches, with role and branch permissions enforced in the database and fee reminders sent over WhatsApp.

An independent school groupClient engagement2026
Fees and invoices across all branches: collected, pending, and each invoice's status with a WhatsApp reminder action
The product itself, running with demonstration data.
branch isolation
Multi
enforced permissions
RLS
fee reminders
WhatsApp

The problem

Multiple branches, each needing to see its own students, fees and staff (and head office needing to see all of them), with the same application serving both without leaking data between sites.

Fee collection depended on someone remembering to chase, and the records of who had been chased lived in a notebook.

What we built

01

Scope by role and by branch, in the database

Row-level security policies carry both dimensions, so a branch administrator's queries return their branch's rows and nothing else, regardless of which screen asked. The interface reflects the same rules, but the database is what enforces them.

02

One ledger from enrolment to accounts

Students, fee invoices, payments, expenses, employees and payslips feed a single accounting layer, so a fee receipt and a salary payment land in the same books and the reports reconcile without a spreadsheet in between.

03

Reminders where parents actually read them

Fee reminders go out over WhatsApp from templates, turning collection into a scheduled action rather than a remembered one.

04

Closing the obvious doors

Public signup disabled, account creation moved behind a privileged server-side function holding the only elevated credential, and receipts in their own storage bucket.

05

Built with Claude Code, under review

The system was built and extended with Claude Code. Its commit history carries a Claude co-author trailer on 136 of 242 commits, and changes arrive as pull requests that must pass lint, tests and a build in CI before they merge. The agent drafts quickly; the review and the test suite decide what ships.

06

Reviewed by seven read-only agents

One project command runs seven review agents in parallel: security, database, accounting, code quality, deployment and dependencies, UX and compliance, and a features reviewer. They only read the code. Their reports are merged into one summary, the highest-severity findings are spot-checked against the source, and what survives is ranked into waves of work.

07

Rules written as ordered migrations

Permissions and money rules live in ordered, idempotent, transaction-wrapped migrations: role and branch policies, an audit trail written by database triggers rather than the browser, money functions that post an invoice, payment and ledger entry together, ledger guards and a private receipts bucket. Each carries a pre-flight checklist and rollback notes.

Payroll: a month of payslips with allowances, deductions and net pay
Payroll: a month of payslips with allowances, deductions and net pay

The outcome

  • Branch data isolation that a mistake in the interface cannot undo, because the policy is evaluated in Postgres.

  • Real-time multi-session sync, so two staff working the same list see each other's changes.

  • Fee chasing became a process with a record rather than an act of memory.

  • Forty-two test files, including date and payroll logic checked under two time zones, and a CI workflow that lints, tests, builds and audits dependencies on every pull request.

Built with

  • React
  • Supabase
  • PostgreSQL
  • Row-level security
  • Edge Functions
  • WhatsApp API
  • Vercel
  • Claude Code

Page copy drafted with AI assistance. Skofi is accountable for it. Editorial policy

Start here

Have something shaped like this?

If any part of the above resembles a problem you are living with, a short call is the fastest way to find out whether it is the same problem underneath.

Book a 15-minute callsaveez@skofi.tech

What happens on the call

  • 15 minutes, no deck
  • We map the process on the call
  • A written scope, or an honest no
Book a call