A comprehensive Node.js API for tracking cargo shipments with real-time location updates, geospatial queries, and ETA calculations. Built as part of the MERN Stack Tracking Assignment.
This project implements a complete Track Fleet backend using Node.js, Express, and MongoDB with all required features:
- CRUD Operations: Complete RESTful API endpoints for shipment management
- Data Modeling: Comprehensive shipment schema with nested documents and geospatial data
- Geospatial Support: MongoDB 2dsphere indexes for location-based queries
- ETA Calculation: Intelligent algorithms considering route, distance, and current location
- Location History: Track all checkpoint updates with timestamps
- Docker Support: Full containerization with Docker Compose for easy deployment
- Error Handling: Comprehensive error middleware with detailed validation
- Logging: Winston logger for production monitoring
- Security: Helmet, CORS, and input sanitization
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/shipments |
Retrieve all shipments with pagination support |
| GET | /api/shipments/:trackingNumber |
Get specific shipment by tracking number |
| POST | /api/shipments |
Create a new shipment |
| PUT | /api/shipments/:trackingNumber |
Update shipment details |
| DELETE | /api/shipments/:trackingNumber |
Delete a shipment |
| Method | Endpoint | Description |
|---|---|---|
| PATCH | /api/shipments/:trackingNumber/location |
Update current location |
| PATCH | /api/shipments/:trackingNumber/status |
Update shipment status |
| POST | /api/shipments/:trackingNumber/checkpoints |
Add a new checkpoint |
| PATCH | /api/shipments/:trackingNumber/checkpoints/:checkpointId |
Update a checkpoint |
| DELETE | /api/shipments/:trackingNumber/checkpoints/:checkpointId |
Delete a checkpoint |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/shipments/:trackingNumber/eta |
Get estimated delivery time |
| GET | /api/shipments/:trackingNumber/history |
Get full location history |
| GET | /api/shipments/:trackingNumber/distance |
Get route distance |
| GET | /api/shipments/nearby |
Find shipments near a location |
| POST | /api/shipments/seed |
Seed database with sample data |
| POST | /api/shipments/seed/india |
Seed with India-specific data |
| Method | Endpoint | Description |
|---|---|---|
| GET | /health |
Health check endpoint |
{
trackingNumber: { // Unique tracking identifier (required)
type: String,
required: true,
unique: true
},
containerId: { // Container identifier
type: String,
required: true
},
status: { // Current shipment status
type: String,
enum: ['pending', 'in_transit', 'out_for_delivery', 'delivered', 'exception'],
default: 'pending'
},
origin: { // Origin location
type: {
type: String,
enum: ['Point'],
default: 'Point'
},
coordinates: { // [longitude, latitude]
type: [Number],
required: true,
index: '2dsphere'
},
address: String
},
destination: { // Destination location
type: {
type: String,
enum: ['Point'],
default: 'Point'
},
coordinates: { // [longitude, latitude]
type: [Number],
required: true,
index: '2dsphere'
},
address: String
},
currentLocation: { // Current location
type: {
type: String,
enum: ['Point'],
default: 'Point'
},
coordinates: { // [longitude, latitude]
type: [Number],
index: '2dsphere'
},
address: String,
timestamp: Date
},
route: [{ // Route waypoints
location: {
type: {
type: String,
enum: ['Point'],
default: 'Point'
},
coordinates: [Number, Number],
address: String
},
estimatedArrival: Date,
order: Number
}],
checkpoints: [{ // Checkpoint history
location: {
type: {
type: String,
enum: ['Point'],
default: 'Point'
},
coordinates: [Number, Number],
address: String
},
status: String,
notes: String,
timestamp: {
type: Date,
default: Date.now
}
}],
currentEta: { // Current estimated delivery date
type: Date
},
distance: { // Total distance in kilometers
type: Number,
default: 0
},
deliveredAt: Date, // Delivery timestamp
estimatedDelivery: Date, // Original estimated delivery
weight: Number, // Shipment weight in kg
dimensions: { // Package dimensions
length: Number,
width: Number,
height: Number,
unit: { type: String, default: 'cm' }
},
customerInfo: { // Customer details
name: String,
email: String,
phone: String,
address: String
},
createdAt: {
type: Date,
default: Date.now
},
updatedAt: {
type: Date,
default: Date.now
}
}trackingNumber: Unique index for fast lookupsorigin.coordinates: 2dsphere for origin queriesdestination.coordinates: 2dsphere for destination queriescurrentLocation.coordinates: 2dsphere for location updates
- Node.js (v18+) - JavaScript runtime
- Express (v4.18+) - Web framework
- MongoDB (v6.0+) - NoSQL database
- Mongoose (v7.0+) - ODM for MongoDB
- Helmet - Security headers
- CORS - Cross-origin resource sharing
- Express Validator - Input validation
- Rate Limiter - API rate limiting
- Nodemon - Hot reload for development
- Winston - Logging
- Dotenv - Environment variable management
- ESLint - Code linting
- Prettier - Code formatting
- Docker & Docker Compose - Containerization
- Render - Deployment
- GitHub Actions - CI/CD
- Node.js (v18 or later)
- Docker (optional, for containerized deployment)
- MongoDB Atlas account or local MongoDB installation
- Git
Create a .env file in the root directory:
# Server Configuration
NODE_ENV=development
PORT=5000
HOST=0.0.0.0
# Database Configuration
MONGO_URI=mongodb+srv://<username>:<password>@<cluster>.mongodb.net/trackfleet?retryWrites=true&w=majority
MONGO_OPTIONS='{"useNewUrlParser":true,"useUnifiedTopology":true}'
# Security
JWT_SECRET=your_jwt_secret_key_here
JWT_EXPIRES_IN=7d
# Rate Limiting
RATE_LIMIT_WINDOW=15
RATE_LIMIT_MAX=100
# CORS
CORS_ORIGIN=http://localhost:3000
# Logging
LOG_LEVEL=info
LOG_FILE=logs/app.log# Clone the repository
git clone https://github.com/Codewithakk/TrackFleet.git
cd TrackFleet
# Install dependencies
npm install
# Create .env file with your configuration
cp .env.example .env
# Edit .env with your actual values
# Start development server with auto-reload
npm run dev
# Or start production server
npm start# Clone the repository
git clone https://github.com/Codewithakk/TrackFleet.git
cd TrackFleet
# Create .env file
cp .env.example .env
# Edit .env with your actual values
# Build and run with Docker Compose
docker-compose up -d --build
# Or use the deployment script
chmod +x docker-deploy.sh
./docker-deploy.shTrackFleet/
βββ src/
β βββ config/
β β βββ database.js # MongoDB connection
β β βββ logger.js # Winston logger configuration
β β βββ redis.js # Redis configuration (optional)
β βββ controllers/
β β βββ shipment.controller.js
β β βββ health.controller.js
β βββ middleware/
β β βββ error.middleware.js
β β βββ auth.middleware.js
β β βββ validation.middleware.js
β β βββ rateLimiter.js
β βββ models/
β β βββ shipment.model.js # Shipment schema
β βββ routes/
β β βββ shipment.routes.js
β β βββ health.routes.js
β βββ services/
β β βββ shipment.service.js
β β βββ location.service.js
β βββ utils/
β β βββ location.utils.js
β β βββ eta.utils.js
β β βββ validators.js
β βββ server.js # Application entry point
βββ tests/
β βββ unit/
β βββ integration/
β βββ e2e/
βββ logs/ # Application logs
βββ .env.example # Example environment variables
βββ .dockerignore
βββ docker-compose.yml # Docker Compose configuration
βββ Dockerfile # Docker image configuration
βββ package.json
βββ package-lock.json
βββ postman-collection.json # API testing collection
βββ README.md
βββ LICENSE
# Build and start all services (API + MongoDB)
docker-compose up -d --build
# Start without rebuilding
docker-compose up -d
# Build only the API service
docker-compose build api
# Start a specific service
docker-compose up -d api# View running containers
docker ps
# View container logs (all services)
docker-compose logs -f
# View logs for a specific service
docker-compose logs -f api
# View logs for MongoDB
docker-compose logs -f mongodb
# Check container health
curl http://localhost:5000/health
# Get container stats
docker stats
# Inspect MongoDB data
docker exec -it trackfleet-mongo mongosh# Stop containers
docker-compose down
# Stop containers and remove volumes (deletes database data)
docker-compose down -v
# Stop containers, remove volumes, and images
docker-compose down -v --rmi all
# Clean up unused Docker resources
docker system prune -a --volumes# Check if services are healthy
docker-compose ps
# Test API endpoint
curl http://localhost:5000/health
# Access MongoDB shell
docker exec -it trackfleet-mongo mongosh --eval "db.runCommand({ ping: 1 })"
# Check container logs for errors
docker-compose logs --tail=100 api
# Rebuild after code changes
docker-compose up -d --build --force-recreatePOST /api/shipments
Content-Type: application/json
{
"trackingNumber": "TRK123456",
"containerId": "CONT9876",
"origin": {
"coordinates": [77.2167, 28.6139],
"address": "New Delhi, India"
},
"destination": {
"coordinates": [72.8777, 19.0760],
"address": "Mumbai, India"
},
"customerInfo": {
"name": "John Doe",
"email": "john@example.com",
"phone": "+1234567890"
},
"weight": 15.5,
"dimensions": {
"length": 30,
"width": 20,
"height": 15
}
}PATCH /api/shipments/TRK123456/location
Content-Type: application/json
{
"coordinates": [75.8577, 26.9124],
"address": "Jaipur, Rajasthan",
"status": "in_transit"
}GET /api/shipments/TRK123456GET /api/shipments/TRK123456/etaGET /api/shipments/TRK123456/history-
Connect GitHub Repository
- Go to Render Dashboard
- Click "New Web Service"
- Connect your GitHub account and select the repository
-
Configure Service
Name: trackfleet-api Environment: Node Build Command: npm install Start Command: npm start
-
Add Environment Variables
NODE_ENV: productionPORT: 5000MONGO_URI: Your MongoDB Atlas URI- All other required variables from
.env.example
-
Deploy
- Click "Create Web Service"
- Render will automatically build and deploy
# Install PM2 for process management
npm install -g pm2
# Build and start the application
npm install --production
pm2 start src/server.js --name trackfleet
# Save PM2 configuration
pm2 save
pm2 startupNODE_ENV=development
LOG_LEVEL=debugNODE_ENV=production
LOG_LEVEL=info
RATE_LIMIT_ENABLED=true# Run unit tests
npm test
# Run integration tests
npm run test:integration
# Run tests with coverage
npm run test:coverage
# Run specific test file
npm test -- tests/unit/shipment.test.js- Database Indexing: All geospatial fields are indexed with 2dsphere
- Query Optimization: Projection queries for reduced data transfer
- Caching: Redis support for frequently accessed data (optional)
- Rate Limiting: Prevent abuse with configurable rate limits
- Compression: Gzip compression for API responses
- Connection Pooling: MongoDB connection pooling for better performance
- Helmet.js: Secure HTTP headers
- CORS: Configurable CORS policies
- Input Validation: Express-validator for all inputs
- XSS Protection: Input sanitization
- Rate Limiting: Prevent brute force attacks
- JWT Authentication: Optional JWT implementation
- Environment Variables: All sensitive data in .env
- Geospatial Data: MongoDB Atlas with 2dsphere indexing is used for location queries
- ETA Calculation: Based on average speed and remaining distance
- Unique Identifiers: Each shipment has unique trackingNumber and containerId
- Location Format: Coordinates are in [longitude, latitude] format
- Timezone: All timestamps are in UTC
- Database: MongoDB Atlas is used in production, local MongoDB for development
- Fork the repository
- Create a feature branch (
git checkout -b feature/AmazingFeature) - Commit changes (
git commit -m 'Add AmazingFeature') - Push to branch (
git push origin feature/AmazingFeature) - Open a Pull Request
- MongoDB for the excellent geospatial features
- Express.js community for the robust framework
- Docker for making deployment seamless
- Render for hosting the API
Built with β€οΈ for the MERN Stack Tracking Assignment