A full-stack web application for comprehensive school administration. Manages students, staff, academics, finance, communication, library, and transport — built for four user roles across a single integrated platform.
- Overview
- Features
- Tech Stack
- Project Structure
- Getting Started
- Environment Variables
- API Reference
- User Roles
- Modules
- Deployment
- Development Phases
- Team
The School Management System (SMS) is a production-ready web application that consolidates all core school operations into a single platform. It replaces fragmented spreadsheets and manual registers with a unified system accessible to administrators, teachers, students, and parents.
The system was built as a final year project at Medicaps University, Indore, over a ten-month development timeline across five phases.
Live Application: https://sms-client.vercel.app
API Base URL: https://sms-server.onrender.com/api
Authentication and Security
- JWT-based stateless authentication with 7-day token expiry
- BCrypt password hashing (strength factor 10)
- Role-based access control across four user roles
- Protected routes with per-role middleware enforcement
Academic Management
- Drag-and-drop timetable builder with teacher double-booking prevention
- Subject-wise attendance tracking with automatic email alerts to parents
- Exam scheduling with bulk marks entry and absent flag support
- Automated PDF report card generation (percentage, letter grade, GPA, class rank)
Finance Management
- Fee structure definition per class with multiple frequency types
- Payment recording with auto-generated receipt numbers
- Partial payment support with real-time balance tracking
- PDF receipt (A5) and full invoice (A4) generation
- Expense tracking with monthly revenue vs expense reports
Communication
- School-wide and class-specific announcements with priority levels
- Real-time push notifications via Socket.io (room-based)
- Email blast to target audience on announcement creation
- In-app parent-teacher messaging with typing indicators and read receipts
- Event calendar with seven event types and multi-day event support
Add-on Modules
- Library catalog with issue/return tracking and fine calculation
- Transport route, vehicle, and driver management with student allocation
- Analytics dashboard with Recharts visualisations (bar, line, radar, pie)
| Layer | Technology |
|---|---|
| Frontend | React 18, Vite 5, Tailwind CSS |
| State Management | Redux Toolkit, React Query (TanStack) |
| Real-time | Socket.io (client + server) |
| Charts | Recharts |
| Drag and Drop | @dnd-kit/core |
| HTTP Client | Axios |
| Backend | Node.js 18, Express.js |
| Authentication | JSON Web Token, BCrypt |
| Database | PostgreSQL 15 |
| DB Client | pg (node-postgres) |
| PDF Generation | PDFKit |
| Nodemailer (Gmail SMTP) | |
| File Uploads | Multer + Cloudinary |
| Frontend Hosting | Vercel |
| Backend Hosting | Render |
| Database Hosting | Neon (managed PostgreSQL) |
school-management-system/
├── client/ # React frontend
│ ├── src/
│ │ ├── api/ # Axios instance and API call functions
│ │ ├── app/ # Redux store configuration
│ │ ├── components/ # Shared UI components
│ │ │ ├── DashboardLayout.jsx
│ │ │ ├── Navbar.jsx
│ │ │ ├── NotificationBell.jsx
│ │ │ └── Sidebar.jsx
│ │ ├── context/ # Socket.io context provider
│ │ ├── features/ # Redux slices
│ │ │ └── auth/
│ │ ├── hooks/ # Custom hooks (useNotifications)
│ │ ├── pages/
│ │ │ ├── admin/ # Admin-only pages
│ │ │ ├── teacher/ # Teacher-only pages
│ │ │ ├── student/ # Student-only pages
│ │ │ ├── parent/ # Parent-only pages
│ │ │ └── shared/ # Shared pages (messaging, calendar)
│ │ ├── routes/ # ProtectedRoute component
│ │ └── utils/ # Helper functions (PDF download)
│ ├── .env.development
│ ├── .env.production
│ └── vercel.json
│
└── server/ # Node.js backend
├── config/
│ ├── db.js # PostgreSQL connection pool
│ └── cloudinary.js # Cloudinary configuration
├── controllers/ # Route handler functions
│ ├── auth.controller.js
│ ├── student.controller.js
│ ├── attendance.controller.js
│ ├── marks.controller.js
│ ├── feeCollection.controller.js
│ ├── feeStructure.controller.js
│ ├── announcement.controller.js
│ ├── message.controller.js
│ ├── event.controller.js
│ ├── library.controller.js
│ ├── transport.controller.js
│ ├── analytics.controller.js
│ └── financialReport.controller.js
├── middleware/
│ ├── auth.middleware.js # JWT protect + authorizeRoles
│ └── upload.middleware.js # Multer + Cloudinary storage
├── routes/ # Express routers
├── socket/
│ └── index.js # Socket.io server with JWT auth
├── utils/
│ ├── mailer.js # Nodemailer helpers
│ ├── grading.js # Grade/GPA calculation
│ ├── receipt.js # Receipt number generator
│ ├── receiptPDF.js # Receipt and invoice PDF
│ └── reportCard.js # Report card PDF
├── db/
│ └── schema.sql # Full PostgreSQL schema
└── index.js # Express app entry point
- Node.js 18 or higher
- PostgreSQL 15 or higher (or a Neon account for managed cloud PostgreSQL)
- A Cloudinary account (free tier)
- A Gmail account with App Password enabled
Option A — Local PostgreSQL
psql -U postgres
CREATE DATABASE sms_db;
\q
psql -U postgres -d sms_db -f server/db/schema.sqlOption B — Neon (recommended for deployment)
- Create a project at neon.tech
- Copy the connection string from the dashboard
- Open the Neon SQL Editor and paste the contents of
server/db/schema.sql - Run the schema
cd server
npm install
cp .env.example .env
# Fill in all values in .env (see Environment Variables section)
npm run devThe server starts on http://localhost:5000.
Verify the setup:
curl http://localhost:5000/api/health
# Expected: {"status":"OK","message":"SMS API is running"}cd client
npm install
# Create .env.development (see Environment Variables section)
npm run devThe frontend starts on http://localhost:5173.
Default login credentials:
| Role | Password | |
|---|---|---|
| Super Admin | admin@school.com | Admin@123 |
# Server
PORT=5000
NODE_ENV=development
# Database
DATABASE_URL=postgresql://postgres:password@localhost:5432/sms_db
# Authentication
JWT_SECRET=your_minimum_32_character_random_secret_key
JWT_EXPIRES_IN=7d
# Email (Gmail SMTP)
# Generate App Password at: Google Account > Security > 2-Step Verification > App Passwords
EMAIL_USER=yourgmail@gmail.com
EMAIL_PASS=your_16_character_app_password
EMAIL_FROM=SMS School <yourgmail@gmail.com>
# Cloudinary
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret
# Frontend URL (for CORS)
FRONTEND_URL=http://localhost:5173VITE_API_URL=http://localhost:5000/api
VITE_SOCKET_URL=http://localhost:5000VITE_API_URL=https://sms-server.onrender.com/api
VITE_SOCKET_URL=https://sms-server.onrender.comAll endpoints except /api/auth/login require a valid JWT token in the Authorization header:
Authorization: Bearer <token>
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /api/auth/login | None | Login; returns JWT and user object |
| GET | /api/auth/me | JWT | Returns current user profile |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /api/students | Admin, Teacher | List all students |
| POST | /api/students | Admin | Create student and user account |
| PUT | /api/students/:id | Admin | Update student profile |
| DELETE | /api/students/:id | Admin | Delete student |
| POST | /api/students/:id/photo | Admin | Upload photo to Cloudinary |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /api/attendance | Admin, Teacher | Bulk mark attendance for a class |
| GET | /api/attendance/:classId/:subjectId/:date | Admin, Teacher | Attendance sheet for marking |
| GET | /api/attendance/student/:studentId | All | Student attendance history |
| GET | /api/attendance/report/:classId | Admin, Teacher | Class attendance report |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /api/exams | Admin | Schedule an examination |
| PUT | /api/exams/:id | Admin | Update or publish exam results |
| POST | /api/marks | Admin, Teacher | Bulk marks entry |
| GET | /api/marks/report-card/:studentId/:examId | All | Report card data (JSON) |
| GET | /api/marks/report-card/:studentId/:examId/pdf | All | Download report card PDF |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /api/fees/structure | Admin | Create fee structure for a class |
| POST | /api/fees/pay | Admin | Record a fee payment |
| GET | /api/fees/student/:studentId | All | Student dues and payment history |
| GET | /api/fees/receipt/:receiptNo | All | Download receipt PDF |
| GET | /api/fees/invoice/:studentId | All | Download full invoice PDF |
| GET | /api/fees/outstanding | Admin | All students with pending dues |
| GET | /api/fees/report/financial | Admin | Financial summary report |
| GET | /api/fees/report/financial/pdf | Admin | Export financial report PDF |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /api/announcements | All | Role-filtered announcements |
| POST | /api/announcements | Admin, Teacher | Create announcement with email blast |
| GET | /api/messages/conversations | All | Inbox conversation list |
| GET | /api/messages/conversation/:userId | All | Full message thread |
| POST | /api/messages | All | Send a message |
| GET | /api/events | All | Calendar events |
| POST | /api/events | Admin, Teacher | Create calendar event |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /api/library/books | All | Book catalog |
| POST | /api/library/books | Admin | Add a book |
| POST | /api/library/issue | Admin | Issue book to student |
| POST | /api/library/return/:issueId | Admin | Return book with fine calculation |
| GET | /api/library/overdue | Admin | Overdue books list |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /api/transport/routes | All | All transport routes |
| POST | /api/transport/routes | Admin | Create route with stops |
| POST | /api/transport/assign | Admin | Assign student to route |
| GET | /api/transport/student/:studentId | All | Student transport details |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| GET | /api/analytics/dashboard | All | Role-specific dashboard data |
Full access to all modules. Can create and manage all user accounts, configure fee structures, publish exam results, view all financial reports, and access the analytics dashboard.
Can mark and view attendance for assigned classes, enter marks for assigned exams, view their own timetable, post class-specific announcements, and communicate with parents via in-app messaging.
Read-only access to own attendance (with shortage warnings), published exam results with downloadable PDF report card, class timetable, fee status, school notices, and event calendar.
View their child's attendance, marks, fee dues, and timetable. Receive automatic email alerts when their child is marked absent. Communicate with teachers via in-app messaging.
| Module | Status | Key Capabilities |
|---|---|---|
| Student Management | Complete | Enrollment, profile, photo upload, guardian info, search |
| Staff Management | Complete | Teacher profiles, subject assignment, salary |
| Class and Subject Setup | Complete | Class/section CRUD, subject codes, teacher assignment |
| Timetable Builder | Complete | Drag-drop grid, 8 periods, conflict detection |
| Attendance System | Complete | Subject-wise, upsert, email alerts, Socket.io notifications |
| Exams and Marks | Complete | Scheduling, bulk entry, grading, PDF report cards |
| Fee Structure | Complete | Per-class fee types, multiple frequency options |
| Fee Collection | Complete | Payments, partial dues, receipts, invoices, reports |
| Communication | Complete | Announcements, Socket.io, email blast, messaging, calendar |
| Library | Complete | Catalog, issue/return, fine calculation, overdue tracking |
| Transport | Complete | Routes, stops, vehicles, drivers, student allocation |
| Analytics Dashboard | Complete | Role-specific data, four chart types, toppers list |
The application is deployed on free-tier infrastructure.
- Connect the
clientrepository to Vercel - Set Framework Preset to Vite, Output Directory to dist
- Add environment variables:
VITE_API_URL=https://sms-server.onrender.com/apiVITE_SOCKET_URL=https://sms-server.onrender.com
- Deploy
- Create a new Web Service on Render, connected to the
serverrepository - Set Build Command:
npm install, Start Command:npm start - Set Runtime to Node, Region to Singapore
- Add all environment variables from
server/.env(production values) - Enable WebSocket support in Service Settings
- Deploy
- Create a project at neon.tech
- Copy the connection string (includes
?sslmode=require) - Set as
DATABASE_URLin Render environment variables - Run schema SQL in Neon SQL Editor
Both Vercel and Render watch the connected GitHub repositories. Every push to main triggers an automatic redeploy.
Note: Render free tier spins down after 15 minutes of inactivity. The first request after a sleep period takes approximately 30 seconds to respond. This is acceptable for development and demonstration purposes.
| Phase | Timeline | Scope |
|---|---|---|
| Phase 1 — Foundation | Month 1–2 | Project setup, JWT authentication, student and staff CRUD, database schema |
| Phase 2 — Academics | Month 3–4 | Classes, subjects, timetable builder, attendance, exams, marks, PDF report cards |
| Phase 3 — Finance | Month 5–6 | Fee structure, fee collection, PDF receipts and invoices, expense tracking, financial reports |
| Phase 4 — Communication | Month 7–8 | Announcements, Socket.io notifications, in-app messaging, event calendar |
| Phase 5 — Add-ons and Launch | Month 9–10 | Library, transport, analytics dashboard, deployment |
| Percentage | Letter Grade | GPA | Remark |
|---|---|---|---|
| 90 – 100 | A+ | 4.0 | Outstanding |
| 80 – 89 | A | 3.7 | Excellent |
| 70 – 79 | B+ | 3.3 | Very Good |
| 60 – 69 | B | 3.0 | Good |
| 50 – 59 | C | 2.0 | Average |
| 40 – 49 | D | 1.0 | Below Average |
| Below 40 | F | 0.0 | Fail |
A student is marked FAIL if any subject falls below 40% or if any subject is absent.
| Event | Direction | Description |
|---|---|---|
notification |
Server → Client | General notification payload (announcement, absence, fee payment) |
new_message |
Server → Client | New message delivered to recipient's personal room |
user_typing |
Server → Client | Typing indicator sent to conversation partner |
user_stop_typing |
Server → Client | Typing stopped indicator |
join_conversation |
Client → Server | Join a conversation room for typing indicators |
connected |
Server → Client | Confirmation of successful WebSocket connection |
Room naming convention:
user:<id>— Personal notificationsrole:<role>— Role-based broadcasts (e.g.,role:teacher)role:all— School-wide broadcasts