How elhajjame/subledger-api works
1. What this repo is
- This is a Node.js/Express REST API for subscription management, backed by MongoDB via Mongoose.
- The architecture is a classic layered API: HTTP routes → controllers → models → database, with authentication/authorization enforced in middleware.
2. Runtime entrypoints
- server.js is the likely process bootstrapper: it starts the HTTP server and connects to the configured runtime environment.
- app.js is the Express application composition layer: middleware, route registration, and app-wide setup live here.
3. Request routing boundary
- routes/userRoutes.js, routes/subscriptionRoutes.js, and the auth-related route wiring in the app split the API into functional areas.
- Routes are the main API boundary: they decide which controller handles each request and where auth/validation middleware is applied.
4. Controller layer
- controllers/authController.js handles authentication concerns such as sign-up and login.
- controllers/subscriptionController.js handles CRUD for subscriptions.
- controllers/userController.js covers user-related API behavior beyond auth itself.
- Controllers appear to own request/response handling and delegate persistence to models.
5. Data model layer
- models/User.js and models/Subscription.js define the persisted domain objects.
- The data model is centered on two core entities:
- User: identity, credentials, and role
- Subscription: subscription metadata plus ownership through userId
6. Authentication flow
- A user registers or logs in through auth endpoints.
- Passwords are hashed with bcrypt.
- Successful login issues a JWT, which becomes the access token used on protected routes.
- This creates a clear split between public auth routes and token-protected application routes.
7. Authorization flow
- middlewares/roleMiddleware.js enforces role-based access control.
- The repo supports at least two roles, User and Admin.
- Middleware sits between the route and controller layers, so authorization decisions are made before business logic runs.
8. Subscription domain flow
- Authenticated users can create, read, update, and delete subscriptions.
- Subscription records include name, price, billingCycle, timestamps, and a userId link back to the owner.
- That userId boundary is important: it scopes data access per user and prevents subscriptions from being treated as global records.
9. Validation boundary
- The project uses express-validator to enforce input rules at the API edge.
- Validation is applied before controller logic, covering fields like email, password, subscription name, price, and billing cycle.
- This keeps malformed requests from reaching the persistence layer.
10. Persistence and infrastructure
- MongoDB is the primary datastore, accessed through Mongoose models.
- config.env likely stores runtime configuration such as database connection settings, JWT secret, and server port.
- Dockerfile and compose.yaml indicate the API is container-friendly and can be run with a containerized app/database setup.
11. Testing structure
- tests/integration/ contains end-to-end API tests for login, signup, and subscriptions.
- tests/setup/setup.js provides test initialization and shared setup/teardown behavior.
- This suggests the repo validates the full request path: routing, middleware, controllers, and persistence.
12. Operational artifacts
- coverage/ contains generated test coverage output and is not part of runtime architecture.
- jest.config.cjs shows the project uses Jest for test execution.
13. How to draw the architecture
- A good diagram should show:
- External client → Express app
- Express routes → auth/user/subscription controllers
- Controllers → Mongoose models → MongoDB
- Route middleware in front of controllers for JWT auth and role checks
- Validation at the route boundary
- Separate auth flow from subscription management flow
Main entry points: app.js Express App · subscriptionRoutes.js Subscription Routes · server.js Server · User.js User Model
Components 17
Runtime/API
HTTP application bootstrap, routing, controllers, and request middleware.
- API Client · Any HTTP consumer of the REST API.
- Server · Process entrypoint that starts the app.
server.js - Express App · Express middleware and route wiring.
app.js - Auth Routes · Authentication-related request boundary.
routes/userRoutes.js - User Routes · User-focused API boundary.
routes/userRoutes.js - Subscription Routes · Subscription CRUD request boundary.
routes/subscriptionRoutes.js - Auth Controller · Handles signup, login, and token issuance.
controllers/authController.js - User Controller · Handles user API behavior.
controllers/userController.js - Subscription Controller · Handles subscription CRUD operations.
controllers/subscriptionController.js - Role Middleware · Enforces role-based access control.
middlewares/roleMiddleware.js
Domain/Data
Core persistence models and datastore boundary.
- User Model · User identity, credentials, and role schema.
models/User.js - Subscription Model · Subscription schema with owner linkage.
models/Subscription.js - MongoDB · Persistent document database.
Tests
Integration test harness and end-to-end API coverage.
- Integration Tests · End-to-end API tests for auth and subscriptions.
tests/integration - Test Setup · Shared test initialization and teardown.
tests/setup/setup.js
Ops
Container and runtime configuration artifacts.
- Compose · Containerized app/database runtime definition.
compose.yaml - Dockerfile · Container image build definition.
Dockerfile
Connections 19
- API Client → Express App: HTTP requests · Clients call the Express application.
- Server → Express App: starts · Server bootstraps the Express app.
- Express App → Auth Routes: mounts · Registers auth-related routes.
- Express App → User Routes: mounts · Registers user routes.
- Express App → Subscription Routes: mounts · Registers subscription routes.
- Auth Routes → Auth Controller: dispatches to · Auth routes delegate to controller handlers.
- User Routes → User Controller: dispatches to · User routes delegate to controller handlers.
- Subscription Routes → Role Middleware: protects with · Role checks are applied before protected handlers.
- Subscription Routes → Subscription Controller: dispatches to · Subscription routes delegate to controller handlers.
- Auth Controller → User Model: uses · Auth flow reads and creates users.
- User Controller → User Model: uses · User API operates on user records.
- Subscription Controller → Subscription Model: uses · Subscription API operates on subscription records.
- User Model → MongoDB: persists to · User documents are stored in MongoDB.
- Subscription Model → MongoDB: persists to · Subscription documents are stored in MongoDB.
- Test Setup → Integration Tests: prepares · Shared setup supports integration tests.
- Integration Tests → Express App: exercises · Integration tests drive the HTTP application path.
- Compose → Server: runs · Compose can start the API container.
- Compose → MongoDB: provisions · Compose defines the database runtime.
- Dockerfile → Server: packages · Docker image contains the API process.