Final Project – Asynchronous Server-Side Development Course
This project implements a Cost Manager RESTful Web Services system that enables managing users, costs, monthly reports, logs, and administrative information.
The system was developed according to the course requirements and follows a four-process architecture, allowing future separation into independent services or servers.
The project uses Node.js, Express.js, MongoDB Atlas, Mongoose, and Pino, and is fully deployed to the cloud.
- Node.js
- Express.js
- MongoDB Atlas
- Mongoose
- Render
- GitHub
- Pino Logger
- Jest
The project is divided into four independent processes, each responsible for a specific domain:
- Add new users
- Get details of a specific user
- List all users
- Add cost items
- Generate monthly reports
- Implements the Computed Design Pattern
- Logs every HTTP request
- Stores logs in MongoDB
- Returns development team details
- Data is not stored in the database
Each process runs separately and can be deployed independently.
-
Users Service
https://cost-manager-users-sgdp.onrender.com -
Costs Service
https://cost-manager-costs-ptc6.onrender.com -
Logs Service
https://cost-manager-logs-7cgb.onrender.com -
Admin Service
https://cost-manager-admin-otvg.onrender.com
- MongoDB Atlas (cloud-hosted)
- Collections:
- users
- costs
- logs
- report_cache
_idis stored in MongoDB but never returned in API responses- Supported categories:
- food
- health
- housing
- sports
- education
Monthly reports are cached only for past months.
Since the system does not allow adding cost items with past dates, cached reports are immutable and safe to reuse.
Reports for the current or future months are always generated dynamically.
-
GET /api/users
Returns all users -
GET /api/users/:id
Returns user details and total costs -
POST /api/add
Adds a new user. Send a JSON body (Content-Type: application/json) with:Field Type Required Notes idNumber yes Unique user id first_nameString yes last_nameString yes birthdayString (date) yes Any valid date, e.g. 1990-01-01{ "id": 123123, "first_name": "mosh", "last_name": "israeli", "birthday": "1990-01-01" }
-
POST /api/add
Adds a new cost item. Send a JSON body (Content-Type: application/json) with:Field Type Required Notes descriptionString yes categoryString yes One of: food,health,housing,sports,educationuseridNumber yes Must be an existing user id sumNumber yes Must be >= 0dateString (date) no Defaults to now; future dates are allowed, past dates are rejected { "description": "milk", "category": "food", "userid": 123123, "sum": 8 } -
GET /api/report?id=USER_ID&year=YYYY&month=MM
Returns a monthly cost report grouped by categories
- GET /api/logs
Returns all logged HTTP requests
- GET /api/about
Returns development team details
There are two ways to use the project: run the four services yourself, or call the services that are already deployed on Render.
- Install dependencies:
npm install - Create a
.envfile (use.env.exampleas a template). For a fully local run, setUSERS_SERVICE_URL=http://localhost:2001so the Costs service verifies users against your local Users service (not the deployed one). - Start each process in its own terminal:
npm run start:users # http://localhost:2001
npm run start:costs # http://localhost:2002
npm run start:logs # http://localhost:2003
npm run start:admin # http://localhost:2004The services are now reachable at http://localhost:PORT.
The four services are already deployed (see Deployed Services above), so no local setup is needed — just send HTTP requests to the Render URLs.
Note: free Render instances sleep after ~15 minutes of inactivity. The first request after a sleep can take 30–50 seconds while the service wakes up. Hit each
/healthendpoint first to wake all four before testing.
Unit tests were written for all endpoints using Jest (with supertest). They verify:
- Endpoint accessibility (
/health) - Basic request/response structure
- Validation handling (error responses)
Run the Jest suite:
npm testA Python end-to-end tester is also included at tests/test.py. It walks the full flow (about → report → add cost → report → user → logs):
python3 tests/test.pyBoth test sets target the deployed Render services by default. To point them at a local run instead, switch the base URLs to http://localhost:PORT (the local URLs are present as a commented-out block in tests/test.py).