Vishal.dev
Back
Full-Stack

RGD School Management System

Production school management platform with multi-role access, fee handling, attendance tracking, result generation, and reporting — a true business domain system.

Next.jsTypeScriptNode.jsPostgreSQLPrismaRedisDocker
4
User roles
12
Core modules
<80ms
Page load time
100%
Uptime

Domain Knowledge

What problem this project solves

School management is deceptively complex. Most people think it's CRUD until they encounter problems like: a student transfers sections mid-year but their attendance history must remain correct, fees have installments/discounts/late fees/scholarships, and exam results require ranked grade calculations across multiple subjects. RGD handles all of these with proper domain modeling and workflow engines.

Architecture

How the system is structured

The system uses a modular architecture with clear domain boundaries: Student Management, Academic Tracking, Fee Management, Examination, and Reporting. Each module has its own service layer and data access patterns. Authentication uses JWT with role-based middleware that enforces permissions at both the API and data level. Background workers (BullMQ) handle report generation, fee reminders, and bulk operations without blocking the request thread.

Data Model

Schema design and data flow

The domain model centers around the Student entity, which connects to Attendance, Fee, Exam, and Class entities. A Student transfers between sections over time, so attendance and fee records are linked to the admission period rather than the current section. The fee model supports installments, discounts (sibling, merit), late fees, and scholarship adjustments. The exam model supports multiple subjects, grade boundaries, rank calculation, and report card generation.

Key Challenges

Hardest problems encountered

Fee management was the most complex module. Real schools don't just charge a flat fee — they have installment plans, early-bird discounts, sibling discounts, late payment penalties, scholarship adjustments, and refund processing. The fee engine had to handle all these cases while maintaining an auditable payment trail. Attendance tracking faced its own challenge: a student might be marked present in one class but absent in another on the same day, requiring period-level attendance rather than day-level.

Scaling Strategy

How the system grows

The system serves a single school with horizontal scaling for peak periods (exam result days, fee due dates). PostgreSQL handles the relational data, Redis caches frequently accessed data (student lists, fee structures, class schedules). Background jobs prevent slow operations (report generation, bulk SMS/email) from blocking HTTP requests.

Security

Defense-in-depth approach

Four role levels (Admin, Teacher, Student, Parent) with granular permissions. Teachers can only access their assigned classes. Students see only their own data. Parents see their children's data. All API endpoints enforce role-based access at the middleware level, with row-level security in PostgreSQL as a backup.

Failure Handling

Resilience and recovery

Fee payments use idempotency keys to prevent double-charging. Report generation retries on failure. Attendance saving is transactional — if saving 40 students' attendance fails, the entire batch rolls back. Notifications queue with retry for SMS/email failures.

Observability

Monitoring and debugging

Dashboard tracks: fee collection rates, attendance trends, class performance comparisons, and exam result distributions. Structured logging helps debug issues in production. Audit logs track who modified student records, fee waivers, and grade changes.

Trade-offs

Engineering decisions and alternatives

Single-database PostgreSQL was chosen over microservices because the school's scale doesn't warrant distributed complexity. Prisma ORM provides type safety and migration management at the cost of some query flexibility. Background jobs over cron for reliability and observability.

Architecture Decisions

Key choices and what was rejected

Decision
Chosen
Rejected
Architecture
Modular monolith with domain boundaries
Microservices (premature complexity)
Fee engine
Custom fee module with installment/discount support
Fixed-fee model (too inflexible)
Attendance
Period-level attendance tracking
Day-level (loses granularity)
Background jobs
BullMQ queue
Cron jobs (no retry/observability)

Senior-Level Topics

Concepts this project explores

Domain-Driven DesignState MachinesAudit LoggingRole-Based Access ControlBulk OperationsReport Generation