Replace describe/before/it/expect() (Jest) with the node:test module and node:assert. All test logic, endpoints, and assertion semantics are preserved; the file now runs with: node --test backend/test/phase-06-tests.js Co-Authored-By: claude-flow <ruv@ruv.net>
Gravl Backend
Backend service for the Gravl exercise and fitness tracking platform.
Overview
The Gravl backend is a Node.js/Express application that provides:
- REST API for exercise data management
- User authentication and authorization
- Integration with frontend via HTTP
- Structured logging for monitoring and debugging
- Health check endpoint with system metrics for deployment monitoring
Local Development
Prerequisites
- Node.js 18+
- npm or yarn
- Docker & Docker Compose (for local container development)
Installation
cd backend
npm install
Running Locally
Development mode (with hot reload):
npm run dev
The server starts on http://localhost:3001
Production mode:
npm run build
npm start
Environment Variables
Create a .env file in the backend directory:
NODE_ENV=development
PORT=3001
DATABASE_URL=postgresql://user:password@localhost:5432/gravl
See .env.example (if available) for all supported variables.
Logging & Monitoring
Structured Logging (Winston)
The backend uses Winston for structured logging with multiple transports:
Console Output (Development):
- Human-readable format with timestamps and color coding
- Logs all INFO, WARN, ERROR, and DEBUG messages
File Output:
logs/combined.log— All application logslogs/error.log— Error-level logs only- Max file size: 5MB with 5 file rotation
Log Levels:
debug— Development debugging infoinfo— General information eventswarn— Warning conditionserror— Error conditions
Example Log Format:
2026-03-03 18:21:00 [info] User registered { userId: 42, email: user@example.com }
2026-03-03 18:21:15 [info] HTTP Request { method: 'GET', path: '/api/health', statusCode: 200, duration: '12ms' }
Request Logging Middleware
All HTTP requests are automatically logged with:
- HTTP method and path
- Response status code
- Request duration (milliseconds)
- Client IP address
- User-Agent
Example:
[info] HTTP Request { method: 'POST', path: '/api/logs', statusCode: 200, duration: '45ms' }
Accessing Logs
Local Development:
npm run dev # Logs print to console in real-time
tail -f logs/combined.log # Follow all logs
tail -f logs/error.log # Follow errors only
Docker Container:
docker logs -f gravl-backend # Real-time logs
docker logs --tail 100 gravl-backend # Last 100 lines
API Endpoints
Health Check (Monitoring & Deployment)
GET /api/health
Comprehensive health endpoint that returns system status, uptime, and database connectivity. Used by deployment scripts to verify backend is operational.
Response (Healthy):
{
"status": "healthy",
"uptime": 3600,
"timestamp": "2026-03-03T18:21:00.000Z",
"database": {
"connected": true,
"responseTime": "15ms"
}
}
Response (Degraded):
{
"status": "degraded",
"uptime": 3600,
"timestamp": "2026-03-03T18:21:00.000Z",
"database": {
"connected": false,
"error": "Connection timeout"
}
}
Status Values:
healthy— All systems operational (HTTP 200)degraded— Some systems degraded but functional (HTTP 200)unhealthy— Critical systems down (HTTP 503)
Response Fields:
status— Overall health statusuptime— Seconds since application startedtimestamp— ISO 8601 timestamp of checkdatabase.connected— Boolean database connectivity statusdatabase.responseTime— Database query response timedatabase.error— Error message if connection failed (optional)
Testing
npm test # Run all tests
npm run test:watch # Run tests in watch mode
Health & Logging Tests
The test suite includes:
- Health endpoint status validation
- Uptime tracking accuracy
- Database connectivity checking
- Request logging middleware functionality
- Error handling for database failures
Docker
Building the Image
docker build -t gravl-backend:latest .
Running in Container
docker run -p 3001:3001 \
-e NODE_ENV=production \
-e DATABASE_URL=postgresql://... \
gravl-backend:latest
Viewing logs from container:
docker logs -f gravl-backend
With Docker Compose
See the root docker-compose.yml for multi-container setup.
Deployment
Automated Deployment
The backend is deployed using scripts in the root scripts/ directory:
scripts/deploy.sh— Pulls latest code, builds fresh Docker image, starts container with health checksscripts/build-check.sh— Verifies deployed container matches local git HEAD
How to Deploy
cd /workspace/gravl
scripts/deploy.sh
Checking Deployment Status
cd /workspace/gravl
scripts/build-check.sh
For complete deployment documentation, see: docs/DEPLOYMENT.md
That guide includes:
- Prerequisites and setup
- How to run deploy.sh
- How to check build status
- Troubleshooting (health check failures, stale containers, etc.)
- Recovery procedures (rollbacks, cleanup)
Health Check Configuration
The backend exposes a comprehensive health check endpoint at GET /api/health. The deployment script (scripts/deploy.sh) waits up to 60 seconds for this endpoint to return HTTP 200.
In your backend code:
// Auto-integrated in src/index.js
app.get('/api/health', async (req, res) => {
const health = await getHealthStatus(pool);
const statusCode = health.status === 'healthy' ? 200 : 503;
res.status(statusCode).json(health);
});
Deployment timeout: 60 seconds (12 retries × 5 seconds)
- If this endpoint takes >5 seconds to respond, deployment will timeout
- Health check is lightweight and includes database connectivity test
Project Structure
backend/
├── src/
│ ├── index.js # Server entry point
│ ├── utils/
│ │ ├── logger.js # Winston logger configuration
│ │ └── health.js # Health monitoring utilities
│ ├── middleware/
│ │ └── requestLogger.js # HTTP request logging middleware
│ ├── routes/ # API endpoints
│ ├── controllers/ # Business logic
│ ├── models/ # Data models (if using ORM)
│ └── services/ # External integrations
├── test/ # Test files
├── logs/ # Log files (created at runtime)
├── Dockerfile # Container image definition
├── package.json # Dependencies
└── README.md # This file
Troubleshooting
Health Check Endpoint Not Responding
Symptom: Deployment fails with "Health check failed after 60s"
Causes & Fixes:
-
Port 3001 is already in use
lsof -i :3001 # Kill the conflicting process or use a different port -
Backend code has a syntax error
npm run dev # Look for error messages in logs tail -f logs/error.log -
Database connection is failing
- Backend is stuck trying to connect to DB
- Check
DB_HOST,DB_PORT,DB_USER,DB_PASSWORDin.env - Ensure database is running and accessible
-
Logs directory not writable
mkdir -p logs chmod 755 logs
See docs/DEPLOYMENT.md for more deployment troubleshooting.
Checking Logs for Errors
Console (Development):
npm run dev # Full logs with colors
Log Files:
tail -50 logs/combined.log # Last 50 lines of all logs
tail -50 logs/error.log # Last 50 lines of errors only
grep "ERROR" logs/combined.log # Find all error messages
Docker:
docker logs gravl-backend | grep ERROR
Contributing
See the root project README or CONTRIBUTING.md for guidelines on:
- Code style (CODING-CONVENTIONS.md)
- Testing requirements
- Pull request process
License
[Specify your license here]
Last updated: 2026-03-03 Phase 08-01: Health Monitoring & Logging Infrastructure