Files
ITWorx-Pulse-Public/apps/web/src/overviewSignals.ts
T
ITWorx Pulse release export bd774932d5
Public source validation / validate (push) Failing after 3m8s
Publish ITWorx Pulse source
2026-09-03 02:09:19 +02:00

58 lines
2.4 KiB
TypeScript

export type SignalTone = 'healthy' | 'attention' | 'critical' | 'stale' | 'unknown';
export type SignalSource = {
state?: string;
freshness?: string;
};
export type SignalContainer = {
state?: string;
health?: string;
intentionalStop?: boolean;
};
export const signalToneRank: Record<SignalTone, number> = {
critical: 0,
attention: 1,
stale: 2,
unknown: 3,
healthy: 4,
};
export function signalToneFromState(state: string | undefined): SignalTone {
const normalized = state?.trim().toLowerCase();
if (normalized === 'critical' || normalized === 'faulted' || normalized === 'down' || normalized === 'failed' || normalized === 'error') return 'critical';
if (normalized === 'attention' || normalized === 'degraded' || normalized === 'warning' || normalized === 'restarting' || normalized === 'paused' || normalized === 'removing') return 'attention';
if (normalized === 'stale') return 'stale';
if (normalized === 'healthy' || normalized === 'normal' || normalized === 'up' || normalized === 'running' || normalized === 'fresh') return 'healthy';
return 'unknown';
}
export function worstSignalTone(tones: SignalTone[]): SignalTone {
if (tones.length === 0) return 'unknown';
return tones.reduce<SignalTone>((worst, tone) => signalToneRank[tone] < signalToneRank[worst] ? tone : worst, 'healthy');
}
/** A successful HTTP response is not healthy when its provenance is stale or unknown. */
export function sourceSignalTone(source: SignalSource | undefined): SignalTone {
if (!source) return 'unknown';
const freshness = source.freshness?.trim().toLowerCase();
if (freshness === 'stale') return 'stale';
if (freshness !== 'fresh') return 'unknown';
return signalToneFromState(source.state);
}
/** Mirrors the backend application-state projection without treating an intentional stop as a failure. */
export function containerSignalTone(container: SignalContainer): SignalTone {
const state = container.state?.trim().toLowerCase();
const health = container.health?.trim().toLowerCase();
if (state === 'running') {
if (health === 'healthy') return 'healthy';
if (health === 'unhealthy') return 'attention';
return 'unknown';
}
if (state === 'restarting' || state === 'paused' || state === 'removing') return 'attention';
if (state === 'exited' || state === 'dead' || state === 'stopped') return container.intentionalStop ? 'unknown' : 'critical';
return 'unknown';
}