How farhanasfar/subscription-management-api works
1. Overall shape
- This is a Node.js/Express REST API backed by MongoDB via Mongoose.
- The repository is organized in a classic layered style: routes → controllers → models, with shared middlewares, utils, and docs around that core.
2. Application entry and bootstrapping
- index.js and app.js are the top-level runtime entry points.
- The bootstrap path likely handles environment setup, Express initialization, middleware registration, route mounting, error handling, and server startup.
- db/index.js is the database connection boundary to MongoDB.
3. Request routing layer
- The routes/ folder splits the API into four bounded areas:
- auth.routes.js
- user.routes.js
- subscription.routes.js
- admin.routes.js
- This is the first architectural boundary after HTTP ingress: requests are classified by domain and forwarded to the relevant controller.
4. Domain controllers
- controllers/ contains the application logic for each area:
- auth.controller.js handles signup/signin/signout and session/token behavior.
- user.controller.js handles profile/account management and password changes.
- subscription.controller.js handles creating, listing, and cancelling subscriptions.
- admin.controller.js supports role-based admin operations.
- Controllers are the main orchestration layer: they validate intent, call models, shape responses, and rely on shared error utilities.
5. Data model layer
- models/ contains the MongoDB schemas/entities:
- user.model.js
- subscription.model.js
- admin.model.js
- These are the persistence boundary for the system. The API’s state is stored in MongoDB, and business behavior is expressed through these Mongoose models.
6. Authentication and authorization
- middlewares/auth.middleware.js is the security gate for protected routes.
- The README indicates JWT-based authentication and role-based access control (RBAC), so the auth middleware is the key boundary separating public endpoints from authenticated user/admin flows.
- Password handling uses bcrypt; token issuance/validation uses JWT.
7. Error and async handling
- middlewares/error.middleware.js centralizes error translation and HTTP responses.
- utils/asyncHandler.js suggests controllers are wrapped to avoid repetitive try/catch logic and to route async failures into the global error middleware.
- utils/ApiError.js and utils/ApiResponse.js define the repo’s standard error/response contracts, which is important for diagramming the API’s output shape.
8. API documentation surface
- docs/openapi.js and the docs/paths/ files define the OpenAPI/Swagger contract.
- Documented endpoints mirror the route domains: auth, user, and subscription.
- Swagger is a parallel contract layer, not runtime logic, but it matters because it describes the external API boundary and expected request/response structures.
9. Testing boundary
- tests/integration/ contains end-to-end style tests using Jest + Supertest.
- tests/setup.js likely prepares the test database/app lifecycle.
- The tests focus on API behavior across the HTTP boundary, especially auth and user flows, which makes them useful for validating route/controller/middleware integration.
10. Deployment and runtime packaging
- Dockerfile and docker-compose.yml show the service is containerized for local and production-style deployment.
- The README says it is deployed on Render and the Docker image is published to Docker Hub.
- CI/CD is driven by GitHub Actions:
- build.yml runs dependency installation and tests.
- deploy.yml builds and pushes the image on main.
11. External services and config
- The app depends on MongoDB as its primary datastore.
- Runtime configuration is environment-driven via .env, including PORT, MONGODB_URI, JWT_SECRET, and optional CLOUDINARY_URL.
- Cloudinary is only mentioned as optional for user profile images, so it is an auxiliary external integration rather than a core subsystem.
12. Primary data flows
- Public auth flow: client → auth route → auth controller → user model/MongoDB → JWT response.
- Authenticated user flow: client → auth middleware → user/subscription route → controller → model/MongoDB → standardized response.
- Admin flow: client → auth middleware with role checks → admin route/controller → model/MongoDB.
- Failure flow: any async/controller/model error → async handler/error middleware → standardized API error response.
13. What to emphasize in an architecture diagram
- Show the API as a single Express service with four domain route groups.
- Put MongoDB as the main persistence store behind Mongoose models.
- Highlight auth middleware as the central guard for protected endpoints.
- Show Swagger/OpenAPI as a documentation plane alongside the service.
- Show Docker/GitHub Actions/Render as the delivery pipeline around the application, not inside the request path.
Main entry points: app.js App setup · subscription.controller.js Sub controller · asyncHandler.js Async handler · auth.controller.js Auth controller
Components 26
API runtime
Express service bootstrap, request handling, and persistence
- Server entry · Process entrypoint that starts the application
index.js - App setup · Express application wiring, middleware, and route mounting
app.js - DB connect · MongoDB connection boundary
db/index.js
Domain layer
Routes, controllers, and models for core API behaviors
- Auth routes · HTTP routes for signup, signin, and signout
routes/auth.routes.js - User routes · HTTP routes for profile and account actions
routes/user.routes.js - Sub routes · HTTP routes for subscription lifecycle actions
routes/subscription.routes.js - Admin routes · HTTP routes for role-based admin operations
routes/admin.routes.js - Auth controller · Authentication orchestration and token/session handling
controllers/auth.controller.js - User controller · Profile and account management logic
controllers/user.controller.js - Sub controller · Subscription creation, listing, and cancellation
controllers/subscription.controller.js - Admin controller · Administrative operations and privileged workflows
controllers/admin.controller.js - User model · User schema and persistence behavior
models/user.model.js - Subscription model · Subscription schema and persistence behavior
models/subscription.model.js - Admin model · Admin schema and persistence behavior
models/admin.model.js
Support
Security, error handling, utilities, and docs
- Auth guard · JWT authentication and role-based access control
middlewares/auth.middleware.js - Error handler · Global HTTP error translation and response handling
middlewares/error.middleware.js - Async handler · Wraps async controller logic and forwards failures
utils/asyncHandler.js - API error · Standard application error shape
utils/ApiError.js - API response · Standard success response shape
utils/ApiResponse.js - OpenAPI · Swagger/OpenAPI root contract
docs/openapi.js
Delivery
Testing, containerization, and CI/CD
- Test setup · Integration test lifecycle and environment setup
tests/setup.js - API tests · End-to-end HTTP tests for auth and user flows
tests/integration/auth.test.js - Dockerfile · Image build definition
Dockerfile - Compose · Local multi-service orchestration
docker-compose.yml - Build CI · GitHub Actions workflow for install and test
.github/workflows/build.yml - Deploy CI · GitHub Actions workflow for build and image publish
.github/workflows/deploy.yml
Connections 37
- Server entry → App setup: starts · Server entry boots the Express app
- App setup → DB connect: connects · App initialization depends on MongoDB connection
- App setup → Auth routes: mounts · Express mounts the auth route group
- App setup → User routes: mounts · Express mounts the user route group
- App setup → Sub routes: mounts · Express mounts the subscription route group
- App setup → Admin routes: mounts · Express mounts the admin route group
- Auth routes → Auth guard: protects · Protected auth endpoints pass through security middleware
- User routes → Auth guard: protects · Protected user endpoints require JWT and roles
- Sub routes → Auth guard: protects · Subscription endpoints are gated by auth middleware
- Admin routes → Auth guard: protects · Admin endpoints are restricted by role checks
- Auth routes → Auth controller: delegates · Auth routes delegate request handling to controller logic
- User routes → User controller: delegates · User routes delegate request handling to controller logic
- Sub routes → Sub controller: delegates · Subscription routes delegate request handling to controller logic
- Admin routes → Admin controller: delegates · Admin routes delegate request handling to controller logic
- Auth controller → User model: reads/writes · Auth flow persists and looks up user records
- User controller → User model: reads/writes · User flow operates on user records
- Sub controller → Subscription model: reads/writes · Subscription flow operates on subscription records
- Admin controller → Admin model: reads/writes · Admin flow operates on admin records
- Sub controller → User model: reads/writes · Subscriptions are associated with users
- Auth controller → Async handler: wraps · Async controller actions are funneled through the helper
- User controller → Async handler: wraps · Async controller actions are funneled through the helper
- Sub controller → Async handler: wraps · Async controller actions are funneled through the helper
- Admin controller → Async handler: wraps · Async controller actions are funneled through the helper
- Async handler → Error handler: forwards · Unhandled async failures reach the global error middleware
- Error handler → API error: formats · Errors are normalized into the standard error contract
- Auth controller → API response: formats · Successful auth responses use the standard response contract
- User controller → API response: formats · Successful user responses use the standard response contract
- Sub controller → API response: formats · Successful subscription responses use the standard response contract
- Admin controller → API response: formats · Successful admin responses use the standard response contract
- OpenAPI → Auth routes: documents · OpenAPI documents the auth API surface
- OpenAPI → User routes: documents · OpenAPI documents the user API surface
- OpenAPI → Sub routes: documents · OpenAPI documents the subscription API surface
- Test setup → API tests: supports · Shared setup prepares integration test execution
- API tests → App setup: exercises · Integration tests drive the HTTP app boundary
- Build CI → API tests: runs · CI workflow installs dependencies and executes tests
- Deploy CI → Dockerfile: builds · Deploy workflow builds the container image
- Deploy CI → Compose: orchestrates · Deployment packaging is defined for containerized runtime