Relational schema design, indexing strategies and query optimisation
Advanced features — JSONB, full-text search, row-level security
Netlify FunctionsNetlify
01
Overview
CampusEnroll is a secure admissions and enrollment system for schools, from the first application to a student number.
02
The problem
Schools juggle paper forms, document photos in chat and cashier receipts in separate books. Parents never know where an application stands, and student data is too sensitive for a loose spreadsheet.
03
What I built
Online application with document upload and status tracking
Registrar review, assessment of fees and down payment
Sign-in with two-step verification and a tamper-evident audit log
Hand-off of enrolled students to CampusCard for ID printing
Built-in guide with journey diagrams, and a privacy and security page for parents
04
Architecture
A React and TypeScript front end validates every form with Zod before it leaves the browser. Serverless functions check the role on every request and talk to a PostgreSQL database. Enrolled students are handed to CampusCard for their ID.
Architecture · CampusEnroll - School Enrollment System
A high-level view. Endpoints, hosts and security details are left out on purpose.
05
Key decisions
01
Validate once, share the rules
Why: The same Zod schemas check forms in the browser and on the server, so bad data is stopped early and never trusted.
Trade-off: Schema changes have to be released to both sides together.
02
Tamper-evident audit log
Why: Every sensitive change is chained in the log, so an edit to history would show.
Trade-off: Records are corrected with new entries, never edited in place.
03
Serverless instead of a server to babysit
Why: A school has no IT team to patch a server; functions scale and stay patched by the platform.
Trade-off: Cold starts can add a moment to the first request.
04
Enrollment and IDs are separate systems
Why: CampusEnroll hands students to CampusCard, so each system does one job well.
Trade-off: The hand-off format has to stay in sync between the two.