2026 · case study
Student Management System
A role-based platform where an institute runs admissions, courses and people from one place.

01 Overview
Angular SPA plus an Express/MongoDB API. JWT auth and route guards drive separate admin, teacher and student dashboards over shared course and user data.
02 The problem
Small institutes juggle student records, course lists and staff access across spreadsheets and disconnected tools. Everyone sees everything, or no one can find anything.
03 What I built
One application with three faces. A single Angular SPA authenticates against an Express API, decodes the JWT, and routes each person to the dashboard their role is allowed to see — admin, teacher or student — over one shared data layer.
04 Key features
JWT login with token decoding and protected routes Route guards that gate whole dashboard trees by role Admin view: manage users and courses Teacher and student views scoped to their own data Course and user services with typed models Chart.js analytics on the dashboard Email flows on the backend via Nodemailer Password hashing with bcrypt
05 Technologies
- Angular
- TypeScript
- Routing & guards
- Reactive forms
- RxJS
- REST API integration
- Auth & JWT
- Role-based access
- Charts & data viz
- Node.js
- Express
- MongoDB / Mongoose
06 Engineering decisions
Access control at the router
Rather than hiding buttons, permission is enforced where navigation happens. A guard reads the decoded token and blocks the route before the component ever loads, so the three dashboards stay genuinely separate.
Thin services, typed contracts
api.service centralises the HttpClient calls; auth, course and user services layer intent on top. Every response maps to an interface, so a shape change surfaces at compile time, not in production.
- api.service.ts — transport
- auth.service.ts — session
- course.service.ts / user.service.ts — domain
One backend, real auth
The Express 5 API uses Mongoose models for users and courses, bcrypt for password storage, JSON Web Tokens for sessions and Nodemailer for account email — a full auth surface rather than a mock.
07 What I took from it
- Designing a permission model before writing screens saves a rewrite later.
- Guards are the honest place to enforce access; template *ngIf is only cosmetics.
- Owning both sides of the API makes the contract easier to keep clean.