import { NextRequest, NextResponse } from 'next/server'; /** * Health check endpoint for network status detection and monitoring * Returns 200 OK when the app is healthy * Supports detailed health checks with ?detailed=true */ export async function GET(request: NextRequest) { const startTime = Date.now(); // Basic health check response const basicHealth = { status: 'healthy', timestamp: new Date().toISOString(), version: process.env.APP_VERSION || process.env.NEXT_PUBLIC_APP_VERSION || 'unknown', environment: process.env.NODE_ENV || 'unknown', }; // Check for detailed health check const isDetailed = request.nextUrl.searchParams.get('detailed') === 'true'; if (!isDetailed) { return NextResponse.json(basicHealth, { status: 200 }); } // Detailed health check const checks: Record = {}; // Check memory usage const memUsage = process.memoryUsage(); const memoryHealthy = memUsage.heapUsed < 150 * 1024 * 1024; // 150MB threshold checks.memory = { status: memoryHealthy ? 'healthy' : 'warning', heapUsed: Math.round(memUsage.heapUsed / 1024 / 1024) + 'MB', heapTotal: Math.round(memUsage.heapTotal / 1024 / 1024) + 'MB', rss: Math.round(memUsage.rss / 1024 / 1024) + 'MB', }; // Check API connectivity try { const apiUrl = process.env.NEXT_PUBLIC_API_URL || 'https://api.parentflowapp.com'; const controller = new AbortController(); const timeoutId = setTimeout(() => controller.abort(), 5000); const apiStart = Date.now(); const apiResponse = await fetch(`${apiUrl}/health`, { signal: controller.signal, cache: 'no-cache', }); clearTimeout(timeoutId); checks.api = { status: apiResponse.ok ? 'healthy' : 'unhealthy', statusCode: apiResponse.status, responseTime: `${Date.now() - apiStart}ms`, url: apiUrl, }; } catch (error) { checks.api = { status: 'unhealthy', error: error instanceof Error ? error.message : 'Unknown error', }; } // Check build info checks.build = { version: process.env.APP_VERSION || process.env.NEXT_PUBLIC_APP_VERSION || 'unknown', nodeVersion: process.version, uptime: Math.round(process.uptime()) + 's', }; // Overall health status const overallHealthy = memoryHealthy && checks.api?.status === 'healthy'; return NextResponse.json( { ...basicHealth, status: overallHealthy ? 'healthy' : 'degraded', checks, responseTime: `${Date.now() - startTime}ms`, }, { status: overallHealthy ? 200 : 503 } ); } // Kubernetes liveness probe export async function HEAD() { return new NextResponse(null, { status: 200 }); }