Backend API for a quiz/testing platform built with Node.js, Express, MongoDB, and Mongoose.
- User authentication with JWT (
sign-up,sign-in,sign-out) - Role-aware access (
admin,teacher,student) - Test creation and publishing
- Question creation and assignment to tests
- Student enrollment for private tests
- Fetch available tests by role
- Node.js (ES Modules)
- Express
- MongoDB + Mongoose
- JWT (
jsonwebtoken) - Password hashing (
bcryptjs)
- Node.js
>=20.19.0(required bymongoose@9.x) - npm
- MongoDB connection string
- Install dependencies:
npm install- Create a
.envfile in the project root:
PORT=5500
SERVER_URL=http://localhost:5500
MONGODB_URI=your_mongodb_connection_string
JWT_SECRET=your_jwt_secret
JWT_EXPIRES_IN=1d- Start in development mode:
npm run dev- Or run in normal mode:
npm startThe app currently listens on http://localhost:5500.
npm run dev- run withnodemonnpm start- run withnode app.js
/api/v1
Protected routes require:
Authorization: Bearer <token>
Token is returned from POST /api/v1/auth/sign-in.
POST /api/v1/auth/sign-up- Create a userPOST /api/v1/auth/sign-in- Sign in and get JWT tokenPOST /api/v1/auth/sign-out- Sign out (stateless response)
GET /api/v1/users- Get all usersGET /api/v1/users/:id- Get single user (auth required)PATCH /api/v1/users/update/:id- Update user (auth required)
POST /api/v1/tests/create- Create test (teacher/admin)PATCH /api/v1/tests/:id/publish- Update/publish test (teacher/admin)POST /api/v1/tests/:id/questions- Add question to test (teacher/admin)POST /api/v1/tests/:id/enroll- Enroll student by email (teacher/admin)GET /api/v1/tests/available- Get available tests by role (auth required)
{
"firstName": "Jane",
"lastName": "Doe",
"email": "jane@example.com",
"password": "secret123",
"role": "student"
}{
"email": "jane@example.com",
"password": "secret123"
}{
"title": "Intro to Biology",
"description": "Week 1 quiz",
"duration": 30,
"visibility": "public",
"status": "draft",
"startTime": "2026-03-07T09:00:00.000Z",
"endTime": "2026-03-07T09:30:00.000Z"
}{
"testId": "TEST_OBJECT_ID",
"questionText": "What is 2 + 2?",
"type": "single",
"options": [
{ "text": "3", "isCorrect": false },
{ "text": "4", "isCorrect": true }
],
"points": 1
}Most errors are returned as:
{
"success": false,
"error": "Error message"
}backend/
app.js
config/
controllers/
database/
middleware/
models/
routes/
app.jscurrently uses a hardcoded port (5500) instead ofPORTfrom.env.POST /api/v1/tests/:id/questionsreadstestIdfrom request body.POST /api/v1/tests/:id/enrollhas query/model mismatches that may affect enrollment flow.
MIT - see LICENSE.