import { NextResponse } from 'next/server'; import { getDb } from '@/lib/db'; export const dynamic = 'force-dynamic'; type TimeRange = '24h' | '7d' | '30d' | '365d'; const RANGE_CONFIG: Record = { '24h': { sqlOffset: '-24 hours', strftime: '%Y-%m-%d %H:00', bars: 24 }, '7d': { sqlOffset: '-7 days', strftime: '%Y-%m-%d', bars: 7 }, '30d': { sqlOffset: '-30 days', strftime: '%Y-%m-%d', bars: 30 }, '365d': { sqlOffset: '-365 days', strftime: '%Y-%m', bars: 12 }, }; export async function GET(request: Request) { try { const db = await getDb(); const { searchParams } = new URL(request.url); const range = (searchParams.get('range') || '24h') as TimeRange; const config = RANGE_CONFIG[range] || RANGE_CONFIG['24h']; // Get live status (most recent log per service) const live = await db.all(` SELECT service_name as name, url, status, latency FROM uptime_logs WHERE id IN (SELECT MAX(id) FROM uptime_logs GROUP BY service_name) `); // Get 24h stats const stats24h = await db.all(` SELECT service_name, count(*) as total, sum(case when status = 'up' then 1 else 0 end) as up_count FROM uptime_logs WHERE timestamp > datetime('now', '-24 hours') GROUP BY service_name `); // Get 7d stats const stats7d = await db.all(` SELECT service_name, count(*) as total, sum(case when status = 'up' then 1 else 0 end) as up_count FROM uptime_logs WHERE timestamp > datetime('now', '-7 days') GROUP BY service_name `); // Get lifetime stats (all available data) const statsLifetime = await db.all(` SELECT service_name, count(*) as total, sum(case when status = 'up' then 1 else 0 end) as up_count FROM uptime_logs GROUP BY service_name `); // Get average latency over last 24h (only for 'up' checks) const avgLatencyRows = await db.all(` SELECT service_name, ROUND(AVG(latency)) as avg_latency FROM uptime_logs WHERE timestamp > datetime('now', '-24 hours') AND status = 'up' AND latency > 0 GROUP BY service_name `); // Get bucketed history for the requested range const history = await db.all(` SELECT service_name, strftime('${config.strftime}', timestamp) as bucket, count(*) as total, sum(case when status = 'up' then 1 else 0 end) as up_count FROM uptime_logs WHERE timestamp > datetime('now', '${config.sqlOffset}') GROUP BY service_name, bucket ORDER BY bucket ASC `); // Group history by service — return up_count and total per bucket const historyMap: Record> = {}; for (const row of history) { if (!historyMap[row.service_name]) historyMap[row.service_name] = []; historyMap[row.service_name].push({ bucket: row.bucket, up_count: row.up_count, total: row.total, }); } // Merge data const results = live.map(l => { const s24 = stats24h.find(s => s.service_name === l.name); const s7d = stats7d.find(s => s.service_name === l.name); const sLife = statsLifetime.find(s => s.service_name === l.name); const avgLat = avgLatencyRows.find(s => s.service_name === l.name); return { ...l, uptime24h: s24 ? Math.round((s24.up_count / s24.total) * 100) : 100, uptime7d: s7d ? Math.round((s7d.up_count / s7d.total) * 100) : 100, uptimeLifetime: sLife ? Math.round((sLife.up_count / sLife.total) * 100) : 100, avgLatency24h: avgLat ? avgLat.avg_latency : 0, history: historyMap[l.name] || [], }; }); return NextResponse.json(results); } catch (error) { console.error('Uptime stats error:', error); return NextResponse.json([]); } }