import type { ViewDataBuilder } from '@/lib/contracts/builders/ViewDataBuilder'; import { HealthAlertFormatter } from '@/lib/formatters/HealthAlertFormatter'; import { HealthComponentFormatter } from '@/lib/formatters/HealthComponentFormatter'; import { HealthMetricFormatter } from '@/lib/formatters/HealthMetricFormatter'; import { HealthStatusFormatter } from '@/lib/formatters/HealthStatusFormatter'; import type { HealthDTO } from '../../../../api/src/domain/health/HealthDTO'; import type { HealthAlert, HealthComponent, HealthMetrics, HealthStatus, HealthViewData } from '@/lib/view-data/HealthViewData'; export type { HealthDTO }; export class HealthViewDataBuilder { public static build(apiDto: HealthDTO): HealthViewData { const now = new Date(); const lastUpdated = apiDto.timestamp || now.toISOString(); // Build overall status const overallStatus: HealthStatus = { status: apiDto.status, timestamp: apiDto.timestamp, formattedTimestamp: HealthStatusFormatter.formatTimestamp(apiDto.timestamp), relativeTime: HealthStatusFormatter.formatRelativeTime(apiDto.timestamp), statusLabel: HealthStatusFormatter.formatStatusLabel(apiDto.status), statusColor: HealthStatusFormatter.formatStatusColor(apiDto.status), statusIcon: HealthStatusFormatter.formatStatusIcon(apiDto.status), }; // Build metrics const metrics: HealthMetrics = { uptime: HealthMetricFormatter.formatUptime(apiDto.uptime), responseTime: HealthMetricFormatter.formatResponseTime(apiDto.responseTime), errorRate: HealthMetricFormatter.formatErrorRate(apiDto.errorRate), lastCheck: apiDto.lastCheck || lastUpdated, formattedLastCheck: HealthMetricFormatter.formatTimestamp(apiDto.lastCheck || lastUpdated), checksPassed: apiDto.checksPassed || 0, checksFailed: apiDto.checksFailed || 0, totalChecks: (apiDto.checksPassed || 0) + (apiDto.checksFailed || 0), successRate: HealthMetricFormatter.formatSuccessRate(apiDto.checksPassed, apiDto.checksFailed), }; // Build components const components: HealthComponent[] = (apiDto.components || []).map((component: { name: string; status: 'ok' | 'degraded' | 'error' | 'unknown'; lastCheck?: string; responseTime?: number; errorRate?: number; }) => ({ name: component.name, status: component.status, statusLabel: HealthComponentFormatter.formatStatusLabel(component.status), statusColor: HealthComponentFormatter.formatStatusColor(component.status), statusIcon: HealthComponentFormatter.formatStatusIcon(component.status), lastCheck: component.lastCheck || lastUpdated, formattedLastCheck: HealthComponentFormatter.formatTimestamp(component.lastCheck || lastUpdated), responseTime: HealthMetricFormatter.formatResponseTime(component.responseTime), errorRate: HealthMetricFormatter.formatErrorRate(component.errorRate), })); // Build alerts const alerts: HealthAlert[] = (apiDto.alerts || []).map((alert: { id: string; type: 'critical' | 'warning' | 'info'; title: string; message: string; timestamp: string; }) => ({ id: alert.id, type: alert.type, title: alert.title, message: alert.message, timestamp: alert.timestamp, formattedTimestamp: HealthAlertFormatter.formatTimestamp(alert.timestamp), relativeTime: HealthAlertFormatter.formatRelativeTime(alert.timestamp), severity: HealthAlertFormatter.formatSeverity(alert.type), severityColor: HealthAlertFormatter.formatSeverityColor(alert.type), })); // Calculate derived fields const hasAlerts = alerts.length > 0; const hasDegradedComponents = components.some((c) => c.status === 'degraded'); const hasErrorComponents = components.some((c) => c.status === 'error'); return { overallStatus, metrics, components, alerts, hasAlerts, hasDegradedComponents, hasErrorComponents, lastUpdated, formattedLastUpdated: HealthStatusFormatter.formatTimestamp(lastUpdated), }; } } HealthViewDataBuilder satisfies ViewDataBuilder;