# 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 ```bash cd backend npm install ``` ### Running Locally **Development mode (with hot reload):** ```bash npm run dev ``` The server starts on `http://localhost:3001` **Production mode:** ```bash npm run build npm start ``` ### Environment Variables Create a `.env` file in the backend directory: ```bash 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 logs - `logs/error.log` — Error-level logs only - Max file size: 5MB with 5 file rotation **Log Levels:** - `debug` — Development debugging info - `info` — General information events - `warn` — Warning conditions - `error` — 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:** ```bash 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:** ```bash 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):** ```json { "status": "healthy", "uptime": 3600, "timestamp": "2026-03-03T18:21:00.000Z", "database": { "connected": true, "responseTime": "15ms" } } ``` **Response (Degraded):** ```json { "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 status - `uptime` — Seconds since application started - `timestamp` — ISO 8601 timestamp of check - `database.connected` — Boolean database connectivity status - `database.responseTime` — Database query response time - `database.error` — Error message if connection failed (optional) --- ## Testing ```bash 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 ```bash docker build -t gravl-backend:latest . ``` ### Running in Container ```bash docker run -p 3001:3001 \ -e NODE_ENV=production \ -e DATABASE_URL=postgresql://... \ gravl-backend:latest ``` **Viewing logs from container:** ```bash 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 checks - **`scripts/build-check.sh`** — Verifies deployed container matches local git HEAD ### How to Deploy ```bash cd /workspace/gravl scripts/deploy.sh ``` ### Checking Deployment Status ```bash cd /workspace/gravl scripts/build-check.sh ``` For complete deployment documentation, see: **[`docs/DEPLOYMENT.md`](../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:** ```javascript // 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:** 1. **Port 3001 is already in use** ```bash lsof -i :3001 # Kill the conflicting process or use a different port ``` 2. **Backend code has a syntax error** ```bash npm run dev # Look for error messages in logs tail -f logs/error.log ``` 3. **Database connection is failing** - Backend is stuck trying to connect to DB - Check `DB_HOST`, `DB_PORT`, `DB_USER`, `DB_PASSWORD` in `.env` - Ensure database is running and accessible 4. **Logs directory not writable** ```bash mkdir -p logs chmod 755 logs ``` See **[`docs/DEPLOYMENT.md`](../docs/DEPLOYMENT.md#troubleshooting)** for more deployment troubleshooting. ### Checking Logs for Errors **Console (Development):** ```bash npm run dev # Full logs with colors ``` **Log Files:** ```bash 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:** ```bash docker logs gravl-backend | grep ERROR ``` --- ## Contributing See the root project README or CONTRIBUTING.md for guidelines on: - Code style ([CODING-CONVENTIONS.md](../docs/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*