import type { HttpContext } from '@adonisjs/core/http' import { getMongoDb } from '#providers/mongodb_provider' import { verifyCwmpExchangesIndexes } from '#services/exchange_index_checker' import { ExchangeStoreService } from '#services/exchange_store_service' export default class HealthController { async checklife({ response }: HttpContext) { return response.json({ status: 'OK' }) } async checkservice({ response }: HttpContext) { try { const db = getMongoDb() await db.command({ ping: 1 }) const indexCheck = await verifyCwmpExchangesIndexes(db).catch(() => null) return response.json({ status: 'OK', version: '1.0.0', indexes: indexCheck ? { cwmp_exchanges: { allPresent: indexCheck.allPresent, indexes: indexCheck.indexes, }, } : undefined, }) } catch { return response.status(503).json({ status: 'KO', version: '1.0.0' }) } } /** * GET /api/v1/health/tr069-exchanges * * Health check endpoint for the TR-069 exchange viewer subsystem. * Reports: * - MongoDB connectivity and latency * - Active SSE connection count * - Collection stats (document count, size) * - Overall status: healthy / degraded / unhealthy * * Status logic: * - healthy: MongoDB connected, latency < 100ms, indexes present * - degraded: MongoDB connected but latency >= 100ms, or missing indexes * - unhealthy: MongoDB unreachable or ping fails */ async checkTr069Exchanges({ response }: HttpContext) { const timestamp = new Date().toISOString() let mongoConnected = false let latencyMs = -1 let collectionStats: { count: number; sizeMb: number } | null = null let indexCheck: Awaited> | null = null // Check MongoDB connectivity and measure latency try { const db = getMongoDb() const start = Date.now() await db.command({ ping: 1 }) latencyMs = Date.now() - start mongoConnected = true // Get collection stats const collection = db.collection('cwmp_exchanges') const count = await collection.estimatedDocumentCount() let sizeMb = 0 try { const stats = await db.command({ collStats: 'cwmp_exchanges' }) sizeMb = Math.round((stats.size / (1024 * 1024)) * 100) / 100 } catch { // Collection may not exist yet or collStats may not be available sizeMb = 0 } collectionStats = { count, sizeMb } // Check indexes indexCheck = await verifyCwmpExchangesIndexes(db) } catch { mongoConnected = false } // Get active SSE connection count const exchangeStore = ExchangeStoreService.getInstance() const activeConnections = exchangeStore.activeConnectionCount // Determine overall status let status: 'healthy' | 'degraded' | 'unhealthy' if (!mongoConnected) { status = 'unhealthy' } else if (latencyMs >= 100 || (indexCheck && !indexCheck.allPresent)) { status = 'degraded' } else { status = 'healthy' } const statusCode = status === 'unhealthy' ? 503 : 200 return response.status(statusCode).json({ status, mongodb: { connected: mongoConnected, latency_ms: latencyMs >= 0 ? latencyMs : null, collections: collectionStats ? { cwmp_exchanges: { count: collectionStats.count, size_mb: collectionStats.sizeMb, }, } : null, indexes: indexCheck ? { allPresent: indexCheck.allPresent, details: indexCheck.indexes, } : null, }, sse: { active_connections: activeConnections, }, timestamp, }) } }