Implementation Guide for Course
Management System
Overview
This guide provides detailed implementation instructions for the Course Management
System project. It covers the technical approach, coding standards, and specific
implementation details for each component of the system.
Technology Stack
• Backend: Node.js with Express.js
• Database: MongoDB with Mongoose ODM
• Frontend: Handlebars templating engine with CoreUI template
• Authentication: Custom implementation with bcrypt for password hashing
• Session Management: Custom implementation (no express-sessions allowed)
• Security: Custom CSRF protection implementation
Development Environment Setup
Prerequisites
• Node.js (v14 or higher)
• MongoDB (v4.4 or higher)
• Git
Local Setup Instructions
1. Clone the repository git clone [repository-url] cd course-management-system
2. Install dependencies npm install
3. Create a .env file in the root directory with the following variables: PORT=3000
MONGODB_URI=mongodb://localhost:27017/course-management-system
NODE_ENV=development
4. Start MongoDB service on your local machine
5. Start the application in development mode npm run dev
Database Schema Design
User Collection
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
program: {
type: String,
required: true
},
contactInfo: {
type: String,
required: true
},
role: {
type: String,
enum: ['student', 'hod'],
default: 'student'
},
isVerified: {
type: Boolean,
default: false
},
verificationToken: {
type: String
},
resetPasswordToken: {
type: String
},
resetPasswordExpires: {
type: Date
},
createdAt: {
type: Date,
default: Date.now
}
});
Request Collection
const RequestSchema = new mongoose.Schema({
student: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: true
},
category: {
type: String,
required: true,
enum: ['section_change', 'course_registration', 'capstone_registration', 'other']
},
subject: {
type: String,
required: true
},
description: {
type: String,
required: true
},
status: {
type: String,
enum: ['pending', 'processing', 'resolved', 'rejected', 'cancelled'],
default: 'pending'
},
queuePosition: {
type: Number
},
estimatedCompletionTime: {
type: Date
},
hodNotes: {
type: String
},
semester: {
type: String,
required: true
},
createdAt: {
type: Date,
default: Date.now
},
updatedAt: {
type: Date,
default: Date.now
}
});
Queue Collection
const QueueSchema = new mongoose.Schema({
category: {
type: String,
required: true,
unique: true
},
description: {
type: String
},
averageProcessingTime: {
type: Number, // in minutes
default: 15
},
requests: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Request'
}],
createdAt: {
type: Date,
default: Date.now
}
});
Authentication Implementation
User Registration Process
1. Create a registration form with fields for name, email, password, program, and
contact information
2. Implement client-side validation for all fields
3. On form submission, hash the password using bcrypt
4. Generate a verification token using crypto
5. Save the user to the database with isVerified set to false
6. Log the verification email to the console (as per requirements, no actual email
sending)
7. Redirect to a page informing the user to check their email
Email Verification Process
1. Create a route to handle verification links
2. When a user clicks the verification link, find the user by verification token
3. If found, set isVerified to true and remove the verification token
4. Redirect to login page with success message
Login Process
1. Create a login form with fields for email and password
2. On form submission, find the user by email
3. If found, check if the user is verified
4. If verified, compare the password with the stored hash using bcrypt
5. If password matches, generate a session ID using crypto
6. Store the session in the sessions object with user information and expiration time
7. Set a cookie with the session ID
8. Redirect to the appropriate dashboard based on user role
Password Reset Process
1. Create a forgot password form with field for email
2. On form submission, find the user by email
3. If found, generate a reset token using crypto and set expiration time
4. Save the token and expiration to the user document
5. Log the reset email to the console
6. Create a reset password form that accepts the token and new password
7. On form submission, find the user by reset token and check if it's expired
8. If valid, hash the new password and update the user document
9. Remove the reset token and expiration
10. Redirect to login page with success message
Request Management Implementation
Request Submission Process
1. Create a form for students to submit requests with fields for category, subject, and
description
2. Implement client-side validation for all fields
3. On form submission, create a new request document
4. Determine the appropriate queue based on the category
5. Calculate the estimated completion time based on the queue length and average
processing time
6. Add the request to the queue
7. Redirect to a confirmation page with the estimated completion time
Request Cancellation Process
1. Create a button for students to cancel their pending requests
2. On button click, update the request status to 'cancelled'
3. Remove the request from the queue
4. Update the estimated completion times for all remaining requests in the queue
5. Redirect to the request history page with success message
Request History Viewing
1. Create a page for students to view their request history
2. Implement filtering by semester
3. Display requests with their status, submission time, and estimated/actual
completion time
4. Provide a way to view the details of each request
Department Head Interface Implementation
Dashboard Implementation
1. Create a dashboard page for the department head
2. Display statistics for each queue (number of requests, average processing time)
3. Provide links to view each queue
4. Implement the "I don't know where to begin!" button that selects a random
request
Queue Viewing Implementation
1. Create a page to display all requests in a specific queue
2. Sort requests by submission time (first-come-first-served)
3. Display basic information for each request
4. Provide a way to view the details of each request
Request Processing Implementation
1. Create a page for the department head to process a request
2. Display all details of the request
3. Provide a form for the department head to enter notes
4. Implement buttons for resolving or rejecting the request
5. On form submission, update the request status and add the notes
6. Remove the request from the queue
7. Log the notification email to the console
8. Update the estimated completion times for all remaining requests in the queue
9. Redirect to the queue page
Email Notification System
Email Service Module
// utils/emailService.js
const emailService = {
sendVerificationEmail: (user, token) => {
// In a real application, this would send an actual email
// For this project, just log to console
console.log(`
To: ${user.email}
Subject: Verify Your Email
Body:
Hello ${user.name},
Please verify your email by clicking the link below:
http://localhost:3000/auth/verify/${token}
Thank you,
Course Management System Team
`);
},
sendPasswordResetEmail: (user, token) => {
console.log(`
To: ${user.email}
Subject: Reset Your Password
Body:
Hello ${user.name},
You requested a password reset. Please click the link below to reset your password:
http://localhost:3000/auth/reset-password/${token}
This link will expire in 1 hour.
Thank you,
Course Management System Team
`);
},
sendRequestProcessedEmail: (user, request) => {
console.log(`
To: ${user.email}
Subject: Your Request Has Been Processed
Body:
Hello ${user.name},
Your request "${request.subject}" has been ${request.status}.
${request.hodNotes ? `Notes from Department Head: ${request.hodNotes}` : ''}
Thank you,
Course Management System Team
`);
}
};
module.exports = emailService;
CSRF Protection Implementation
CSRF Middleware
// middleware/csrf.js
const crypto = require('crypto');
const csrfProtection = {
generate: (req, res, next) => {
if (req.method === 'GET') {
// Generate CSRF token
const csrfToken = crypto.randomBytes(16).toString('hex');
// Set cookie
res.cookie('csrf-token', csrfToken, { httpOnly: true });
// Make it available to templates
res.locals.csrfToken = csrfToken;
}
next();
},
validate: (req, res, next) => {
if (['POST', 'PUT', 'DELETE'].includes(req.method)) {
const cookieToken = req.cookies['csrf-token'];
const bodyToken = req.body._csrf;
if (!cookieToken || !bodyToken || cookieToken !== bodyToken) {
return res.status(403).send('CSRF token validation failed');
}
}
next();
}
};
module.exports = csrfProtection;
Session Management Implementation
Session Middleware
// middleware/session.js
const crypto = require('crypto');
// In-memory session store (would use MongoDB in production)
const sessions = {};
// Session cleanup (run periodically)
const cleanupSessions = () => {
const now = Date.now();
Object.keys(sessions).forEach(sessionId => {
if (sessions[sessionId].expires < now) {
delete sessions[sessionId];
}
});
};
// Run cleanup every hour
setInterval(cleanupSessions, 3600000);
const sessionMiddleware = {
create: (req, res, user) => {
// Generate session ID
const sessionId = crypto.randomBytes(32).toString('hex');
// Set session expiration (24 hours)
const expires = Date.now() + 86400000;
// Store session
sessions[sessionId] = {
user: {
id: user._id,
name: user.name,
email: user.email,
role: user.role
},
expires
};
// Set cookie
res.cookie('sessionId', sessionId, {
httpOnly: true,
expires: new Date(expires)
});
return sessionId;
},
validate: (req, res, next) => {
const sessionId = req.cookies.sessionId;
if (sessionId && sessions[sessionId]) {
// Check if session is expired
if (sessions[sessionId].expires < Date.now()) {
// Clear expired session
delete sessions[sessionId];
res.clearCookie('sessionId');
return next();
}
// Attach user to request
req.user = sessions[sessionId].user;
// Extend session expiration on activity
sessions[sessionId].expires = Date.now() + 86400000;
res.cookie('sessionId', sessionId, {
httpOnly: true,
expires: new Date(sessions[sessionId].expires)
});
}
next();
},
destroy: (req, res) => {
const sessionId = req.cookies.sessionId;
if (sessionId && sessions[sessionId]) {
// Delete session
delete sessions[sessionId];
}
// Clear cookie
res.clearCookie('sessionId');
}
};
module.exports = sessionMiddleware;
CoreUI Template Integration
Main Layout
The main layout should include the CoreUI template structure with header, sidebar, and
footer. The content area should be a placeholder for page-specific content.
<!-- views/layouts/main.handlebars -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<title>Course Management System</title>
<!-- CoreUI CSS -->
<link href="/css/coreui.min.css" rel="stylesheet">
<link href="/css/custom.css" rel="stylesheet">
<!-- Icons -->
<link href="/css/free.min.css" rel="stylesheet">
</head>
<body class="c-app">
{{> sidebar}}
<div class="c-wrapper">
{{> header}}
<div class="c-body">
<main class="c-main">
<div class="container-fluid">
<div class="fade-in">
{{{body}}}
</div>
</div>
</main>
</div>
{{> footer}}
</div>
<!-- CoreUI and necessary plugins-->
<script src="/js/coreui.bundle.min.js"></script>
<script src="/js/main.js"></script>
</body>
</html>
Header Partial
<!-- views/partials/header.handlebars -->
<header class="c-header c-header-light c-header-fixed">
<button class="c-header-toggler c-class-toggler d-lg-none" type="button" data-target="#sidebar"
data-class="c-sidebar-show">
<span class="c-header-toggler-icon"></span>
</button>
<button class="c-header-toggler c-class-toggler ml-3 d-md-down-none" type="button" data-
target="#sidebar" data-class="c-sidebar-lg-show" responsive="true">
<span class="c-header-toggler-icon"></span>
</button>
<ul class="c-header-nav ml-auto">
{{#if user}}
<li class="c-header-nav-item dropdown">
<a class="c-header-nav-link" data-toggle="dropdown" href="#" role="button" aria-haspopup="true"
aria-expanded="false">
<div class="c-avatar">
<span>{{user.name}}</span>
</div>
</a>
<div class="dropdown-menu dropdown-menu-right">
<a class="dropdown-item" href="/auth/profile">
<i class="c-icon mr-2 cil-user"></i> Profile
</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="/auth/logout">
<i class="c-icon mr-2 cil-account-logout"></i> Logout
</a>
</div>
</li>
{{/if}}
</ul>
</header>
Sidebar Partial
<!-- views/partials/sidebar.handlebars -->
<div class="c-sidebar c-sidebar-dark c-sidebar-fixed c-sidebar-lg-show" id="sidebar">
<div class="c-sidebar-brand">
<h5>Course Management System</h5>
</div>
<ul class="c-sidebar-nav">
<li class="c-sidebar-nav-item">
<a class="c-sidebar-nav-link" href="/">
<i class="c-sidebar-nav-icon cil-speedometer"></i> Dashboard
</a>
</li>
{{#if user}}
{{#if (eq user.role "student")}}
<li class="c-sidebar-nav-item">
<a class="c-sidebar-nav-link" href="/student/submit-request">
<i class="c-sidebar-nav-icon cil-note-add"></i> Submit Request
</a>
</li>
<li class="c-sidebar-nav-item">
<a class="c-sidebar-nav-link" href="/student/request-history">
<i class="c-sidebar-nav-icon cil-history"></i> Request History
</a>
</li>
{{else if (eq user.role "hod")}}
<li class="c-sidebar-nav-item">
<a class="c-sidebar-nav-link" href="/hod/dashboard">
<i class="c-sidebar-nav-icon cil-speedometer"></i> Dashboard
</a>
</li>
<li class="c-sidebar-nav-title">Request Queues</li>
<li class="c-sidebar-nav-item">
<a class="c-sidebar-nav-link" href="/hod/queue/section_change">
<i class="c-sidebar-nav-icon cil-list"></i> Section Changes
</a>
</li>
<li class="c-sidebar-nav-item">
<a class="c-sidebar-nav-link" href="/hod/queue/course_registration">
<i class="c-sidebar-nav-icon cil-list"></i> Course Registration
</a>
</li>
<li class="c-sidebar-nav-item">
<a class="c-sidebar-nav-link" href="/hod/queue/capstone_registration">
<i class="c-sidebar-nav-icon cil-list"></i> Capstone Registration
</a>
</li>
<li class="c-sidebar-nav-item">
<a class="c-sidebar-nav-link" href="/hod/queue/other">
<i class="c-sidebar-nav-icon cil-list"></i> Other Requests
</a>
</li>
<li class="c-sidebar-nav-item">
<a class="c-sidebar-nav-link" href="/hod/random-request">
<i class="c-sidebar-nav-icon cil-random"></i> Random Request
</a>
</li>
{{/if}}
{{else}}
<li class="c-sidebar-nav-item">
<a class="c-sidebar-nav-link" href="/auth/login">
<i class="c-sidebar-nav-icon cil-account-login"></i> Login
</a>
</li>
<li class="c-sidebar-nav-item">
<a class="c-sidebar-nav-link" href="/auth/register">
<i class="c-sidebar-nav-icon cil-user-follow"></i> Register
</a>
</li>
{{/if}}
</ul>
<button class="c-sidebar-minimizer c-class-toggler" type="button" data-target="_parent" data-
class="c-sidebar-minimized"></button>
</div>
Footer Partial
<!-- views/partials/footer.handlebars -->
<footer class="c-footer">
<div>Course Management System © 2025</div>
<div class="ml-auto">Powered by CoreUI</div>
</footer>
Testing Strategy
Unit Testing
• Test each model's validation rules
• Test authentication functions
• Test request processing logic
• Test time estimation algorithm
Integration Testing
• Test user registration and login flow
• Test request submission and processing flow
• Test queue management
End-to-End Testing
• Test complete user journeys
• Test responsive design on different screen sizes
Deployment Considerations
• Set up proper environment variables for production
• Implement proper error handling and logging
• Consider using a production-ready MongoDB instance
• Implement rate limiting for authentication endpoints
Additional Resources
• CoreUI Documentation: https://coreui.io/docs/
• Express.js Documentation: https://expressjs.com/
• Mongoose Documentation: https://mongoosejs.com/docs/
• Handlebars Documentation: https://handlebarsjs.com/