import type { APIRoute } from 'astro'; import { pool } from '@/lib/db'; /** * Live Log Streaming (SSE) * Stream database activity logs */ function validateGodToken(request: Request): boolean { const token = request.headers.get('X-God-Token') || request.headers.get('Authorization')?.replace('Bearer ', '') || new URL(request.url).searchParams.get('token'); const godToken = process.env.GOD_MODE_TOKEN || import.meta.env.GOD_MODE_TOKEN; if (!godToken) return true; return token === godToken; } export const GET: APIRoute = async ({ request }) => { if (!validateGodToken(request)) { return new Response(JSON.stringify({ error: 'Unauthorized' }), { status: 401, headers: { 'Content-Type': 'application/json' } }); } const url = new URL(request.url); const lines = parseInt(url.searchParams.get('lines') || '100'); try { // Get recent pg_stat_activity as "logs" const result = await pool.query(` SELECT pid, usename, application_name, state, query, state_change, EXTRACT(EPOCH FROM (now() - query_start)) as duration_seconds FROM pg_stat_activity WHERE datname = current_database() AND pid != pg_backend_pid() ORDER BY query_start DESC LIMIT $1 `, [lines]); // Format as log entries const logs = result.rows.map(row => ({ timestamp: row.state_change, pid: row.pid, user: row.usename, app: row.application_name, state: row.state, duration: `${Math.round(row.duration_seconds)}s`, query: row.query?.substring(0, 200) })); return new Response(JSON.stringify({ logs, count: logs.length, requested: lines, timestamp: new Date().toISOString() }), { status: 200, headers: { 'Content-Type': 'application/json' } }); } catch (error: any) { return new Response(JSON.stringify({ error: 'Failed to fetch logs', details: error.message }), { status: 500, headers: { 'Content-Type': 'application/json' } }); } };