import * as React from 'react'; /** Shape of the /health API response. */ interface HealthResponse { status: 'ok' | 'degraded'; version?: string; uptime?: number; services: { postgres: 'connected' | 'disconnected'; redis: 'connected' | 'disconnected'; }; } type ServiceStatus = 'connected' | 'disconnected' | 'unknown'; interface HealthState { postgres: ServiceStatus; redis: ServiceStatus; version: string | null; uptime: number | null; lastChecked: Date | null; reachable: boolean; } const initialState: HealthState = { postgres: 'unknown', redis: 'unknown', version: null, uptime: null, lastChecked: null, reachable: true, }; /** Formats seconds into a human-readable uptime string. */ function formatUptime(seconds: number): string { const days = Math.floor(seconds / 86400); const hours = Math.floor((seconds % 86400) / 3600); const minutes = Math.floor((seconds % 3600) / 60); const parts: string[] = []; if (days > 0) parts.push(`${days}d`); if (hours > 0) parts.push(`${hours}h`); parts.push(`${minutes}m`); return parts.join(' '); } interface StatusCardProps { label: string; status: ServiceStatus; } /** Card displaying the connectivity status of a single service. */ function StatusCard({ label, status }: StatusCardProps): React.JSX.Element { const isConnected = status === 'connected'; const isUnknown = status === 'unknown'; return (

{label}

{isUnknown ? 'Checking…' : isConnected ? 'Connected' : 'Disconnected'}
); } /** * Health page — shows PostgreSQL and Redis connectivity status. * Polls GET /health every 30 seconds. No authentication required. * Route: /dashboard/health */ export default function Health(): React.JSX.Element { const [health, setHealth] = React.useState(initialState); const [loading, setLoading] = React.useState(true); const checkHealth = React.useCallback(async (): Promise => { try { const response = await fetch('/health'); const data = (await response.json()) as HealthResponse; setHealth({ postgres: data.services?.postgres ?? 'unknown', redis: data.services?.redis ?? 'unknown', version: data.version ?? null, uptime: data.uptime ?? null, lastChecked: new Date(), reachable: true, }); } catch { setHealth((prev) => ({ ...prev, postgres: 'disconnected', redis: 'disconnected', lastChecked: new Date(), reachable: false, })); } finally { setLoading(false); } }, []); React.useEffect(() => { void checkHealth(); const interval = setInterval(() => { void checkHealth(); }, 30_000); return () => { clearInterval(interval); }; }, [checkHealth]); return (

System Health

{!health.reachable && (
API is unreachable. Check that the server is running.
)}
{/* Metadata */} {(health.version !== null || health.uptime !== null) && (

API Details

{health.version !== null && (
Version
{health.version}
)} {health.uptime !== null && (
Uptime
{formatUptime(health.uptime)}
)}
)} {/* Last checked */} {health.lastChecked !== null && (

Last checked: {health.lastChecked.toLocaleTimeString()} — auto-refreshes every 30 seconds

)}
); }