Express + MongoDB REST API for the DevCamper application: bootcamps, the courses and reviews attached to them, and the users who own them.
| Layer | Choice |
|---|---|
| Runtime | Node.js >= 20.15.0, npm >= 10.2.4 |
| Web framework | Express 5 |
| Database | MongoDB through Mongoose 9 |
| Validation | Joi schemas on params, body and query per route |
| Authentication | JWT (Bearer header or httpOnly cookie) + lusca CSRF tokens |
| Geocoding | node-geocoder (LocationIQ by default) |
| Nodemailer over SMTP | |
| Testing | Jest + Supertest |
| Formatting | Prettier |
git clone <repository-url> && cd apiNodeJS
npm install
cp .env.example .env # then edit the values
npm run seed # optional: load fixture data
npm run dev # http://localhost:4444MongoDB must be reachable at MONGO_URI before the server starts.
Gotcha: keep
NODE_ENV=developmentin.envwhile developing.index.jsskipsconnectDB()whenNODE_ENV=test, and the seeder than writes toMONGO_URI_TESTinstead ofMONGO_URI.
| Command | What it does |
|---|---|
npm run dev |
Dev server with nodemon + inspector |
npm start |
Production server (node index.js) |
npm test |
Full Jest suite (--detectOpenHandles) |
npm run format |
Write Prettier formatting across the repo |
npm run seed |
Import _data/*.json into MONGO_URI |
npm run seed:destroy |
Drop all seeded collections |
npm run seed:test |
Import fixtures into MONGO_URI_TEST |
npm run seed:test:destroy |
Drop collections on the test DB |
Seeding an already-populated database fails on duplicate _id and exits 1 β run npm run seed:destroy first. Batches are dependent (users β bootcamps β courses β reviews), so a failure stops the dependents instead of cascading more errors.
Copy .env.example to .env. Never commit .env β it is git-ignored.
| Variable | Purpose |
|---|---|
NODE_ENV |
development | production | test. Gates CSRF, DB auto-connect and logging |
PORT |
HTTP port; .env.example sets 4444, code falls back to 5000 |
MONGO_URI |
Development / production database |
MONGO_URI_TEST |
Database used by tests and --test seeding |
GEOCODER_PROVIDER |
node-geocoder provider (e.g. locationiq) |
GEOCODER_API_KEY |
Geocoding provider API key |
FILE_UPLOAD_PATH |
Upload target for bootcamp photos |
MAX_FILE_UPLOAD |
Maximum upload size in bytes |
JWT_SECRET |
Signing key for access tokens |
JWT_EXPIRE |
Token lifetime (e.g. 30d) |
JWT_COOKIE_EXPIRE |
Cookie lifetime in days |
SESSION_SECRET |
Signing key for session / CSRF state |
SMTP_HOST, SMTP_PORT, SMTP_EMAIL, SMTP_PASSWORD |
Outbound mail |
FROM_EMAIL, FROM_NAME |
Mail sender identity |
All routes mount under /api/v1.
| Group | Endpoints | Access |
|---|---|---|
Auth /auth |
POST /register, POST /login, GET /logout, GET /csrf-token, GET /me, PUT /updatedetails, PUT /updatepassword, POST /forgotpassword, PUT /resetpassword/:resettoken |
Public; mutating calls need a CSRF token. Login / register / forgot / reset are rate limited |
Bootcamps /bootcamps |
GET /, GET /:id, POST /, PUT /:id, DELETE /:id, PUT /:id/photo, GET /radius/:zipcode/:distance |
Reads public; writes need admin or publisher |
Courses /bootcamps/:bootcampId/courses, /courses |
GET /, GET /:id, POST /, PUT /:id, DELETE /:id |
Reads public; writes need admin or publisher |
Reviews /bootcamps/:bootcampId/reviews, /reviews |
GET /, GET /:id, POST /, PUT /:id, DELETE /:id |
Reads public; writes need admin or user |
Users /users |
GET /, GET /:id, POST /, PUT /:id, DELETE /:id |
admin only |
List endpoints accept advancedResults query params (pagination, sorting, filtering, field selection). Request/response examples are in API Reference.
index.js App bootstrap: middleware pipeline, route mounting, Swagger UI
seeder.js Fixture import / destroy
db/ Mongo connection; picks dev vs test URI from NODE_ENV
routes/ One router per resource + index barrel
controllers/ Request handlers
models/ Mongoose schemas, hooks, statics, indexes
middleware/ protect, authorize, validate, advancedResults, async, error, logging
utils/ geocoder, sendMail, ErrorResponse, validators/, csrf/
_data/ JSON fixtures (bootcamps, courses, users, reviews)
config/ config.json (hostname, mailer settings)
tests/ Jest + Supertest suites
docs/ Guides, swagger.json, Swagger UI source
index.jsloads.envand applies middleware in order: body parser β cookies β logger β file upload βhelmetβ mongo-sanitize β global rate limit βhppβcorsβ session +lusca.csrf()β static files.- The request hits a router mounted under
/api/v1/.... - Per route:
validate(joiSchema)βprotect(JWT) βauthorize(...roles)βadvancedResults(model)β controller. - Controllers call the Mongoose models and respond; the
async()wrapper forwards rejections to the error handler. middleware/error.jsrenders{ success: false, error }with a status code.
lusca.csrf() is enabled whenever NODE_ENV !== "development", so every POST / PUT / DELETE needs the token from GET /api/v1/auth/csrf-token together with its session cookie.
- Bootcamp β Course (1: N) β deleting a bootcamp cascade to its courses;
getAverageCost()rolls tuition up intobootcamp.averageCostand$unsets it when no courses remain. - Bootcamp β Review (1: N) β
getAverageRating()rolls ratings up intobootcamp.averageRatingand$unsets it when no reviews remain. - User β Bootcamp / Course / Review (1: N) β ownership used for authorization.
- Review carries a unique
(bootcamp, user)index: one review per user per bootcamp. - A
pre("save")hook geocodesbootcamp.addressintobootcamp.location, then clears the raw address. - Read paths use
.lean(); foreign keys are indexed.
npm test- Suites live in
tests/β currently 32 suites / 83 tests. - Integration style: Supertest drives the real Express app against a real MongoDB (
MONGO_URI_TEST, databasebnodeapi_test). - Jest forces
NODE_ENV=test, so CSRF stays on whileindex.jsskips auto-connecting; each suite opens its own connection inbeforeAll. - Tests create their own users and bootcamps and clean up in
afterAll. Seeding with--teststubs the geocoder, so no external API calls are made.
- bcrypt password hashing; JWT with configurable expiry; httpOnly cookies.
- Role-based authorization (
user,publisher,admin) on every mutating route. - Joi validation on
params,bodyandqueryfor every route. - Per-endpoint rate limits (login 10/10 min, register 10/10 min, forgot-password 5/15 min, reset 10/15 min) plus a global limiter.
helmet,cors,hpp,express-mongo-sanitize, lusca CSRF.- Photo upload validates MIME type and extension, rebuilds the filename from the bootcamp id, and rejects path traversal.
The documentation has been split into several files for better organization:
- System Design: Comprehensive system architecture, design patterns, and technical overview of the project.
- Setup and Configuration: Instructions on how to install, configure, and run the project.
- API Reference: Detailed documentation of all API endpoints, including request/response examples.
- Project Structure: Explanation of the codebase organization and key directories.
- Project Flow: Request lifecycle and data flow diagrams.
flowchart TD
subgraph group_client["Client"]
end
subgraph group_api["HTTP API"]
node_index_js["index.js<br/>app entry<br/>[index.js]"]
node_routes_index["Routes<br/>router compose<br/>[index.js]"]
node_middleware_index["Middleware<br/>[index.js]"]
node_auth_mw["Auth<br/>[auth.js]"]
node_validate_mw["Validate<br/>validation middleware<br/>[validate.js]"]
node_async_mw["Async<br/>error wrapper<br/>[async.js]"]
node_error_mw["Error Handler<br/>error middleware<br/>[error.js]"]
node_request_logger["Request Log<br/>logging middleware<br/>[requestLogger.js]"]
end
subgraph group_domain["Domain"]
node_auth_ctrl["Auth Ctrl<br/>auth controller<br/>[authController.js]"]
node_users_ctrl["Users Ctrl<br/>user controller<br/>[usersController.js]"]
node_bootcamps_ctrl["Bootcamps Ctrl<br/>bootcamp controller"]
node_courses_ctrl["Courses Ctrl<br/>course controller"]
node_reviews_ctrl["Reviews Ctrl<br/>review controller"]
node_validators["Validators<br/>validation rules<br/>[index.js]"]
end
subgraph group_data["Data"]
node_models_index["Models<br/>model exports<br/>[index.js]"]
node_db_index[("DB<br/>database wiring<br/>[index.js]")]
node_bootcamp_model["Bootcamp<br/>mongoose model<br/>[BootcampModel.js]"]
node_course_model["Course<br/>mongoose model<br/>[CourseModel.js]"]
node_review_model["Review<br/>mongoose model<br/>[ReviewModel.js]"]
node_user_model["User<br/>mongoose model<br/>[UserModel.js]"]
end
subgraph group_integrations["Integrations"]
node_geocoder["Geocoder<br/>external service<br/>[geocoder.js]"]
node_send_mail["Send Mail<br/>email service<br/>[sendMail.js]"]
node_csrf_utils["CSRF Utils<br/>security utility<br/>[reproduce_csrf.js]"]
end
subgraph group_ops["Ops"]
node_seeder["Seeder<br/>data seeding<br/>[seeder.js]"]
node_tests["API Tests<br/>integration tests<br/>[auth.test.js]"]
end
node_index_js -->|"mounts"| node_routes_index
node_index_js -->|"uses"| node_middleware_index
node_index_js -->|"connects"| node_db_index
node_index_js -->|"finalizes"| node_error_mw
node_routes_index -->|"routes"| node_auth_ctrl
node_routes_index -->|"routes"| node_users_ctrl
node_routes_index -->|"routes"| node_bootcamps_ctrl
node_routes_index -->|"routes"| node_courses_ctrl
node_routes_index -->|"routes"| node_reviews_ctrl
node_routes_index -->|"guards"| node_auth_mw
node_routes_index -->|"validates"| node_validate_mw
node_middleware_index -->|"exports"| node_async_mw
node_middleware_index -->|"exports"| node_auth_mw
node_middleware_index -->|"exports"| node_validate_mw
node_middleware_index -->|"exports"| node_request_logger
node_middleware_index -->|"exports"| node_error_mw
node_auth_ctrl -->|"uses"| node_user_model
node_users_ctrl -->|"uses"| node_user_model
node_bootcamps_ctrl -->|"uses"| node_bootcamp_model
node_bootcamps_ctrl -->|"calls"| node_geocoder
node_courses_ctrl -->|"uses"| node_course_model
node_reviews_ctrl -->|"uses"| node_review_model
node_auth_ctrl -->|"calls"| node_send_mail
node_bootcamps_ctrl -->|"checks"| node_validators
node_courses_ctrl -->|"checks"| node_validators
node_reviews_ctrl -->|"checks"| node_validators
node_users_ctrl -->|"checks"| node_validators
node_auth_ctrl -->|"checks"| node_validators
node_models_index -->|"exports"| node_bootcamp_model
node_models_index -->|"exports"| node_course_model
node_models_index -->|"exports"| node_review_model
node_models_index -->|"exports"| node_user_model
node_db_index -->|"supports"| node_models_index
node_seeder -->|"uses"| node_db_index
node_seeder -->|"loads"| node_models_index
node_tests -->|"exercises"| node_routes_index
node_tests -->|"regresses"| node_middleware_index
node_csrf_utils -->|"supports"| node_middleware_index
node_request_logger -->|"observes"| node_index_js
click node_index_js "https://github.com/sourav-roy/apinodejs/blob/SOURAV/index.js"
click node_routes_index "https://github.com/sourav-roy/apinodejs/blob/SOURAV/routes/index.js"
click node_middleware_index "https://github.com/sourav-roy/apinodejs/blob/SOURAV/middleware/index.js"
click node_auth_mw "https://github.com/sourav-roy/apinodejs/blob/SOURAV/middleware/auth.js"
click node_validate_mw "https://github.com/sourav-roy/apinodejs/blob/SOURAV/middleware/validate.js"
click node_async_mw "https://github.com/sourav-roy/apinodejs/blob/SOURAV/middleware/async.js"
click node_error_mw "https://github.com/sourav-roy/apinodejs/blob/SOURAV/middleware/error.js"
click node_request_logger "https://github.com/sourav-roy/apinodejs/blob/SOURAV/middleware/requestLogger.js"
click node_auth_ctrl "https://github.com/sourav-roy/apinodejs/blob/SOURAV/controllers/authController.js"
click node_users_ctrl "https://github.com/sourav-roy/apinodejs/blob/SOURAV/controllers/usersController.js"
click node_bootcamps_ctrl "https://github.com/sourav-roy/apinodejs/blob/SOURAV/controllers/bootcampsController.js"
click node_courses_ctrl "https://github.com/sourav-roy/apinodejs/blob/SOURAV/controllers/coursesController.js"
click node_reviews_ctrl "https://github.com/sourav-roy/apinodejs/blob/SOURAV/controllers/reviewsController.js"
click node_validators "https://github.com/sourav-roy/apinodejs/blob/SOURAV/utils/validators/index.js"
click node_models_index "https://github.com/sourav-roy/apinodejs/blob/SOURAV/models/index.js"
click node_db_index "https://github.com/sourav-roy/apinodejs/blob/SOURAV/db/index.js"
click node_bootcamp_model "https://github.com/sourav-roy/apinodejs/blob/SOURAV/models/BootcampModel.js"
click node_course_model "https://github.com/sourav-roy/apinodejs/blob/SOURAV/models/CourseModel.js"
click node_review_model "https://github.com/sourav-roy/apinodejs/blob/SOURAV/models/ReviewModel.js"
click node_user_model "https://github.com/sourav-roy/apinodejs/blob/SOURAV/models/UserModel.js"
click node_geocoder "https://github.com/sourav-roy/apinodejs/blob/SOURAV/utils/geocoder.js"
click node_send_mail "https://github.com/sourav-roy/apinodejs/blob/SOURAV/utils/sendMail.js"
click node_csrf_utils "https://github.com/sourav-roy/apinodejs/blob/SOURAV/utils/csrf/reproduce_csrf.js"
click node_seeder "https://github.com/sourav-roy/apinodejs/blob/SOURAV/seeder.js"
click node_tests "https://github.com/sourav-roy/apinodejs/blob/SOURAV/tests/auth.test.js"
classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_index_js,node_routes_index,node_middleware_index,node_auth_mw,node_validate_mw,node_async_mw,node_error_mw,node_request_logger toneAmber
class node_auth_ctrl,node_users_ctrl,node_bootcamps_ctrl,node_courses_ctrl,node_reviews_ctrl,node_validators toneMint
class node_models_index,node_db_index,node_bootcamp_model,node_course_model,node_review_model,node_user_model toneRose
class node_geocoder,node_send_mail,node_csrf_utils toneIndigo
class node_seeder,node_tests toneTeal
flowchart TD
subgraph group_http["HTTP API"]
node_server["Express server<br/>Node entrypoint<br/>[index.js]"]
node_routes["Route composition<br/>Express router<br/>[index.js]"]
node_bootcamp_routes["Bootcamp routes<br/>resource routes<br/>[bootcampsRoute.js]"]
node_course_routes["Course routes<br/>resource routes<br/>[coursesRoute.js]"]
node_review_routes["Review routes<br/>resource routes<br/>[reviewsRoute.js]"]
node_account_routes["Auth and user routes<br/>account routes<br/>[authRoute.js]"]
node_auth_middleware["Auth and authorization<br/>JWT middleware<br/>[auth.js]"]
node_request_pipeline["Request safeguards<br/>middleware<br/>[advancedResults.js]"]
end
subgraph group_domain["Domain"]
node_bootcamp_controller["Bootcamp controller"]
node_course_controller["Course controller"]
node_review_controller["Review controller"]
node_auth_controller["Auth controller<br/>[authController.js]"]
node_user_controller["User controller<br/>[usersController.js]"]
node_models[("Bootcamp domain models<br/>Mongoose schemas<br/>[BootcampModel.js]")]
end
subgraph group_platform["Platform"]
node_database[("MongoDB connection<br/>persistence adapter<br/>[db.js]")]
node_geocoder{{"Geocoding service<br/>external integration<br/>[geocoder.js]"}}
node_mail{{"Mail delivery<br/>external integration<br/>[sendMail.js]"}}
node_seeder["Data seeder<br/>operations script<br/>[seeder.js]"]
node_deployment{{"Vercel deployment<br/>serverless target<br/>[vercel.json]"}}
end
node_server -->|"applies"| node_request_pipeline
node_server -->|"applies"| node_auth_middleware
node_server -->|"mounts"| node_routes
node_routes -->|"composes"| node_bootcamp_routes
node_routes -->|"composes"| node_course_routes
node_routes -->|"composes"| node_review_routes
node_routes -->|"composes"| node_account_routes
node_auth_middleware -.->|"protects"| node_bootcamp_routes
node_auth_middleware -.->|"protects"| node_course_routes
node_auth_middleware -.->|"protects"| node_review_routes
node_auth_middleware -.->|"protects"| node_account_routes
node_bootcamp_routes -->|"dispatches"| node_bootcamp_controller
node_course_routes -->|"dispatches"| node_course_controller
node_review_routes -->|"dispatches"| node_review_controller
node_account_routes -->|"dispatches"| node_auth_controller
node_account_routes -->|"dispatches"| node_user_controller
node_bootcamp_controller -->|"reads and writes"| node_models
node_course_controller -->|"reads and writes"| node_models
node_review_controller -->|"reads and writes"| node_models
node_auth_controller -->|"manages users"| node_models
node_user_controller -->|"manages users"| node_models
node_models -->|"persists through"| node_database
node_bootcamp_controller -->|"geocodes addresses"| node_geocoder
node_auth_controller -->|"sends recovery mail"| node_mail
node_seeder -->|"loads seed records"| node_models
node_deployment -->|"hosts"| node_server
click node_server "https://github.com/sourav-roy/apinodejs/blob/SOURAV/index.js"
click node_routes "https://github.com/sourav-roy/apinodejs/blob/SOURAV/routes/index.js"
click node_bootcamp_routes "https://github.com/sourav-roy/apinodejs/blob/SOURAV/routes/bootcampsRoute.js"
click node_course_routes "https://github.com/sourav-roy/apinodejs/blob/SOURAV/routes/coursesRoute.js"
click node_review_routes "https://github.com/sourav-roy/apinodejs/blob/SOURAV/routes/reviewsRoute.js"
click node_account_routes "https://github.com/sourav-roy/apinodejs/blob/SOURAV/routes/authRoute.js"
click node_auth_middleware "https://github.com/sourav-roy/apinodejs/blob/SOURAV/middleware/auth.js"
click node_request_pipeline "https://github.com/sourav-roy/apinodejs/blob/SOURAV/middleware/advancedResults.js"
click node_bootcamp_controller "https://github.com/sourav-roy/apinodejs/blob/SOURAV/controllers/bootcampsController.js"
click node_course_controller "https://github.com/sourav-roy/apinodejs/blob/SOURAV/controllers/coursesController.js"
click node_review_controller "https://github.com/sourav-roy/apinodejs/blob/SOURAV/controllers/reviewsController.js"
click node_auth_controller "https://github.com/sourav-roy/apinodejs/blob/SOURAV/controllers/authController.js"
click node_user_controller "https://github.com/sourav-roy/apinodejs/blob/SOURAV/controllers/usersController.js"
click node_models "https://github.com/sourav-roy/apinodejs/blob/SOURAV/models/BootcampModel.js"
click node_database "https://github.com/sourav-roy/apinodejs/blob/SOURAV/db/db.js"
click node_geocoder "https://github.com/sourav-roy/apinodejs/blob/SOURAV/utils/geocoder.js"
click node_mail "https://github.com/sourav-roy/apinodejs/blob/SOURAV/utils/sendMail.js"
click node_seeder "https://github.com/sourav-roy/apinodejs/blob/SOURAV/seeder.js"
click node_deployment "https://github.com/sourav-roy/apinodejs/blob/SOURAV/vercel.json"
classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_server,node_routes,node_bootcamp_routes,node_course_routes,node_review_routes,node_account_routes,node_auth_middleware,node_request_pipeline toneBlue
class node_bootcamp_controller,node_course_controller,node_review_controller,node_auth_controller,node_user_controller,node_models toneAmber
class node_database,node_geocoder,node_mail,node_seeder,node_deployment toneMint
flowchart TD
subgraph group_api["HTTP API"]
node_server["Server bootstrap<br/>Express entry point<br/>[index.js]"]
node_routes["Route aggregation<br/>router composition<br/>[index.js]"]
node_auth_routes["Auth routes<br/>router<br/>[authRoute.js]"]
node_bootcamp_routes["Bootcamp routes<br/>router<br/>[bootcampsRoute.js]"]
node_controllers["Controller exports<br/>controller composition<br/>[index.js]"]
node_authz{{"JWT & role guard<br/>auth middleware<br/>[auth.js]"}}
node_results["Query results middleware<br/>pagination/filtering<br/>[advancedResults.js]"]
node_validation_errors["Validation & error boundary<br/>middleware<br/>[validate.js]"]
end
subgraph group_domain["Domain"]
node_bootcamps["Bootcamp controller<br/>resource controller"]
node_courses["Course controller<br/>resource controller"]
node_reviews["Review controller<br/>resource controller"]
node_users["User controller<br/>user administration<br/>[usersController.js]"]
node_auth["Auth controller<br/>identity workflow<br/>[authController.js]"]
node_models[("Mongoose aggregates<br/>persistence models<br/>[BootcampModel.js]")]
node_database[("MongoDB connection<br/>database adapter<br/>[db.js]")]
end
subgraph group_integrations["Integrations & operations"]
node_geocoder{{"Geocoding service<br/>external service adapter<br/>[geocoder.js]"}}
node_email{{"Email delivery<br/>external integration<br/>[sendMail.js]"}}
node_seeder["Data seeder<br/>development operation<br/>[seeder.js]"]
node_fixtures["Bootcamp fixtures<br/>seed data<br/>[bootcamps.json]"]
node_deployment["Vercel deployment<br/>deployment config<br/>[vercel.json]"]
end
node_deployment -.->|"deploys"| node_server
node_server -->|"mounts"| node_routes
node_server -->|"applies"| node_authz
node_server -->|"applies"| node_validation_errors
node_routes -->|"includes"| node_auth_routes
node_routes -->|"includes"| node_bootcamp_routes
node_routes -->|"dispatches through"| node_controllers
node_auth_routes -->|"dispatches"| node_auth
node_bootcamp_routes -->|"dispatches"| node_bootcamps
node_authz -->|"protects"| node_auth
node_authz -->|"authorizes"| node_users
node_results -->|"enriches queries"| node_bootcamps
node_controllers -->|"exports"| node_courses
node_controllers -->|"exports"| node_reviews
node_controllers -->|"exports"| node_users
node_bootcamps -->|"persists"| node_models
node_courses -->|"persists"| node_models
node_reviews -->|"persists"| node_models
node_users -->|"persists"| node_models
node_auth -->|"manages users"| node_models
node_models -->|"uses"| node_database
node_bootcamps -->|"geocodes writes"| node_geocoder
node_auth -->|"sends reset email"| node_email
node_seeder -->|"loads"| node_fixtures
node_seeder -->|"seeds"| node_database
click node_server "https://github.com/sourav-roy/apinodejs/blob/SOURAV/index.js"
click node_routes "https://github.com/sourav-roy/apinodejs/blob/SOURAV/routes/index.js"
click node_auth_routes "https://github.com/sourav-roy/apinodejs/blob/SOURAV/routes/authRoute.js"
click node_bootcamp_routes "https://github.com/sourav-roy/apinodejs/blob/SOURAV/routes/bootcampsRoute.js"
click node_controllers "https://github.com/sourav-roy/apinodejs/blob/SOURAV/controllers/index.js"
click node_authz "https://github.com/sourav-roy/apinodejs/blob/SOURAV/middleware/auth.js"
click node_results "https://github.com/sourav-roy/apinodejs/blob/SOURAV/middleware/advancedResults.js"
click node_validation_errors "https://github.com/sourav-roy/apinodejs/blob/SOURAV/middleware/validate.js"
click node_bootcamps "https://github.com/sourav-roy/apinodejs/blob/SOURAV/controllers/bootcampsController.js"
click node_courses "https://github.com/sourav-roy/apinodejs/blob/SOURAV/controllers/coursesController.js"
click node_reviews "https://github.com/sourav-roy/apinodejs/blob/SOURAV/controllers/reviewsController.js"
click node_users "https://github.com/sourav-roy/apinodejs/blob/SOURAV/controllers/usersController.js"
click node_auth "https://github.com/sourav-roy/apinodejs/blob/SOURAV/controllers/authController.js"
click node_models "https://github.com/sourav-roy/apinodejs/blob/SOURAV/models/BootcampModel.js"
click node_database "https://github.com/sourav-roy/apinodejs/blob/SOURAV/db/db.js"
click node_geocoder "https://github.com/sourav-roy/apinodejs/blob/SOURAV/utils/geocoder.js"
click node_email "https://github.com/sourav-roy/apinodejs/blob/SOURAV/utils/sendMail.js"
click node_seeder "https://github.com/sourav-roy/apinodejs/blob/SOURAV/seeder.js"
click node_fixtures "https://github.com/sourav-roy/apinodejs/blob/SOURAV/_data/bootcamps.json"
click node_deployment "https://github.com/sourav-roy/apinodejs/blob/SOURAV/vercel.json"
classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_server,node_routes,node_auth_routes,node_bootcamp_routes,node_controllers,node_authz,node_results,node_validation_errors toneBlue
class node_bootcamps,node_courses,node_reviews,node_users,node_auth,node_models,node_database toneAmber
class node_geocoder,node_email,node_seeder,node_fixtures,node_deployment toneMint
- Bootcamps: Create, read, update, and delete bootcamps.
- Courses: Manage courses associated with bootcamps.
- Reviews: Users can review bootcamps.
- Users & Authentication:
- JWT/ Cookie-based authentication.
- User roles (User, Publisher, Admin).
- Password reset and update profile.
- Geocoding: Calculate location and radius for bootcamps.
- File Upload: Upload photos for bootcamps.
- Security:
- Password encryption.
- Rate limiting.
- NoSQL injection protection.
- XSS protection.
- HPP protection.
- CORS enabled.
ISC