This document explains the directory layout of the CodeX Backend and the purpose of each folder and file.
Understanding the project structure makes it easier to navigate the codebase, locate specific functionality, and contribute to the project.
- Project Overview
- Directory Structure
- Root Directory
- Source Directory
- Configuration
- Controllers
- Models
- Routes
- Middlewares
- Utilities
- Request Flow
- Best Practices
The CodeX Backend follows a modular architecture inspired by the MVC (Model–View–Controller) pattern.
Each folder has a single responsibility.
Client
│
▼
Routes
│
▼
Controllers
│
▼
Models
│
▼
MongoDB
Supporting this architecture are:
- Middlewares
- Utilities
- Configuration
- Constants
This separation keeps the codebase organized, maintainable, and scalable.
Backend/
│
├── docs/
│
├── public/
│ └── temp/
│
├── src/
│ ├── config/
│ ├── controllers/
│ ├── middlewares/
│ ├── models/
│ ├── routes/
│ ├── utils/
│ ├── app.js
│ ├── constants.js
│ └── server.js
│
├── .env
├── .env.example
├── package.json
├── package-lock.json
└── README.md
The root directory contains the project's configuration, documentation, and entry files.
| File / Folder | Purpose |
|---|---|
| docs | Project documentation |
| public | Static files |
| src | Application source code |
| .env | Environment variables |
| .env.example | Example environment configuration |
| package.json | Project metadata and dependencies |
| package-lock.json | Dependency lock file |
| README.md | Project overview |
The src directory contains the application's implementation.
src/
│
├── config/
├── controllers/
├── middlewares/
├── models/
├── routes/
├── utils/
├── app.js
├── constants.js
└── server.js
Every major feature of the application lives inside this directory.
Location
src/server.js
This is the application's entry point.
Responsibilities:
- Load environment variables
- Register global error handlers
- Connect to MongoDB
- Seed the default administrator
- Start the HTTP server
Flow:
Load Environment
↓
Connect Database
↓
Seed Admin
↓
Start Server
Location
src/app.js
This file configures the Express application.
Responsibilities:
- Initialize Express
- Register global middleware
- Configure CORS
- Configure rate limiting
- Register routes
- Configure Swagger
- Register error middleware
No business logic should be written inside app.js.
Location
src/constants.js
Stores application-wide constants.
Examples include:
- Database names
- API constants
- Reusable configuration values
Keeping constants centralized avoids duplicated values across the project.
Directory:
src/config/
Current structure:
config/
└── db.js
Purpose:
Contains application configuration.
Currently responsible for:
- MongoDB connection
Future configuration files may include:
- Redis
- Logger
- Cache
- Queue
- Storage
Directory:
src/controllers/
Current files:
admin.controller.js
backgroundJob.controller.js
blocklist.controller.js
boardingPass.controller.js
certificate.controller.js
contact.controller.js
customQR.controller.js
event.controller.js
healthcheck.controller.js
registration.controller.js
student.controller.js
team.controller.js
Responsibilities:
- Receive requests from routes
- Validate input
- Execute business logic
- Query database
- Call utilities
- Return API responses
Controllers should not:
- Define routes
- Configure middleware
- Define schemas
Example:
Route
↓
Controller
↓
Model
↓
Response
Directory:
src/models/
Current models:
admin.model.js
backgroundJob.model.js
boardingPass.model.js
certificate.model.js
contact.model.js
customQR.model.js
emailBlocklist.model.js
event.model.js
session.model.js
studentRegistration.model.js
teamMember.model.js
token.model.js
Responsibilities:
- Define MongoDB schemas
- Validation
- Indexes
- Instance methods
- Hooks
Controllers interact with models instead of directly accessing MongoDB.
Directory:
src/routes/
Current routes:
admin.routes.js
blocklist.routes.js
boardingPass.routes.js
certificate.routes.js
contact.routes.js
event.routes.js
healthcheck.routes.js
job.routes.js
qr.routes.js
registration.routes.js
student.routes.js
team.routes.js
Responsibilities:
- Define API endpoints
- Attach middleware
- Forward requests to controllers
Example:
POST /api/v1/events
↓
event.routes.js
↓
createEvent()
Routes should remain small and contain no business logic.
Directory:
src/middlewares/
Current middleware:
auth.middleware.js
error.middleware.js
multer.middleware.js
Purpose:
Execute logic before or after controllers.
- JWT verification
- Session validation
- Authentication
Handles file uploads.
Responsibilities:
- Receive uploaded file
- Save temporarily
- Forward file to controller
Global error handler.
Responsibilities:
- Catch unhandled exceptions
- Return standardized error responses
- Prevent application crashes
Directory:
src/utils/
Current utilities:
ApiError.js
ApiResponse.js
asyncHandler.js
cloudinary.js
emailTemplates.js
seedAdmin.js
sendEmail.js
turnstile.js
Utilities provide reusable functionality shared across multiple modules.
Creates standardized application errors.
Used throughout controllers and middleware.
Creates consistent API success responses.
Example:
{
"success": true,
"message": "Success",
"data": {}
}Wraps asynchronous controllers.
Instead of writing repetitive try/catch blocks:
Controller
↓
asyncHandler
↓
Error Middleware
Responsible for:
- Uploading images
- Deleting images
- Returning secure Cloudinary URLs
Centralized email service.
Used for:
- Login OTP
- Registration Approval
- Registration Rejection
- Certificate Emails
Contains reusable HTML email templates.
Separating templates from business logic makes email management easier.
Executed during application startup.
Responsibilities:
- Check if an administrator exists
- Create the default administrator if required
This ensures a fresh installation is immediately usable.
Integrates with Cloudflare Turnstile.
Responsibilities:
- Verify CAPTCHA token
- Prevent automated registrations
public/
Temporary storage for uploaded files.
public/
└── temp/
Workflow:
Client Upload
↓
Multer
↓
public/temp
↓
Cloudinary
↓
Delete Temporary File
Files stored here are temporary and should not be considered permanent storage.
docs/
Contains all project documentation.
Examples:
architecture.md
database.md
authentication.md
middleware.md
api-reference.md
security.md
deployment.md
Keeping documentation inside its own directory improves discoverability and maintenance.
Client
│
▼
Routes
│
▼
Middleware
│
▼
Controller
│
▼
Utility (Optional)
│
▼
Model
│
▼
MongoDB
│
▼
ApiResponse
│
▼
Client
This flow is followed consistently across all features.
Each major feature follows the same architecture.
Example:
Event Feature
event.routes.js
↓
event.controller.js
↓
event.model.js
Another example:
Certificate Feature
certificate.routes.js
↓
certificate.controller.js
↓
certificate.model.js
This predictable structure makes the project easier to understand and extend.
When adding new features, follow these guidelines:
- Create a dedicated route file.
- Keep business logic inside controllers.
- Store database logic inside models.
- Place reusable functions inside utilities.
- Add middleware only when required.
- Follow the existing naming conventions.
- Keep folders focused on a single responsibility.
- Update documentation whenever a new module is introduced.
The CodeX Backend is organized into modular components that separate routing, business logic, database interaction, middleware, and shared utilities.
This structure provides:
- Clear separation of concerns
- Easier debugging
- Better maintainability
- Consistent feature organization
- Improved scalability
- Cleaner collaboration for multiple developers
Following this structure ensures that new features can be added with minimal impact on the existing codebase while keeping the project easy to navigate and maintain.