This is a comprehensive Examination Management System backend API built with Node.js and Express. The system manages students, instructors, courses, exams, and tracks within an educational institution. It uses Microsoft SQL Server as the database with Sequelize ORM for database interactions.
| Technology | Version | Purpose |
|---|---|---|
| Node.js | Latest | Runtime Environment |
| Express | ^5.2.1 | Web Framework |
| Sequelize | ^6.37.7 | ORM for SQL Server |
| Tedious | ^19.2.0 | MS SQL Server Driver |
| express-validator | ^7.3.1 | Request Validation |
| Morgan | ^1.10.1 | HTTP Request Logger |
| dotenv | ^17.2.3 | Environment Variables |
| Nodemon | ^3.1.11 | Development Server (dev) |
Back_sql_project/
βββ index.js # Application entry point
βββ package.json # Dependencies and scripts
βββ .env # Environment variables (not in repo)
βββ .gitignore # Git ignore rules
β
βββ Auth/
β βββ auth.js # Authentication routes
β
βββ Configuration/
β βββ Sequelize.js # Database configuration
β
βββ controllers/
β βββ Courses.js # Course controller logic
β βββ Exams.js # Exam controller logic
β βββ instructors.js # Instructor controller logic
β βββ Students.js # Student auth controller
β βββ StudentsController.js # Student operations controller
β
βββ models/
β βββ init-models.js # Model initialization & associations
β βββ choice.js # Choice model
β βββ course.js # Course model
β βββ department.js # Department model
β βββ exam.js # Exam model
β βββ examquestion.js # Exam-Question junction model
β βββ instructor.js # Instructor model
β βββ question.js # Question model
β βββ student.js # Student model
β βββ studentquestionanswer.js # Student answers model
β βββ topic.js # Topic model
β βββ track.js # Track model
β
βββ Routes/
β βββ Courses.js # Course routes
β βββ ExamsRoute.js # Exam routes (placeholder)
β βββ instructor.js # Instructor routes
β βββ StudentRoute.js # Student routes
β
βββ validators/
βββ coursesValidators.js # Course validation schemas
βββ validationSchemaForExams.js # Exam validation schemas
βββ validationSchemaForInstructors.js # Instructor validation schemas
βββ ValidationSchemaForStudent.js # Student validation schemas
git clone <repository-url>
cd Back_sql_project
npm install
Configure environment variables
Create a .env file in the root directory:
PORT=3000
API_VERSION=api/v1
DB_NAME=your_database_name
DB_USER=your_database_user
DB_PASSWORD=your_database_password
DB_HOST=localhost
Restore the database
Use one of the provided backup files:
dbafterstored.bakdbveido.bak# Development mode (with hot reload)
npm run dev
# Production mode
npm start
Server running at: http://localhost:3000
| Variable | Description | Default |
|---|---|---|
PORT |
Server port number | 3000 |
API_VERSION |
API version prefix | api/v1 |
DB_NAME |
SQL Server database name | - |
DB_USER |
Database username | - |
DB_PASSWORD |
Database password | - |
DB_HOST |
Database host address | - |
βββββββββββββββ βββββββββββββββ βββββββββββββββ
β Department β β Topic β β Choice β
βββββββββββββββ€ βββββββββββββββ€ βββββββββββββββ€
β departmentidβ β topicid (PK)β β choiceid(PK)β
β departmentnameβ β topicname β β choicelabel β
ββββββββ¬βββββββ ββββββββ¬βββββββ β choicetext β
β β β questionid β
β β ββββββββ¬βββββββ
βΌ βΌ β
βββββββββββββββ βββββββββββββββ β
β Track β β Course β β
βββββββββββββββ€ βββββββββββββββ€ β
β trackid(PK) β β courseid(PK)β β
β trackname β β coursename β β
β deptid (FK) β βinstructorid β β
ββββββββ¬βββββββ β topicid(FK) β β
β ββββββββ¬βββββββ β
β β β
βΌ βΌ β
βββββββββββββββ βββββββββββββββ ββββββββ΄βββββββ
β Student β β Instructor β β Question β
βββββββββββββββ€ βββββββββββββββ€ βββββββββββββββ€
βstudentid(PK)β βinstructorid β βquestionid(PK)β
β studentname β βinstructornameβ β questiontextβ
β email β β email β β questiontypeβ
β trackid(FK) β β deptid(FK) β βcorrectanswerβ
ββββββββ¬βββββββ βββββββββββββββ β degree β
β β courseid(FK)β
β βββββββββββββββ ββββββββ¬βββββββ
β β Exam β β
β βββββββββββββββ€ β
β β examid(PK) β β
ββββββββββββββββ studentid ββββββββββββββββ
β courseid β
β grade β
β examdate β
ββββββββ¬βββββββ
β
ββββββββββββββββΌβββββββββββββββ
βΌ βΌ βΌ
βββββββββββββββ βββββββββββββββ
βExamQuestion β βStudentAnswerβ
βββββββββββββββ€ βββββββββββββββ€
β examid(PK) β β examid(PK) β
βquestionid(PK)β βstudentid(PK)β
βββββββββββββββ βquestionid(PK)β
βstudentanswerβ
β mark β
βββββββββββββββ
| Model | Table | Description |
|---|---|---|
| Student | student |
Students enrolled in tracks |
| Instructor | instructor |
Teaching staff assigned to departments |
| Course | course |
Courses taught by instructors |
| Department | department |
Academic departments |
| Track | track |
Learning tracks within departments |
| Topic | topic |
Course topics/categories |
| Exam | exam |
Exams taken by students |
| Question | question |
Exam questions with answers |
| Choice | choice |
Multiple choice options for questions |
| ExamQuestion | examquestion |
Junction table linking exams to questions |
| StudentQuestionAnswer | studentquestionanswer |
Student responses to exam questions |
http://localhost:3000/api/v1
Creates a new student account.
POST /api/v1/auth/register
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
studentname |
string | β | Studentβs full name (min 3 chars) |
email |
string | β | Valid email address |
password |
string | β | Password (min 6 chars) |
trackid |
integer | β | Track ID to assign student |
Example Request:
{
"studentname": "John Doe",
"email": "john.doe@example.com",
"password": "securePass123",
"trackid": 1
}
Success Response (201):
{
"success": true,
"data": "Student registered successfully"
}
Error Response (400):
{
"success": false,
"data": [
{
"msg": "studentname must be at least 3 characters long",
"param": "studentname",
"location": "body"
}
]
}
Authenticates a student and returns their data with enrolled courses.
POST /api/v1/auth/login
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
email |
string | β | Registered email address |
password |
string | β | Account password (min 6 chars) |
Example Request:
{
"email": "john.doe@example.com",
"password": "securePass123"
}
Success Response (200):
{
"success": true,
"data": {
"student": {
"studentid": 1,
"studentname": "John Doe",
"email": "john.doe@example.com",
"trackid": 1
},
"courses": [
{
"courseid": 1,
"coursename": "Introduction to SQL"
}
]
}
}
Creates a new instructor account.
POST /api/v1/auth/instructor/register
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
instructorname |
string | β | Instructorβs full name (min 3 chars) |
email |
string | β | Valid email address |
password |
string | β | Password (min 6 chars) |
deptid |
integer | β | Department ID |
Example Request:
{
"instructorname": "Dr. Jane Smith",
"email": "jane.smith@university.edu",
"password": "profPass123",
"deptid": 2
}
Success Response (201):
{
"success": true,
"data": "Instructor registered successfully"
}
Authenticates an instructor and returns their data with assigned courses.
POST /api/v1/auth/instructor/login
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
email |
string | β | Registered email address |
password |
string | β | Account password (min 6 chars) |
Example Request:
{
"email": "jane.smith@university.edu",
"password": "profPass123"
}
Success Response (200):
{
"success": true,
"data": {
"InstructorData": {
"instructorid": 1,
"instructorname": "Dr. Jane Smith",
"email": "jane.smith@university.edu",
"deptid": 2
},
"courses": [
{
"courseid": 1,
"coursename": "Advanced Database Systems"
}
],
"track": {
"trackid": 1,
"trackname": "Backend Development"
}
}
}
Retrieves a paginated list of all courses.
GET /api/v1/course
Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
page |
integer | β | 1 | Page number (min: 1) |
size |
integer | β | 10 | Items per page (min: 1) |
Example Request:
GET /api/v1/course?page=1&size=10
Success Response (200):
{
"success": true,
"data": [
{
"courseid": 1,
"coursename": "Introduction to SQL",
"instructorid": 1,
"topicid": 1
},
{
"courseid": 2,
"coursename": "Advanced Node.js",
"instructorid": 2,
"topicid": 2
}
]
}
Retrieves a specific course by its ID.
GET /api/v1/course/:id
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id |
integer | Course ID |
Example Request:
GET /api/v1/course/1
Success Response (200):
{
"success": true,
"data": [
{
"courseid": 1,
"coursename": "Introduction to SQL",
"instructorid": 1,
"topicid": 1
}
]
}
Creates a new course.
POST /api/v1/course
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
coursename |
string | β | Course name (min 3 chars) |
instructorid |
integer | β | Instructor ID |
topicid |
integer | β | Topic ID |
Example Request:
{
"coursename": "Machine Learning Basics",
"instructorid": 3,
"topicid": 5
}
Success Response (201):
{
"success": true,
"data": [
{
"courseid": 10
}
]
}
Updates an existing course.
PATCH /api/v1/course
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
courseid |
integer | β | Course ID to update |
coursename |
string | β | New course name |
instructorid |
integer | β | New instructor ID |
topicid |
integer | β | New topic ID |
Example Request:
{
"courseid": 1,
"coursename": "Advanced SQL Techniques",
"instructorid": 2,
"topicid": 1
}
Success Response (200):
{
"success": true,
"data": "Course updated successfully"
}
Deletes a course by ID.
DELETE /api/v1/course
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
courseid |
integer | β | Course ID to delete |
Example Request:
{
"courseid": 5
}
Success Response (200):
{
"success": true,
"data": "Course deleted successfully"
}
Retrieves all students (instructor access).
GET /api/v1/instructor/students
Success Response (200):
{
"success": true,
"data": [
{
"studentid": 1,
"studentname": "John Doe",
"email": "john.doe@example.com",
"trackid": 1
},
{
"studentid": 2,
"studentname": "Jane Smith",
"email": "jane.smith@example.com",
"trackid": 2
}
]
}
Retrieves a specific student by their ID.
GET /api/v1/instructor/students/:studentId
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
studentId |
integer | Student ID |
Example Request:
GET /api/v1/instructor/students/1
Success Response (200):
{
"success": true,
"data": [
{
"studentid": 1,
"studentname": "John Doe",
"email": "john.doe@example.com",
"trackid": 1
}
]
}
Assigns a student to a specific track.
PATCH /api/v1/instructor/students
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
studentid |
integer | β | Student ID |
trackid |
integer | β | Track ID to assign |
Example Request:
{
"studentid": 1,
"trackid": 3
}
Success Response (200):
{
"success": true,
"data": "Student assigned to track successfully"
}
Note: Student routes are currently minimal. The main student functionality is handled through the authentication endpoints.
{
"success": true,
"data": "<response_data>"
}
{
"success": false,
"data": "<error_message>",
"error": "<detailed_error>" // Optional
}
{
"success": false,
"data": [
{
"type": "field",
"value": "<invalid_value>",
"msg": "<error_message>",
"path": "<field_name>",
"location": "body"
}
]
}
| Field | Validation Rules |
|ββ-|ββββββ|
| studentname | Required, trimmed, min 3 characters |
| email | Required, valid email format |
| password | Required, min 6 characters |
| trackid | Optional, must be integer |
| Field | Validation Rules |
|ββ-|ββββββ|
| email | Required, valid email format |
| password | Required, min 6 characters |
| Field | Validation Rules |
|ββ-|ββββββ|
| instructorname | Required, trimmed, min 3 characters |
| email | Required, valid email format |
| password | Required, min 6 characters |
| deptid | Optional, must be integer |
| Field | Validation Rules |
|ββ-|ββββββ|
| email | Required, valid email format |
| password | Required, min 6 characters |
| Field | Validation Rules |
|ββ-|ββββββ|
| studentid | Required, must be integer |
| trackid | Required, must be integer |
| Field | Location | Validation Rules |
|ββ-|βββ-|ββββββ|
| page | query | Optional, positive integer |
| size | query | Optional, positive integer |
| Field | Validation Rules |
|ββ-|ββββββ|
| coursename | Required, min 3 characters |
| instructorid | Optional, positive integer |
| topicid | Optional, positive integer |
| Code | Status | Description |
|---|---|---|
200 |
OK | Request successful |
201 |
Created | Resource created successfully |
400 |
Bad Request | Validation error or invalid request |
404 |
Not Found | Resource not found |
500 |
Internal Server Error | Server-side error |
The application uses SQL Server stored procedures for database operations:
| Procedure | Purpose | Parameters |
|---|---|---|
insert_student |
Register new student | @studentname, @email, @trackid, @password |
sp_StudentLogin |
Authenticate student | @email, @password |
insert_instructor |
Register new instructor | @instructorname, @email, @password, @deptid |
sp_InstructorLogin |
Authenticate instructor | @email, @password |
select_course |
Get courses (paginated) | @PageNumber, @PageSize, @courseid |
insert_course |
Create new course | @coursename, @instructorid, @topicid |
update_course |
Update existing course | @courseid, @coursename, @instructorid, @topicid |
delete_course |
Delete course | @courseid |
select_student |
Get student(s) | @studentId |
assignStudentToTrack |
Assign student to track | @studentid, @trackid |
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/v1/auth/register |
Register student |
POST |
/api/v1/auth/login |
Login student |
POST |
/api/v1/auth/instructor/register |
Register instructor |
POST |
/api/v1/auth/instructor/login |
Login instructor |
GET |
/api/v1/course |
Get all courses |
GET |
/api/v1/course/:id |
Get course by ID |
POST |
/api/v1/course |
Create course |
PATCH |
/api/v1/course |
Update course |
DELETE |
/api/v1/course |
Delete course |
GET |
/api/v1/instructor/students |
Get all students |
GET |
/api/v1/instructor/students/:studentId |
Get student by ID |
PATCH |
/api/v1/instructor/students |
Assign student to track |
The following features are planned or in development:
/api/v1/exam)git checkout -b feature/AmazingFeature)git commit -m 'Add some AmazingFeature')git push origin feature/AmazingFeature)This project is licensed under the ISC License.
For support, please open an issue in the repository or contact the development team.
Documentation generated on January 22, 2026