export type ServiceStatus = 'healthy' | 'degraded' | 'down' | 'maintenance'; export type OverallStatus = 'healthy' | 'degraded' | 'critical'; export interface OpsService { id: string; name: string; group: string; target: string; status: ServiceStatus; latency: number; version?: string; message?: string; lastChecked: string; } export interface OpsStatusInput { overall: OverallStatus; timestamp: string; services: OpsService[]; } export interface InventoryService extends OpsService { description: string; management: 'docker' | 'vm'; exposure: 'internal' | 'public'; port?: number; restartable: boolean; } export interface InventoryDataInput { timestamp: string; counts: { services: number; healthy: number; degraded: number; down: number; hostTools: number; }; services: InventoryService[]; hostTools: unknown[]; } export interface ValkeyDataInput { timestamp: string; pattern: string; limit: number; summary: { ping: string; dbsize: number; matchedKeys: number; version: string; usedMemoryHuman: string; usedMemoryPeakHuman: string; }; keys: unknown[]; } export interface OpsCockpitTile { label: string; value: string; detail: string; tone: 'success' | 'warning' | 'danger' | 'neutral'; } export interface OpsCockpitAction { serviceId?: string; action: string; detail: string; severity: 'critical' | 'warning' | 'info'; } export interface OpsCockpit { headline: string; summary: string; tiles: OpsCockpitTile[]; priorityActions: OpsCockpitAction[]; } export function buildOpsCockpit(input: { status: OpsStatusInput | null; inventory: InventoryDataInput | null; valkey: ValkeyDataInput | null; }): OpsCockpit { const { status, inventory, valkey } = input; if (!status && !inventory && !valkey) { return { headline: 'Waiting for live ops telemetry', summary: 'Refresh Mission Control to collect service, inventory, and cache health.', tiles: [ { label: 'Services', value: '--', detail: 'No sample yet', tone: 'neutral' }, { label: 'Cache keys', value: '--', detail: 'Valkey not loaded', tone: 'neutral' }, { label: 'Restartable issues', value: '--', detail: 'Inventory not loaded', tone: 'neutral', }, ], priorityActions: [ { action: 'Refresh telemetry', detail: 'Load the latest service and cache status before taking action.', severity: 'info', }, ], }; } const unhealthyServices = status?.services.filter(service => service.status !== 'healthy') ?? []; const restartableIssues = unhealthyServices.filter(service => inventory?.services.some(inv => inv.id === service.id && inv.restartable) ); const cacheHealthy = valkey?.summary.ping === 'PONG'; const criticalCount = unhealthyServices.filter(service => service.status === 'down').length; const degradedCount = unhealthyServices.filter(service => service.status === 'degraded').length; const priorityActions: OpsCockpitAction[] = restartableIssues.map(service => ({ serviceId: service.id, action: 'Restart service', detail: `${service.name} is ${service.status}${service.message ? ` — ${service.message}` : ''}`, severity: service.status === 'down' ? 'critical' : 'warning', })); if (!cacheHealthy && valkey) { priorityActions.push({ action: 'Inspect Valkey', detail: `Cache ping returned ${valkey.summary.ping}; inspect hot keys and dependent services.`, severity: 'warning', }); } if (priorityActions.length === 0) { priorityActions.push({ action: 'Review deploy readiness', detail: 'All loaded systems are healthy; check recent errors before starting a deployment.', severity: 'info', }); } const overall = status?.overall ?? (criticalCount > 0 ? 'critical' : degradedCount > 0 ? 'degraded' : 'healthy'); const headline = overall === 'critical' ? `Critical ops attention needed (${criticalCount} down)` : overall === 'degraded' ? `Ops degraded (${degradedCount} warning${degradedCount === 1 ? '' : 's'})` : 'Ops cockpit healthy'; return { headline, summary: `${inventory?.counts.healthy ?? 0}/${inventory?.counts.services ?? status?.services.length ?? 0} services healthy · Valkey ${cacheHealthy ? 'ready' : 'needs review'}`, tiles: [ { label: 'Healthy services', value: String( inventory?.counts.healthy ?? status?.services.filter(s => s.status === 'healthy').length ?? 0 ), detail: `${inventory?.counts.services ?? status?.services.length ?? 0} tracked`, tone: criticalCount > 0 ? 'danger' : degradedCount > 0 ? 'warning' : 'success', }, { label: 'Cache keys', value: String(valkey?.summary.dbsize ?? 0), detail: valkey ? `${valkey.summary.usedMemoryHuman} used` : 'Valkey not loaded', tone: cacheHealthy ? 'success' : 'warning', }, { label: 'Restartable issues', value: String(restartableIssues.length), detail: restartableIssues.length ? 'Safe action available' : 'No restart needed', tone: restartableIssues.length ? 'danger' : 'success', }, ], priorityActions, }; }