A production-grade, full-stack Learning Management System built with Next.js, Express, TypeScript, PostgreSQL, and Redis. It supports complete course delivery — video lessons, quizzes with auto-grading, assignments, live classes, attendance, certificates, payments, discussions, and role-based dashboards for Admins, Teachers, and Students.
Built as a portfolio project to demonstrate real-world backend architecture (JWT auth with per-device sessions, RBAC, background jobs, file storage, payment integration) paired with a modern, fully functional Next.js frontend.
- Overview
- Features
- Tech Stack
- Architecture
- Folder Structure
- Getting Started
- Demo Accounts
- API Overview
- Testing
- Roadmap
- Contributing
- License
This LMS is designed to closely mirror what a real learning platform (like Udemy or a corporate training portal) needs under the hood: enrollment and progress tracking, auto-graded and manually-graded assessments, live class scheduling with attendance, auto-issued PDF certificates, Stripe-based payments with coupon support, per-course discussion threads, and a full admin control panel — all backed by a properly modeled PostgreSQL schema with 20+ related tables.
The goal was to build something recruiter-ready and technically honest: real authentication (not a toy), real background job processing, real file storage, and a codebase organized the way a mid-size Node.js team would organize it (feature-based vertical slices, not a giant controllers/ dumping ground).
- Browsable course catalog with search, filtering, and pagination
- Course detail pages with curriculum preview and reviews
- Public certificate verification by certificate number
- Enroll in free courses instantly, or purchase paid courses via Stripe checkout (with coupon support)
- Course player with per-lesson progress tracking and resumable playback
- Quizzes with instant auto-grading (single-choice) and manual grading for open-ended answers
- Assignment submissions with file attachments and resubmission support
- Live class schedule, meeting links, and personal attendance history
- Auto-issued PDF certificates the moment a course reaches 100% completion
- Course reviews and star ratings
- Per-lesson discussion threads (Q&A) with teachers
- Editable personal profile
- Course builder: modules, lessons, and direct video upload
- Quiz builder supporting multiple question types
- Assignment creation with due dates and rubric-free grading + written feedback
- Live class scheduling and attendance marking
- Full student roster per course — progress %, quiz scores, and assignment status at a glance
- Drill into any individual student's activity within a course
- Discussion participation and "pin best answer" moderation
- Dashboard analytics: total & monthly revenue, active students/teachers, completion rate, average quiz score
- Full user management: view any user's profile, activity, and course involvement; change roles; activate/deactivate/delete accounts
- View and moderate every course on the platform, regardless of which teacher owns it
- Coupon management for promotions
- Full audit log of every destructive or state-changing action platform-wide
- Discussion moderation
- Dark / light theme toggle
- JWT access tokens + per-device revocable refresh tokens (stored hashed in DB)
- Role-based access control with a centralized permission matrix
- Rate limiting on authentication and quiz-submission endpoints
- Background job processing (email, certificate generation) via BullMQ
- Soft-delete pattern on core entities via Prisma client extensions
- Centralized error handling and structured logging
| Layer | Technology |
|---|---|
| Frontend | Next.js 15 (App Router), TypeScript, Tailwind CSS v4, Zustand, TanStack Query, React Hook Form + Zod |
| Backend | Node.js, Express 5, TypeScript, Prisma ORM |
| Database | PostgreSQL 16 |
| Cache / Queue | Redis, BullMQ (email + certificate generation workers) |
| Object Storage | MinIO (S3-compatible — videos, certificates, assignment files) |
| Auth | JWT (access + refresh), bcrypt, per-device session revocation |
| Payments | Stripe (test mode), provider-abstracted for easy swapping |
| Testing | Vitest + Supertest |
| Infra / DevOps | Docker Compose (Postgres, Redis, MinIO, Mailhog), GitHub Actions CI, pnpm workspaces |
Every API response follows a consistent envelope:
{ "success": true, "message": "...", "data": {} }Paginated endpoints additionally return:
{ "data": [], "pagination": { "page": 1, "limit": 10, "total": 0, "totalPages": 0 } }lms/
├── apps/
│ ├── backend/
│ │ ├── src/
│ │ │ ├── modules/ # feature-based slices: auth, courses, quizzes, payments, admin, ...
│ │ │ ├── middleware/ # auth guard, RBAC guard, centralized error handler
│ │ │ ├── jobs/ # BullMQ processors (email, certificates)
│ │ │ ├── config/ # env validation, logger, Prisma/Redis/MinIO clients
│ │ │ └── tests/ # Vitest + Supertest integration tests
│ │ └── prisma/ # schema.prisma + seed script
│ └── frontend/
│ └── src/
│ ├── app/ # Next.js App Router — student/teacher/admin routes
│ ├── lib/ # typed API client functions per feature
│ ├── store/ # Zustand stores (auth, theme)
│ └── components/
├── packages/shared/ # reserved for cross-app shared types
├── .github/workflows/ci.yml # lint, typecheck, test, build — on every push/PR
└── docker-compose.yml # Postgres, Redis, MinIO, Mailhog
The backend follows a feature-based (vertical slice) structure rather than a traditional MVC layout — each module owns its validators, service, controller, and routes together, which scales better than a flat controllers/ + services/ split once a project passes ~10 features.
A simplified view of the schema — the full model definitions (20+ tables including soft-delete fields, indexes, and constraints) live in apps/backend/prisma/schema.prisma.
- Node.js ≥ 20
- pnpm ≥ 10
- Docker (for Postgres, Redis, MinIO, Mailhog)
git clone https://github.com/farrukh-ali-khan/lms.git
cd lms
pnpm install
# environment variables
cp .env.example .env
# start infrastructure
docker compose up -d
# database
cd apps/backend
pnpm prisma:generate
pnpm prisma:migrate
pnpm prisma:seed
# run the backend
pnpm devIn a second terminal:
cd apps/frontend
echo 'NEXT_PUBLIC_API_URL="http://localhost:5000/api"' > .env.local
pnpm dev| Service | URL |
|---|---|
| Frontend | http://localhost:3000 |
| Backend API | http://localhost:5000 |
| Mailhog (local emails) | http://localhost:8025 |
| MinIO Console | http://localhost:9001 (minioadmin / minioadmin) |
Seeded automatically via pnpm prisma:seed — all accounts share the same password:
| Role | Password | |
|---|---|---|
| Admin | admin@lms.local | Password123! |
| Teacher | teacher@lms.local | Password123! |
| Student | student@lms.local | Password123! |
All routes are documented inline within each feature module under apps/backend/src/modules/*/*.routes.ts. Key route groups:
| Base path | Purpose |
|---|---|
/api/auth |
Register, login, refresh, logout, email verification, password reset |
/api/courses |
Course, module, and lesson CRUD + video upload |
/api/enrollments |
Enrollment, progress tracking, course roster |
/api/quizzes |
Quiz builder, attempts, auto-grading |
/api/assignments |
Assignment creation, submission, grading |
/api/classes |
Live class scheduling and attendance |
/api/certificates |
Certificate issuance and public verification |
/api/payments |
Stripe checkout, coupons |
/api/discussions |
Course Q&A threads and replies |
/api/admin |
User management and platform analytics |
/api/audit-logs |
Platform-wide audit trail |
cd apps/backend
pnpm testTest suite covers the full authentication flow (registration, duplicate-email rejection, email-verification gating, login, wrong-password rejection, protected-route enforcement) and the role-based permission matrix, run against a real Postgres instance via Supertest.
- Self-hosted live video (LiveKit/Jitsi) instead of external meeting links
- Mobile app
- AI-powered course recommendations
- Gamification (badges, leaderboards)
- Draft versioning for published courses
This is primarily a personal portfolio project, but issues and pull requests are welcome — feel free to open one if you spot a bug or have a suggestion.
Released under the MIT License.
Author: Farrukh Ali Khan