const express = require("express"); const router = express.Router(); const { sequelize } = require("../models"); const s3Service = require("../services/s3Service"); const logger = require("../utils/logger"); /** * Health check endpoint for load balancers and monitoring * GET /health * * Returns: * - 200: All services healthy * - 503: One or more services unhealthy */ router.get("/", async (req, res) => { const startTime = Date.now(); const checks = { database: { status: "unknown", latency: null }, s3: { status: "unknown", latency: null }, }; let allHealthy = true; // Database health check try { const dbStart = Date.now(); await sequelize.authenticate(); checks.database = { status: "healthy", latency: Date.now() - dbStart, }; } catch (error) { allHealthy = false; checks.database = { status: "unhealthy", error: error.message, latency: Date.now() - startTime, }; logger.error("Health check: Database connection failed", { error: error.message, }); } // S3 health check (if enabled) if (s3Service.isEnabled()) { try { const s3Start = Date.now(); // S3 is considered healthy if it's properly initialized // A more thorough check could list bucket contents, but that adds latency checks.s3 = { status: "healthy", latency: Date.now() - s3Start, bucket: process.env.S3_BUCKET, }; } catch (error) { allHealthy = false; checks.s3 = { status: "unhealthy", error: error.message, latency: Date.now() - startTime, }; logger.error("Health check: S3 check failed", { error: error.message, }); } } else { checks.s3 = { status: "disabled", latency: 0, }; } // Log unhealthy states if (!allHealthy) { logger.warn("Health check failed", { checks }); } res.status(allHealthy ? 200 : 503).json({ status: allHealthy ? "healthy" : "unhealthy", }); }); /** * Liveness probe - simple check that the process is running * GET /health/live * * Used by Kubernetes/ECS for liveness probes * Returns 200 if the process is alive */ router.get("/live", (req, res) => { res.status(200).json({ status: "alive", timestamp: new Date().toISOString(), }); }); /** * Readiness probe - check if the service is ready to accept traffic * GET /health/ready * * Used by load balancers to determine if instance should receive traffic * Checks critical dependencies (database) */ router.get("/ready", async (req, res) => { try { await sequelize.authenticate(); res.status(200).json({ status: "ready", timestamp: new Date().toISOString(), }); } catch (error) { logger.error("Readiness check failed", { error: error.message, stack: error.stack }); res.status(503).json({ status: "not_ready", timestamp: new Date().toISOString(), error: "Database connection failed", }); } }); module.exports = router;