A clean and scalable backend API for managing companies, job posts, HR accounts, and job applications.
Built using Node.js, Express, MongoDB, Mongoose, and follows clean architecture + modular routing.
- Create company profile
- Update company details
- Soft delete company
- List companies
- Handle HR accounts under each company
- Create job under company
- Update job details
- Delete job
- List jobs by company
- Filter jobs
- JWT-based auth
- Role-based access (Company → HR → Job Posters)
- Request validation using custom validation layers
- Global error handling
- Async error wrapper
- Proper routing structure
- Reusable validation schemas
- Status codes standardization
Job-Search-App/
│── src/
│ ├── modules/
│ │ ├── company/
│ │ │ ├── company.controller.js
│ │ │ ├── company.routes.js
│ │ │ ├── company.validation.js
│ │ │ └── company.service.js
│ │ ├── job/
│ │ │ ├── job.controller.js
│ │ │ ├── job.routes.js
│ │ │ └── job.validation.js
│ │ └── auth/
│ │ ├── auth.controller.js
│ │ ├── auth.routes.js
│ │ └── auth.service.js
│ ├── middleware/
│ │ ├── auth.js
│ │ ├── validation.js
│ │ └── asyncErrorHandler.js
│ └── utils/
│ └── generalValidation.js
│
│── config/
│── package.json
│── README.md
POST /company
{
"companyName": "Tech Solutions",
"description": "Software company",
"companyEmail": "info@tech.com",
"numberOfEmployees": 120,
"industry": "IT",
"address": {
"city": "Cairo",
"street": "Nasr City"
}
}POST /company/:companyId/jobs
{
"jobTitle": "Backend Developer",
"jobLocation": "Remote",
"workingTime": "Full-time",
"seniorityLevel": "Junior",
"jobDescription": "Building REST APIs",
"technicalSkills": ["Node.js", "Express", "MongoDB"],
"softSkills": ["Teamwork", "Communication"]
}Create a .env file:
PORT=5000
MONGO_URI=your_mongodb_connection
JWT_SECRET=your_secret_key
git clone https://github.com/almahdy-byte/Job-Search-App
cd Job-Search-App
npm install
npm run devServer runs on:
http://localhost:5000
| Script | Description |
|---|---|
npm run dev |
Run the project with nodemon |
npm start |
Run production build |
The project uses a global error handler + async wrapper:
export const asyncErrorHandler = (fn) => async (req, res, next) => {
try {
await fn(req, res, next);
} catch (err) {
next(err);
}
};- Fork the repo
- Make your changes
- Create pull request
This project is licensed under MIT License.