Files
gridpilot.gg/apps/website/lib/builders/view-data/HealthViewDataBuilder.ts
2026-01-24 00:52:27 +01:00

86 lines
3.8 KiB
TypeScript

'use client';
import type { HealthDTO } from '@/lib/types/generated/HealthDTO';
import type { HealthViewData, HealthStatus, HealthMetrics, HealthComponent, HealthAlert } from '@/lib/view-data/HealthViewData';
import { HealthStatusDisplay } from '@/lib/display-objects/HealthStatusDisplay';
import { HealthMetricDisplay } from '@/lib/display-objects/HealthMetricDisplay';
import { HealthComponentDisplay } from '@/lib/display-objects/HealthComponentDisplay';
import { HealthAlertDisplay } from '@/lib/display-objects/HealthAlertDisplay';
import type { ViewDataBuilder } from '@/lib/contracts/builders/ViewDataBuilder';
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: HealthStatusDisplay.formatTimestamp(apiDto.timestamp),
relativeTime: HealthStatusDisplay.formatRelativeTime(apiDto.timestamp),
statusLabel: HealthStatusDisplay.formatStatusLabel(apiDto.status),
statusColor: HealthStatusDisplay.formatStatusColor(apiDto.status),
statusIcon: HealthStatusDisplay.formatStatusIcon(apiDto.status),
};
// Build metrics
const metrics: HealthMetrics = {
uptime: HealthMetricDisplay.formatUptime(apiDto.uptime),
responseTime: HealthMetricDisplay.formatResponseTime(apiDto.responseTime),
errorRate: HealthMetricDisplay.formatErrorRate(apiDto.errorRate),
lastCheck: apiDto.lastCheck || lastUpdated,
formattedLastCheck: HealthMetricDisplay.formatTimestamp(apiDto.lastCheck || lastUpdated),
checksPassed: apiDto.checksPassed || 0,
checksFailed: apiDto.checksFailed || 0,
totalChecks: (apiDto.checksPassed || 0) + (apiDto.checksFailed || 0),
successRate: HealthMetricDisplay.formatSuccessRate(apiDto.checksPassed, apiDto.checksFailed),
};
// Build components
const components: HealthComponent[] = (apiDto.components || []).map((component) => ({
name: component.name,
status: component.status,
statusLabel: HealthComponentDisplay.formatStatusLabel(component.status),
statusColor: HealthComponentDisplay.formatStatusColor(component.status),
statusIcon: HealthComponentDisplay.formatStatusIcon(component.status),
lastCheck: component.lastCheck || lastUpdated,
formattedLastCheck: HealthComponentDisplay.formatTimestamp(component.lastCheck || lastUpdated),
responseTime: HealthMetricDisplay.formatResponseTime(component.responseTime),
errorRate: HealthMetricDisplay.formatErrorRate(component.errorRate),
}));
// Build alerts
const alerts: HealthAlert[] = (apiDto.alerts || []).map((alert) => ({
id: alert.id,
type: alert.type,
title: alert.title,
message: alert.message,
timestamp: alert.timestamp,
formattedTimestamp: HealthAlertDisplay.formatTimestamp(alert.timestamp),
relativeTime: HealthAlertDisplay.formatRelativeTime(alert.timestamp),
severity: HealthAlertDisplay.formatSeverity(alert.type),
severityColor: HealthAlertDisplay.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: HealthStatusDisplay.formatTimestamp(lastUpdated),
};
}
}
HealthViewDataBuilder satisfies ViewDataBuilder<HealthDTO, HealthViewData>;