A full-stack web application for tracking vehicle maintenance, built with Node.js, Express, MongoDB (native driver), and vanilla JavaScript (ES6) with a Bootstrap-styled, client-side-rendered frontend.
Live Website: https://garage-tracker.onrender.com/
Demo Video: https://youtu.be/IdhdJPowPLU
Garage Tracker is built for CS5610 Web Development at Northeastern University. It's for anyone who owns one or more vehicles and wants their maintenance history in one place instead of a glovebox full of receipts. Users add the vehicles they own and log each service performed on them; the app then shows useful summaries — total maintenance spend per vehicle, monthly spending, and which services are coming due based on mileage. It uses two linked MongoDB collections (Vehicles and Services), each with full CRUD, exposed through a REST API and rendered entirely in the browser.
- Home (
index.html): Landing page with an overview of the app and links to both feature pages. - Vehicles ("Your Garage") (
vehicles.html): Add, browse, search, and filter vehicles by status, make, and year; open a detail view with all of a car's info, a quick mileage-update control, and edit/delete. - Services (Maintenance History & Costs) (
services.html): Log services with a shop rating, filter history by vehicle/type/cost range/date range, edit/delete records, and view computed summary reports.
Vehicles
- Full CRUD — add, view, edit, and delete vehicles
- Filter by status, make, year, or free-text search (nickname/make/model)
- Detail panel with quick odometer update (PATCH endpoint — no full edit required)
- Cascade delete — removing a vehicle also removes all its service records
Services
- Full CRUD — log, edit, and delete maintenance records linked to a vehicle
- Filters: vehicle, service type, cost range, date range (combinable)
- Sortable table columns (vehicle, date, type, mileage, cost, shop, rating)
- "Other" service type requires a notes entry
- Both Red error and Green success highlight on form fields after a successful save or error
Summary Reports
- Spend by Vehicle — total cost and service count per vehicle, sortable
- Spend by Month — monthly totals with a year dropdown
- Due Soon — predicted next service by mileage; color-coded overdue / due-soon / ok; filterable by status and sortable by miles left
- Node.js + Express — REST API and static file server (ES modules)
- MongoDB (native Node.js driver) — two collections (
vehicles,services), no Mongoose - Vanilla JavaScript (ES6) — client-side rendering with the Fetch API
- HTML5 + CSS3 + Bootstrap 5 — semantic markup, per-page stylesheets
- ESLint + Prettier — code quality and formatting
This app runs locally against a MongoDB instance. We use MongoDB in Docker.
-
Clone and install
git clone https://github.com/kmpat339/garage-tracker.git cd garage-tracker npm install -
Start MongoDB (Docker, exposing the default port):
docker run -d --name garage-mongo -p 27017:27017 mongo
-
Set the connection string. Create a
.envfile in the project root:MONGODB_URI=mongodb://localhost:27017 -
Import sample data into MongoDB:
mongoimport --db garage --collection vehicles --file data/vehicles-backup.json --jsonArray mongoimport --db garage --collection services --file data/services-backup.json --jsonArray
The seed files include 300 vehicles and 700 service records — 1,000+ total records across the two collections.
-
Start the server:
npm run dev # watches for file changes (recommended during development) # or npm start # one-shot start (requires .env file in project root)
Render / production: set the start command to
npm run deploy— this runs without--env-fileso Render's injected environment variables are used directly. -
Open http://localhost:3000 in your browser.
garage-tracker/
├── server.js # Express entry point; serves frontend + mounts routes
├── db/
│ ├── vehiclesDb.js # All MongoDB access for the Vehicles collection
│ └── servicesDb.js # All MongoDB access for the Services collection
├── routes/
│ ├── vehicles.js # /api/vehicles routes (CRUD + filtering + mileage patch)
│ └── services.js # /api/services routes (CRUD + filters + summaries)
├── frontend/
│ ├── index.html # Homepage
│ ├── vehicles.html # Vehicles page
│ ├── services.html # Services page
│ ├── css/
│ │ ├── vehicles.css
│ │ └── services.css
│ └── js/
│ ├── vehicles.js
│ └── services.js
├── data/
│ ├── vehicles-backup.json # Sample vehicles data (import with mongoimport)
│ └── services-backup.json # Sample services data (import with mongoimport)
├── README.md
├── LICENSE # MIT
├── package.json
└── eslint.config.js
All endpoints return JSON.
| Method | Path | Description |
|---|---|---|
GET |
/api/vehicles |
List all vehicles (optional filters). |
POST |
/api/vehicles |
Create a vehicle. |
GET |
/api/vehicles/:id |
Get one vehicle by id. |
PUT |
/api/vehicles/:id |
Update a vehicle by id. |
PATCH |
/api/vehicles/:id/mileage |
Update only the current mileage. |
DELETE |
/api/vehicles/:id |
Delete a vehicle (and all its services) by id. |
Filters (query params on GET /api/vehicles, combinable)
?status=<status>— Active / In Repair / Garaged / Sold?make=<make>— only that make?year=<year>— only that year?q=<text>— search nickname, make, and model (case-insensitive)
| Method | Path | Description |
|---|---|---|
GET |
/api/services |
List all service records (optional filters). |
POST |
/api/services |
Create a service record. |
GET |
/api/services/:id |
Get one record by id. |
PUT |
/api/services/:id |
Replace a record by id. |
DELETE |
/api/services/:id |
Delete a record by id. |
Filters (query params on GET /api/services, combinable)
?vehicleId=<id>— only that vehicle's services?serviceType=<type>— only that service type?costMin=<n>&costMax=<n>— cost range (either end optional)?from=YYYY-MM-DD&to=YYYY-MM-DD— date range (either end optional)
Summary Reports
| Method | Path | Description |
|---|---|---|
GET |
/api/services/summary/by-vehicle |
Total spend and service count per vehicle. |
GET |
/api/services/summary/monthly |
Total spend and service count per month. |
GET |
/api/services/summary/due-soon |
Each vehicle's predicted next service by mileage (milesLeft, negative = overdue), most urgent first. |
Nipun Jayakumar — Garage Management feature (Vehicles) GitHub
Khush Patel — Maintenance History & Costs feature (Services) GitHub
This project was created as part of the Web Development Course (Summer 2026) at Northeastern University.
- Course: CS5610 Web Development — Northeastern University
- Instructor: John Alexis Guerra Gómez
- Design document: Design Document - Project 2 WebDev.pdf
- Slide deck: Google Slides
- Video presentation: (https://youtu.be/IdhdJPowPLU)
- Thumbnail image:

This section discloses where generative AI was used in this project. We used Claude Opus 4.8 model.
-
Seed data generation. Sample data for both collections was generated with Mockaroo. Claude was used to preprocess the mockaroo files so the vehicleId field in services had a matching ObjectId that existed in the Vehicles collection. Also, preprocessed it so each vehicle had 0-5 vehicles in some random distribution.
-
Scaffolding and debugging. Claude was used as a coding aid to scaffold and match the Vehicles and Services files and to help debug along the way. All decisions, validation rules, API design, and final code were reviewed and understood by the team.
-
Build guidance. Claude was used throughout the project to talk through Express/MongoDB concepts and review approach. All implementation choices were made and verified by the team.
This is a course project submission. External contributions are not accepted.
This project is licensed under the MIT License. See LICENSE for details.