A RESTful API built with Express.js, TypeScript, and MongoDB for [brief description of your application]
- Backend API: smart-lms-backend.vercel.app
- Features
- Tech Stack
- System Architecture
- Getting Started
- Environment Variables
- API Documentation
- Database Schema
- Authentication
- Deployment
- Project Structure
- RESTful API Design - Clean and intuitive endpoints following REST principles
- JWT Authentication - Secure user authentication with access and refresh tokens
- Role-Based Authorization - Multi-level user access control (Admin, Student, Instructor)
- Input Validation - Robust request validation using Zod
- Error Handling - Centralized error handling with custom error classes
- MongoDB Integration - Mongoose ODM with schema validation and indexing
- TypeScript - Full type safety across the entire codebase
- Security - Password encryption with bcryptjs, CORS, helmet, rate limiting
- Advanced Feature - Payment Gateway, AI integration, PDF generation, and automated emails
- Runtime: Node.js v22+
- Language: TypeScript 5.9+
- Framework: Express.js 5.2+
- Database: MongoDB Atlas
- ODM: Mongoose 9.0+
- JWT: jsonwebtoken
- Password Hashing: bcryptjs
- CORS: cors
- Security Headers: helmet
- Rate Limiting: express-rate-limit
- Cookies: cookie-parser
- Validation: Zod v4+
- Environment Variables: dotenv
- Global Error Handling: express-async-handler
- File Uploads: Multer
- Cloud Storage: Cloudinary
- Payment gatway: Stripe
- AI integration: Gemini API
- PDF generation: PDFKit
- Email: Nodemailer (automated emails)
┌─────────────┐
│ Client │
│ (Frontend) │
└──────┬──────┘
│
│ HTTPS
│
┌──────▼─────────────────────────────┐
│ Express Server │
│ ┌──────────────────────────────┐ │
│ │ Middleware Layer │ │
│ │ - CORS │ │
| | - Cookie Parser | |
│ │ - Helmet │ │
│ │ - Rate Limiting │ │
│ │ - JWT Authentication │ │
│ │ - Error Handler │ │
| | - Zod Validiton | |
| | - Multer File Handling | |
│ └──────────┬───────────────────┘ │
│ │ │
│ ┌──────────▼───────────────────┐ │
│ │ Routes Layer │ │
│ │ - /api/auth │ │
│ │ - /api/users │ │
│ │ - /api/courses │ │
│ │ - /api/entrollments │ │
| | - /api/progress | |
| | - /api/upload | |
│ └──────────┬───────────────────┘ │
│ │ │
│ ┌──────────▼───────────────────┐ │
│ │ Controllers Layer │ │
│ │ - Business Logic │ │
│ │ - Request/Response Handling │ │
│ └──────────┬───────────────────┘ │
│ │ │
│ ┌──────────▼───────────────────┐ │
│ │ Services Layer │ │
│ │ - Advanced Features │ │
│ │ - External API Integration │ │
│ └──────────┬───────────────────┘ │
│ │ │
│ ┌──────────▼───────────────────┐ │
│ │ Models Layer │ │
│ │ - Mongoose Schemas │ │
│ │ - Data Validation │ │
│ └──────────┬───────────────────┘ │
└─────────────┼──────────────────────┘
│
│
┌────────▼─────────┐
│ MongoDB Atlas │
│ (Database) │
└──────────────────┘
- Node.js v22 or higher
- npm or yarn
- MongoDB Atlas account
- Git
-
Clone the repository
git clone https://github.com/chadew344/Smart-LMS-Backend.git cd Smart-LMS-Backend -
Install dependencies
npm install
-
Set up environment variables
cp .env.example.env
Then edit
.envwith your actual values (see Environment Variables) -
Run development server
npm run dev
-
Build for production
npm run build
-
Start production server
npm start
npm run dev # Start development server with hot reload
npm run build # Compile TypeScript to JavaScript
npm start # Start production server
npm run lint # Run ESLint
npm run type-check # Run TypeScript compiler check
npm test # Run tests (if configured)Create a .env file in the root directory:
# Server Configuration
PORT=5000
NODE_ENV=development
# Database
# For local development
MONGO_URI=mongodb://localhost:27017/<dbname>
# For production / cloud (MongoDB Atlas)
MONGO_URI=mongodb+srv://<username>:<password>@cluster.mongodb.net/<dbname>?retryWrites=true&w=majority
# CORS
ALLOWED_ORIGINS=http://localhost:5173
# JWT Secrets
JWT_SECRET=your-super-secret-access-key-change-this
JWT_REFRESH_SECRET=your-super-secret-refresh-key-change-this
ACCESS_TOKEN_EXPIRY=15m
REFRESH_TOKEN_EXPIRY=7d
# External APIs
# Cloudinary -
CLOUDINARY_CLOUD_NAME=your-cloud-name
CLOUDINARY_API_KEY=your-api-key
CLOUDINARY_API_SECRET=your-api-secret
CLOUDINARY_FOLDER=your-custom-folder-name
# AI Integration
GEMINI_API_KEY=AI-your-gemini-api-key
# Email Service
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=587
EMAIL_USER=your-email@gmail.com
EMAIL_PASSWORD=your-app-password
# OAuth
GOOGLE_CLIENT_ID=your-google-client-id-paste-here
GOOGLE_CLIENT_SECRET=your-google-client-secret-paste-here- Production:
https://backend-url.com/api - Development:
http://localhost:5000/api/v1
All errors follow this format:
{
"success": false,
"error": {
"message": "Error message",
"statusCode": 400,
"errors": [
{
"field": "email",
"message": "Invalid email format"
}
]
}
}All success follow this format:
{
"success": true,
"message": "Login successful",
"data": {
"user": {
"id": "user-id-12345",
"email": "user@example.com",
"firstName": "John",
"lastName": "Doe",
"roles": ["STUDENT"]
},
"accessToken": "<YOUR_ACCESS_TOKEN>"
}
}Common HTTP Status Codes:
200- Success201- Created204- No Content400- Bad Request401- Unauthorized403- Forbidden404- Not Found409- Conflict422- Validation Error429- Too Many Requests500- Internal Server Error
The Smart LMS uses a Hybrid Document Architecture. While most data is relational, the course curriculum uses Deeply Nested Sub-documents to allow for high-performance retrieval of entire course structures in a single query.
Instead of multiple joins, the curriculum hierarchy is stored within the Course document for atomic updates and fast reads.
- Course (Root): Metadata, pricing, and instructor ref.
- Modules (Array): Sub-documents containing groups of lessons.
- Lessons (Nested Array): Supports Polymorphic Content (Video, Reading, or Quiz).
To support secure session management, we use a dedicated RefreshToken collection.
- TTL Indexing: Uses
expireAfterSeconds: 0on theexpiresAtfield. This allows MongoDB to automatically delete expired sessions, ensuring the database remains clean without manual cron jobs. - User Linking: Strict
ref: "User"relationship to maintain session integrity.
| Entity | Type | Description |
|---|---|---|
| User ↔ Course | 1 : N |
One Instructor manages multiple courses. |
| Course ↔ Module ↔ Lesson | Embedded |
Hierarchical curriculum for 1-query fetching. |
| User ↔ RefreshToken | 1 : 1 |
Managed session persistence and token rotation. |
| Lesson ↔ Quiz | Ref |
Lessons link to assessments via quizId. |
| Progress | 1 : 1 |
Tracks a specific Student's completion percentage within a Course. |
The system reduces frontend logic by automating data calculations within the database layer using Mongoose Middleware:
Whenever a Course is created or updated, a pre("save") hook triggers:
- Total Lessons: Automatically counts all lessons across all modules.
- Total Duration: Sums the
durationof every nested lesson.
// Example of the logic implemented
CourseSchema.pre("save", function () {
this.totalLessons = this.modules.reduce(
(total, m) => total + m.lessons.length,
0
);
this.totalDuration = this.modules.reduce((total, m) => {
return total + m.lessons.reduce((sum, l) => sum + (l.duration || 0), 0);
}, 0);
});This API uses JWT (JSON Web Tokens) for authentication with a dual-token system:
-
Access Token
- Short-lived (15 minutes)
- Used for API requests
- Stored in memory (frontend)
-
Refresh Token
- Long-lived (7 days)
- Used to obtain new access tokens
- Stored in httpOnly cookie or secure storage
- Passwords hashed using bcryptjs with salt rounds of 12
- Minimum password requirements enforced in validation
- Never stored in plain text
// Middleware usage example
export enum Role {
ADMIN = "ADMIN",
STUDENT = "STUDENT",
INSTRUCTOR = "INSTRUCTOR",
}
router.post(
"/instructor-only",
authenticate,
authorize([Role.INSTRUCTOR]),
controller
);
router.get(
"/student-or-admin",
authenticate,
authorize([Role.STUDENT, Role.ADMIN]),
controller
);Roles:
- Admin: Manages and maintains the platform.
- Instructor: Creates and manages courses.
- Student: Enrolls in courses and learns.
This project can be deployed easily using Vercel for the backend and MongoDB Atlas for the database.
-
Set up MongoDB Atlas
- Create a cluster on MongoDB Atlas.
- Create a database and user.
- Get your connection string (MONGO_URI).
-
Deploy Backend on Vercel
- Go to Vercel and create a new project.
- Connect your GitHub repository.
- Set environment variables (see Environment Variables), especially
MONGO_URIand JWT secrets. - Vercel will automatically build and deploy your backend.
-
Access your API
- After deployment, Vercel provides a URL like:
https://your-project-name.vercel.app/api - You can use this URL in your frontend or API clients.
- After deployment, Vercel provides a URL like:
backend/
├── src
│ ├── config
│ │ ├── cloudinary.ts # Cloud Storage Conig
│ │ ├── email.config.ts # Email config (Gmail)
│ │ ├── googleOAuth.ts
│ │ └── stripe.config.ts # Payment Gatway config(stripe)
│ ├── controllers
│ │ ├── ai.controller.ts # Intergrate with Gemini
│ │ ├── auth.controller.ts
│ │ ├── course.controller.ts
│ │ ├── email.controller.ts
│ │ ├── enrollement.controller.ts
│ │ ├── payment.controller.ts
│ │ ├── progress.controller.ts
│ │ └── upload.controller.ts
│ ├── middleware
│ │ ├── auth.middleware.ts # JWT authentication and Role-based authorization
│ │ ├── error.middleware.ts # Global error handler
│ │ ├── upload.middleware.ts # File Handling
│ │ └── validate.middleware.ts # Input validation
│ ├── models
│ │ ├── course.model.ts
│ │ ├── enrollment.model.ts
│ │ ├── progress.model.ts
│ │ ├── quiz.model.ts
│ │ ├── refreshToken.model.ts
│ │ ├── submission.model.ts
│ │ └── user.model.ts
│ ├── routes
│ │ ├── ai.routes.ts
│ │ ├── auth.routes.ts
│ │ ├── course.routes.ts
│ │ ├── email.routes.ts
│ │ ├── enrollement.routes.ts
│ │ ├── progess.routes.ts
│ │ ├── progress.routes.ts
│ │ └── upload.routes.ts
│ ├── types # Custom Types
│ │ ├── auth.types.ts
│ │ ├── course.type.ts
│ │ ├── email.type.ts
│ │ └── payment.types.ts
│ ├── utils
│ │ ├── ApiError.ts
│ │ ├── asyncHandler.ts
│ │ ├── emailText.ts # Email text templates notifications
│ │ ├── jwt.util.ts
│ │ └── successResponse.ts
│ ├── validate # Zod validation schemas
│ | ├── auth.schema.ts
│ | ├── course.schema.ts
│ | ├── email.schema.ts
│ | ├── enrollment.schema.ts
│ | ├── progress.schema.ts
│ | └── submission.schema.ts
│ └── index.ts # Server entry point
├── .env.example
├── .gitignore
├── package.json
├── README.md
└── tsconfig.json
Contributions, issues, and feature requests are welcome!
For questions or support, contact: chanuthdewhan273@gmail.com
Note: This project was developed by a student as part of the Rapid API Development module.