At a Glance
| Metric | Detail |
|---|---|
| Type | Student Enrollment Management System (web application) |
| Industry | Education (K-9, 4 school levels) |
| Codebase | 41,000+ lines of TypeScript |
| Database | 15+ tables with complex relationships |
| Commits | 535+ over active development |
| Pages | 28 frontend views |
| API Endpoints | 50+ REST endpoints across 8 service modules |
| Users | Multi-role (Parents, Staff, Finance, Management) with 8 RBAC roles, 20+ permissions |
| Integrations | WhatsApp (WAHA), Cloudflare R2 (file storage), Amplitude (analytics) |
Business Problem
Abata / LPI Leaders is an Indonesian educational institution running student enrollment across 4 school levels (KB, TK, SD, SMP) each academic year. Before this system, the institution relied on physical visits, spreadsheets, and manual coordination, leading to:
- Physical bottleneck: parents had to visit the school in person to register and submit documents
- Manual payment tracking: staff managed payments in spreadsheets with no verification workflow or audit trail
- Scheduling chaos: observation sessions coordinated via phone calls, with no centralized calendar or automated reminders
- No pipeline visibility: management had no way to see how many registrations converted through each stage, making capacity planning guesswork
The goal was to build a self-service platform that lets parents register online while giving staff and management full control and visibility over the enrollment pipeline.
Business Impact
| Before | After |
|---|---|
| Parents visited the school physically to register and submit paper forms | Self-service portal where parents register, upload documents, and track status from anywhere |
| Payments tracked in spreadsheets with no verification trail | Digital payment evidence upload with one-click admin verification and complete audit history |
| Observation scheduling done via individual phone calls | Centralized scheduling system with automated WhatsApp reminders sent to parents |
| Results announced manually, one family at a time | Batch result publishing with instant WhatsApp notifications to all affected parents |
| No visibility into enrollment conversion or drop-off | Pipeline dashboard showing registration volume, conversion rates, and stage breakdown by school level |
| Invoices and receipts created manually in Word/Excel | Auto-generated invoices with installment tracking, discount calculations, and PDF receipts |
The system is used daily by enrollment staff and accessed by hundreds of parents each registration period, replacing what previously required physical visits, phone calls, and manual spreadsheet coordination.
Solution
An end-to-end enrollment management platform handling the full registration lifecycle:
Registration --> Payment Verification --> Observation Scheduling -->
Result Announcement --> Enrollment Confirmation --> Invoice Management
For Parents (Self-Service Portal)
- Register and manage multiple children from a single account
- Upload payment evidence with real-time status tracking
- Receive WhatsApp notifications at every stage transition
- View observation schedules, results, and enrollment invoices
For Administrators (Back-Office Dashboard)
- Manage 100s of registrations with filtering, search, and bulk operations
- Verify payments with one-click approve/reject workflow
- Schedule observations and publish results with multi-level approval
- Generate PDF documents: biodata forms, acceptance letters, payment receipts, agreements
- Export data to Excel for reporting
For Management
- Dashboard with enrollment pipeline metrics and conversion rates
- Registration volume by academic year, school level, and payment period
- Role-based access control with granular permission management
Development Timeline
Development followed an iterative approach, with features prioritized by the institution’s immediate enrollment needs and shaped by direct feedback from staff using the system.
| Phase | Focus |
|---|---|
| Foundation | Domain modeling with school administration, database schema design, authentication system, parent registration portal |
| Core Workflow | Multi-stage enrollment pipeline (registration through enrollment confirmation), payment verification workflow, admin dashboard |
| Automation & Documents | WhatsApp notification integration, PDF generation for 4 document types, observation scheduling system |
| Billing & Polish | Payment scheme engine with installment plans and discount logic, pipeline analytics dashboard, Excel exports, RBAC refinement across 8 roles |
Technical Architecture
Stack
| Layer | Technology |
|---|---|
| Frontend | React 18, TypeScript, Vite, TailwindCSS, shadcn/ui |
| State | TanStack Query (server state), react-hook-form + Zod (forms/validation) |
| Routing | Wouter (lightweight client-side routing) + Protected Routes |
| Backend | Express.js, TypeScript, Drizzle ORM, Passport.js |
| Database | PostgreSQL (Neon Serverless) with Drizzle ORM & SQL migrations |
| Storage | Cloudflare R2 (S3-compatible) with pre-signed URLs via AWS SDK |
| Messaging | WhatsApp Business via WAHA API with notification queue |
| Documents | pdfmake for server-side PDF generation |
| Analytics | Amplitude event tracking |
The stack was chosen to maximize development speed as a solo developer while keeping the system production-grade. TypeScript end-to-end with shared Zod schemas catches validation drift between frontend forms and API at compile time. TanStack Query eliminates manual server state management, critical for an enrollment system where parents and staff need to see up-to-date payment and scheduling status. Drizzle ORM provides type-safe database access with a lightweight SQL-like API, better suited than Prisma for the complex joins needed across registration, payment, and scheduling tables. Cloudflare R2 offered S3-compatible storage without egress fees, important for an app handling frequent document and payment evidence uploads. WAHA (self-hosted WhatsApp API) eliminated per-message costs, giving full control over delivery for high-volume enrollment notifications.
System Design
Client (React SPA)
|
|-- TanStack Query (server state & caching)
|-- react-hook-form + Zod (validated forms)
|-- Wouter (routing) + Protected Routes
|
v
Express.js API Server
|
|-- Passport.js (session-based auth)
|-- Role-based permission middleware
|-- Zod request validation (shared schemas)
|
+-- PostgreSQL (Neon) ........... Primary data store
+-- Cloudflare R2 (S3) ......... File uploads (payment evidence, documents)
+-- WAHA API ................... WhatsApp notification delivery
+-- pdfmake .................... Server-side PDF generation
Key Technical Decisions
| Decision | Rationale |
|---|---|
| Shared Zod schemas between client and server | Single source of truth for validation - eliminates drift between frontend forms and API validation |
| Drizzle ORM over Prisma | Lightweight, SQL-like API, better performance for complex queries with joins across registration, payment, and scheduling tables |
| Session-based auth over JWT | Simpler revocation, no token refresh complexity, appropriate for server-rendered app where parents stay logged in during registration |
| Cloudflare R2 over S3 | Zero egress fees, S3-compatible API - ideal for file-heavy enrollment documents and payment evidence |
| WAHA for WhatsApp | Self-hosted WhatsApp API - no per-message costs, full control over delivery for high-volume enrollment notifications |
| Server-side PDF generation | Consistent output across devices, supports complex layouts for official Indonesian school documents (acceptance letters, agreements) |
Engineering Highlights
1. Multi-Stage Enrollment Pipeline
Designed and implemented a state machine for registration stages (registered -> obs_scheduled -> obs_attended -> passed -> enrolled) with automatic stage transitions, audit trail via registration_stages table, and WhatsApp notifications triggered at each transition. The pipeline handles edge cases like re-scheduling, stage rollback, and multi-child registrations under a single parent account.
2. Role-Based Access Control System
Built a flexible RBAC system with 8 roles, 20+ granular permissions, and user-level permission overrides. Permission checks are enforced both server-side (Express middleware) and client-side (React hooks) using the same permission definitions.
// Server: middleware-based protection
app.get("/api/admin/registrations", requirePermission("registrations.view"), handler);
// Client: hook-based UI control
const { hasPermission } = usePermissions();
{hasPermission("payments.verify") && <VerifyButton />}
3. Payment Scheme & Invoice Engine
Built a complete billing system supporting multiple payment periods with different pricing (Early Bird, Gelombang 1-3), discount calculations (loyalty, event, full payment, group), installment plans (up to 4 installments) with auto-generated invoices, and payment evidence upload with admin verification workflow.
4. Automated WhatsApp Notifications
A key feature of the system: real-time WhatsApp notifications that bridge communication between school and parents throughout the entire admission process. Instead of parents calling the school for updates or staff manually messaging each family, the system automatically sends contextual WhatsApp messages at every critical stage - registration confirmation, payment verification, observation reminders, result announcements, and enrollment confirmation. This transforms what was previously a slow, one-by-one communication process into instant, reliable delivery. Built on WAHA (self-hosted WhatsApp API) with a notification queue, retry logic, and rate limiting to handle bulk sends during peak periods like result announcements.
5. PDF Document Generation
Server-side generation of 4 official document types using pdfmake: student biodata forms, acceptance letters (SK Kelulusan), payment receipts (Bukti Pembayaran), and enrollment agreements (Surat Perjanjian). Each template supports dynamic data binding with proper Indonesian formatting.
Key Challenges Solved
| Challenge | Solution |
|---|---|
| Parents can’t visit school during working hours to register | Self-service portal with full online registration, document upload, and status tracking |
| Staff manually verifying payments across spreadsheets | Digital payment evidence upload with one-click verify/reject workflow and audit trail |
| Scheduling observations for hundreds of students across 4 school levels | Centralized scheduling system with capacity management and automated WhatsApp reminders |
| No way to track which registrations stall or drop off | Pipeline dashboard with stage-by-stage conversion metrics, filterable by school level and period |
| Complex pricing with multiple discount types and installment plans | Configurable payment scheme engine supporting Early Bird pricing, loyalty/group/event discounts, and auto-generated installment invoices |
| Official documents (acceptance letters, receipts) created manually | Server-side PDF generation with 4 document templates, consistent formatting across all devices |
| Staff with different responsibilities need different access levels | 8-role RBAC system with 20+ granular permissions enforced on both server and client |
Engineering Practices
- Type Safety: End-to-end TypeScript with shared Zod schemas for runtime validation
- Database Migrations: SQL migration system with up/down support, status tracking, and rollback capability
- Error Handling: Centralized error handling with user-friendly messages (Indonesian localization)
- Security: bcrypt password hashing, session management, CSRF protection, rate limiting, input sanitization
- File Upload: Pre-signed URL pattern for direct-to-R2 uploads via Uppy, avoiding server memory pressure
- Database Resilience: Connection retry logic for Neon’s serverless cold starts
What This Project Demonstrates
- Solo full-stack delivery: single-handedly designed, built, and shipped a 41K-line enrollment system with 28 views, 50+ API endpoints, and 15+ database tables
- Complex workflow modeling: translated a multi-stage enrollment process (registration, payment, observation, result, confirmation) into a state machine with automatic transitions, audit trails, and edge case handling
- Multi-persona product design: built three distinct interfaces (parent portal, admin dashboard, management analytics) serving users with fundamentally different needs and technical literacy
- Production-grade integrations: WhatsApp notification system with queue, retry, and rate limiting; cloud storage with pre-signed URLs; server-side PDF generation for official Indonesian school documents
- Domain-driven billing logic: payment scheme engine handling multiple pricing periods, 4 discount types, installment plans, and invoice generation - a non-trivial business rules layer
Screenshots
Preview
Preview
Preview
Preview
Links
| Resource | Detail |
|---|---|
| Source Code | Private repository, available for code review on request |
| Live System | pmb.abata.sch.id |