/** Types and helpers for PostgreSQL monitoring API. */ export const POSTGRES_POLL_MS = 20_000; export const POSTGRES_SLOW_POLL_MS = 60_000; export type PostgresOverview = { collected_at: string; connections: { active: number; idle: number; total: number; max_connections: number; }; database: { backends: number; xact_commit: number; xact_rollback: number; deadlocks: number; blks_hit: number; blks_read: number; cache_hit_pct: number; }; database_size_bytes: number; memory_settings: { shared_buffers: string; work_mem: string; effective_cache_size: string; }; replication: Array<{ client_addr?: string; state: string; sync_state?: string; lag_ms?: number; }>; pg_stat_statements_enabled: boolean; }; export type PostgresQueryRow = { queryid?: number; query: string; calls: number; total_exec_ms: number; mean_exec_ms: number; rows: number; }; export type PostgresQueriesResponse = { collected_at: string; source: string; items: PostgresQueryRow[]; statements_available?: boolean; statements_hint?: string; }; export type PostgresLockRow = { locktype: string; mode: string; granted: boolean; pid: number; usename?: string; state?: string; query?: string; blocked: boolean; }; export type PostgresTableRow = { relname: string; total_bytes: number; idx_scan: number; seq_scan: number; n_dead_tup: number; bloat_ratio?: number; last_autovacuum?: string; }; export type PostgresRecommendation = { severity: string; code: string; title: string; detail: string; refs?: string[]; }; export type PostgresRecommendationsResponse = { collected_at: string; items: PostgresRecommendation[]; }; export type PostgresMaintLog = { id: string; kind: string; target_table?: string; dry_run: boolean; status: string; error?: string; created_at: string; }; export type CorrelationResponse = { window_minutes: number; points: Array<{ timestamp: string; pipeline_refresh_p99_ms?: number; cache_hit_pct?: number; }>; }; export function formatBytes(n: number): string { if (n >= 1 << 30) return `${(n / (1 << 30)).toFixed(1)} GiB`; if (n >= 1 << 20) return `${(n / (1 << 20)).toFixed(1)} MiB`; if (n >= 1 << 10) return `${(n / (1 << 10)).toFixed(1)} KiB`; return `${n} B`; } export function connUsagePct(ov: PostgresOverview | null): number { if (!ov?.connections.max_connections) return 0; return Math.min(100, (ov.connections.total / ov.connections.max_connections) * 100); }