diff --git a/server/src/domain/monitors/monitor.type.ts b/server/src/domain/monitors/monitor.type.ts index b033c560a..07b0ef2e4 100644 --- a/server/src/domain/monitors/monitor.type.ts +++ b/server/src/domain/monitors/monitor.type.ts @@ -240,3 +240,8 @@ export type GamesMap = Record; export type MonitorScheduleFields = Pick; export type DockerContainerLogsResult = DockerLogPage; + +export const HardwareMetricKeys = ["cpu", "memory", "disk", "temp"] as const; +export type HardwareMetricKey = (typeof HardwareMetricKeys)[number]; +export type HardwareBreaches = Record; +export type HardwareCounters = Record; diff --git a/server/src/domain/notifications/notification.type.ts b/server/src/domain/notifications/notification.type.ts index 7f2c7df1e..0082f2098 100644 --- a/server/src/domain/notifications/notification.type.ts +++ b/server/src/domain/notifications/notification.type.ts @@ -1,3 +1,5 @@ +import { HardwareMetricKey } from "@/domain/monitors/monitor.type.js"; + export const NotificationChannels = [ "email", "slack", @@ -85,7 +87,7 @@ export interface MonitorInfo { } export interface ThresholdBreach { - metric: "cpu" | "memory" | "disk" | "temp"; + metric: HardwareMetricKey; currentValue: number; threshold: number; unit: string; diff --git a/server/src/service/statusService.ts b/server/src/service/statusService.ts index 64a6f2e61..0ceeb9540 100755 --- a/server/src/service/statusService.ts +++ b/server/src/service/statusService.ts @@ -1,7 +1,14 @@ import { IMonitorStatsRepository } from "@/domain/monitor-stats/monitor-stats.repository.interface.js"; import { IMonitorsRepository } from "@/domain/monitors/monitor.repository.interface.js"; import type { Check, CheckDiskInfo } from "@/domain/checks/check.type.js"; -import { MonitorStatuses, type Monitor, type MonitorStatus } from "@/domain/monitors/monitor.type.js"; +import { + HardwareBreaches, + HardwareCounters, + HardwareMetricKeys, + MonitorStatuses, + type Monitor, + type MonitorStatus, +} from "@/domain/monitors/monitor.type.js"; import type { StatusChangeResult } from "@/types/network.js"; import { AppError } from "@/utils/AppError.js"; import { ILogger } from "@/utils/logger.js"; @@ -12,10 +19,6 @@ import { findContainerBreaches } from "@/domain/docker/docker-alert.js"; const SERVICE_NAME = "StatusService"; const HARDWARE_ALERT_COUNTER_START = 5; -const HARDWARE_METRIC_KEYS = ["cpu", "memory", "disk", "temp"] as const; -type HardwareMetricKey = (typeof HARDWARE_METRIC_KEYS)[number]; -type HardwareBreaches = Record; -type HardwareCounters = Record; export interface IStatusService { updateRunningStats(check: Check, monitor: Monitor): Promise; @@ -111,7 +114,7 @@ export class StatusService implements IStatusService { // Update counters: decrement (floored at 0) if breached, reset to start otherwise. const nextCounters = { ...counters }; - for (const key of HARDWARE_METRIC_KEYS) { + for (const key of HardwareMetricKeys) { nextCounters[key] = breaches[key] ? Math.max(0, counters[key] - 1) : HARDWARE_ALERT_COUNTER_START; } @@ -123,8 +126,8 @@ export class StatusService implements IStatusService { if (!reachabilityDown) { // A counter can only reach zero via the decrement path, which only runs when that // metric is currently breaching — so anyCounterZero already implies anyBreached. - const anyCounterZero = HARDWARE_METRIC_KEYS.some((k) => nextCounters[k] === 0); - const allNormal = HARDWARE_METRIC_KEYS.every((k) => !breaches[k]); + const anyCounterZero = HardwareMetricKeys.some((k) => nextCounters[k] === 0); + const allNormal = HardwareMetricKeys.every((k) => !breaches[k]); if (anyCounterZero && currentStatus !== "breached") { nextStatus = "breached"; diff --git a/server/src/types/network.ts b/server/src/types/network.ts index a2cf78dbe..3ca2f107f 100644 --- a/server/src/types/network.ts +++ b/server/src/types/network.ts @@ -10,7 +10,7 @@ import type { ILighthouseAudit, } from "@/domain/checks/check.type.js"; import { DockerContainerInfo, DockerContainerLogs, DockerContainerSummary } from "@/domain/docker/docker.type.js"; -import type { DnsRecordType, Monitor, MonitorMatchMethod, MonitorStatus, MonitorType } from "@/domain/monitors/monitor.type.js"; +import type { DnsRecordType, HardwareBreaches, Monitor, MonitorMatchMethod, MonitorStatus, MonitorType } from "@/domain/monitors/monitor.type.js"; import type { QueryResult } from "gamedig"; @@ -184,12 +184,7 @@ export type StatusChangeResult = { prevStatus: MonitorStatus; code: number; timestamp: number; - thresholdBreaches?: { - cpu: boolean; - memory: boolean; - disk: boolean; - temp: boolean; - }; + thresholdBreaches?: HardwareBreaches; }; export type MonitorStatusResponseOverrides = Partial, "monitorId" | "teamId" | "type">>;