import { NextResponse } from 'next/server'; import { getRedisClient } from '@/lib/redis'; import { prisma } from '@/lib/prisma'; import { logger } from '@/lib/logger'; /** * Health check endpoint * * Vérifie la santé de l'application et de ses dépendances: * - Base de données PostgreSQL * - Redis (si configuré) * * Usage: * GET /api/health * * Réponses: * 200: Tous les services sont opérationnels * 503: Un ou plusieurs services sont indisponibles */ export async function GET() { const startTime = Date.now(); const checks: Record = {}; let overallStatus: 'ok' | 'degraded' | 'down' = 'ok'; // Vérifier PostgreSQL try { const dbStart = Date.now(); await prisma.$queryRaw`SELECT 1`; const dbLatency = Date.now() - dbStart; checks.database = { status: 'ok', latency: dbLatency, }; } catch (error) { logger.error('[HEALTH] Database check failed', { error: error instanceof Error ? error.message : String(error), }); checks.database = { status: 'error', message: error instanceof Error ? error.message : 'Unknown error', }; overallStatus = 'degraded'; } // Vérifier Redis (optionnel) try { const redis = getRedisClient(); const redisStart = Date.now(); await redis.ping(); const redisLatency = Date.now() - redisStart; checks.redis = { status: 'ok', latency: redisLatency, }; } catch (error) { logger.warn('[HEALTH] Redis check failed', { error: error instanceof Error ? error.message : String(error), }); // Redis n'est pas critique, donc on ne change pas le statut global checks.redis = { status: 'error', message: error instanceof Error ? error.message : 'Unknown error', }; } const totalLatency = Date.now() - startTime; const response = { status: overallStatus, timestamp: new Date().toISOString(), uptime: process.uptime(), checks, latency: totalLatency, }; const statusCode = overallStatus === 'ok' ? 200 : 503; return NextResponse.json(response, { status: statusCode }); }