Scholync is a production-ready university management system — built to run a real institution. It handles everything from student onboarding and OTP verification, to live course streams, assignment submission, attendance tracking, a full gradebook, and a superadmin control panel — all wrapped in a beautiful dark-glass UI with light mode support.
Features · Tech Stack · Architecture · Project Structure· Getting Started
- Email + OTP two-step signup (email sent via Vercel serverless function)
- JWT-based auth with token blacklisting on logout (TTL-indexed MongoDB collection)
- Forgot password with OTP reset flow (3 step: request → verify → reset)
- Route guards for authenticated and unauthenticated users
- Each university has a unique slug — all data is scoped to it
- Admins register their institution on first signup
- Students and professors join by university ID
- Pending approval workflow — admins approve/reject members
| Role | Capabilities |
|---|---|
| Admin | Manage users, create/delete courses, assign professors, view stats |
| Professor | Run courses, post announcements & materials, create assignments, grade submissions, take attendance |
| Student | Enroll in courses, submit assignments, view grades & feedback, track attendance |
Four-tab layout per course:
- Stream — Announcements & material feed with compose, file attachments, edit/delete
- Classwork — Assignments grouped by topic, due-date badges (overdue / due soon)
- People — Professors and enrolled students
- Grades — Sticky-column gradebook spreadsheet with per-assignment scores
- Assignment files (PDF, DOCX, etc.) uploaded directly to Cloudinary
- Profile photos with face-aware smart crop (
gravity: face) - Secure signed URLs, no direct client-to-server file transfers
- Professors mark present / late / absent per student per session
- Students see their attendance ring (% with color: green / amber / red)
- Full session history with expandable per-session records
- Professor-side stats table with per-student attendance percentages
- Separate login with its own JWT secret — completely isolated from main auth
- Create universities with slug, domain, and address
- Manage all users across all universities (search, filter by role/status, approve/reject/delete)
- Platform-wide stats: total universities, users, courses
- Glass-morphism dark theme (
#0a0a0fbase, Electric Blue + Amber accent) - Full light mode toggle (
#eef2ffbase) — persisted on the user's device - Collapsible sidebar, responsive breakpoints down to 480px
- Skeleton shimmer loading states throughout
| Layer | Choice |
|---|---|
| Framework | Angular 19 (NgModules, standalone: false) |
| UI Library | Angular Material MDC |
| Styling | Custom CSS — glass morphism + CSS variables |
| Typography | Poppins (Google Fonts) |
| Forms | Angular Reactive Forms |
| HTTP | Angular HttpClient + JWT interceptor |
| Routing | Lazy-loaded feature modules with auth guards |
| OTP delivery | Vercel Serverless Function (bypasses Render SMTP block) |
| Layer | Choice |
|---|---|
| Runtime | Node.js (CommonJS) |
| Framework | Express 5 |
| Database | MongoDB Atlas (Mongoose 8) |
| Auth | jsonwebtoken + bcryptjs + TokenBlacklist model |
| Security | Helmet, express-rate-limit, mongo-sanitize, custom escapeRegex() |
| File Storage | Cloudinary (multer → cloudinary stream) |
| Nodemailer via Gmail SMTP (on Vercel) | |
| Deployment | Render (free tier, auto-sleep) |
┌─────────────────────────────────────────────────────────────┐
│ CLIENTS │
│ Browser (Angular SPA) Vercel Serverless (OTP emails) │
└────────────────┬──────────────────────┬─────────────────────┘
│ HTTPS │ SMTP (Gmail)
┌────────────────▼──────────────────────▼─────────────────────┐
│ EXPRESS 5 API (Render) │
│ │
│ /api/auth /api/admin /api/courses │
│ /api/assignments /api/attendance /api/university │
│ /api/superadmin /api/upload │
│ │
│ Middleware stack: │
│ helmet → rate-limit → cors → mongo-sanitize → requireRole()│
└────────────────┬───────────────────────┬────────────────────┘
│ Mongoose 8 │ Cloudinary SDK
┌────────────────▼────────┐ ┌──────────▼───────────────────┐
│ MongoDB Atlas │ │ Cloudinary │
│ (multi-tenant) │ │ (profile pics, files) │
│ │ │ │
│ Users Courses │ │ face-crop avatars │
│ Posts Assignments │ │ assignment attachments │
│ Submissions Attendance│ │ │
│ TokenBlacklist (TTL) │ └──────────────────────────────┘
└─────────────────────────┘
scholync-showcase/
├── backend/ Express API
│ ├── config/ Cloudinary + Mailer setup
│ ├── controllers/ Route handlers
│ ├── middleware/ JWT auth, RBAC, file upload
│ ├── models/ Mongoose schemas
│ ├── routes/ API route definitions
│ └── utils/ Security helpers
└── frontend/ Angular 19 SPA
├── api/ Vercel serverless function (OTP email)
└── src/app/
├── guards/ Route guards
├── interceptors/ HTTP auth interceptor
├── models/ TypeScript interfaces
└── services/ API service layer
Copy backend/.env.example and fill in your values:
MONGO_URI=
JWT_SECRET=
CLOUDINARY_CLOUD_NAME=
CLOUDINARY_API_KEY=
CLOUDINARY_API_SECRET=
ALLOWED_ORIGINS=
NODE_ENV=production
The frontend reads src/environments/environment.prod.ts for the API URL.
Backend
cd backend
npm install
cp .env.example .env # fill in your values
npm start # nodemon server.js on :3000Frontend
cd frontend
npm install
ng serve # Angular dev server on :4200This project is for educational and portfolio purposes.
Built with ❤️ by Raman