From ed36db172a1e7c5793770529e99245f1ccdaf4f2 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Fri, 24 Jul 2026 11:32:00 -0700 Subject: [PATCH] dedupe hardware stat definitions, fix tests, remove misleading null return types --- server/src/api/controllers/controllerUtils.ts | 2 +- server/src/api/validation/checkValidation.ts | 2 +- .../src/api/validation/monitorValidation.ts | 2 +- .../checks/check.hardware.aggregations.ts | 17 +++- server/src/domain/checks/check.model.ts | 2 +- .../checks/check.repository.interface.ts | 2 +- .../domain/checks/check.repository.mongo.ts | 59 +++++++------ server/src/domain/checks/check.type.ts | 85 ++++++++++--------- .../src/domain/geo-checks/geo-check.model.ts | 2 +- .../domain/geo-checks/geo-check.service.ts | 2 +- .../src/domain/geo-checks/geo-check.type.ts | 2 +- .../src/domain/incidents/incident.service.ts | 2 +- server/src/domain/monitors/monitor.model.ts | 4 +- .../monitors/monitor.repository.interface.ts | 8 +- .../monitors/monitor.repository.mongo.ts | 6 +- server/src/domain/monitors/monitor.service.ts | 13 ++- .../{monitor.types.ts => monitor.type.ts} | 43 +--------- .../notification.message-builder.ts | 2 +- .../notifications/notification.service.ts | 2 +- .../status-pages/status-page.service.ts | 2 +- .../domain/status-pages/status-page.type.ts | 2 +- server/src/service/globalPingService.ts | 4 +- server/src/service/network/AdvancedMatcher.ts | 2 +- server/src/service/network/DNSProvider.ts | 2 +- server/src/service/network/DockerProvider.ts | 2 +- server/src/service/network/GameProvider.ts | 2 +- server/src/service/network/GrpcProvider.ts | 2 +- .../src/service/network/HardwareProvider.ts | 2 +- server/src/service/network/HttpProvider.ts | 2 +- server/src/service/network/IStatusProvider.ts | 2 +- .../src/service/network/PageSpeedProvider.ts | 2 +- server/src/service/network/PingProvider.ts | 2 +- server/src/service/network/PortProvider.ts | 2 +- .../src/service/network/WebSocketProvider.ts | 2 +- server/src/service/network/utils.ts | 2 +- server/src/service/networkService.ts | 2 +- server/src/service/statusService.ts | 4 +- server/src/types/network.ts | 2 +- server/src/worker/worker.check-evaluator.ts | 2 +- server/src/worker/worker.check-pipeline.ts | 4 +- server/src/worker/worker.check-producer.ts | 2 +- server/src/worker/worker.interface.ts | 2 +- server/src/worker/worker.job-scheduler.ts | 4 +- 43 files changed, 148 insertions(+), 165 deletions(-) rename server/src/domain/monitors/{monitor.types.ts => monitor.type.ts} (87%) diff --git a/server/src/api/controllers/controllerUtils.ts b/server/src/api/controllers/controllerUtils.ts index be3f46533..1980ec0b4 100755 --- a/server/src/api/controllers/controllerUtils.ts +++ b/server/src/api/controllers/controllerUtils.ts @@ -1,5 +1,5 @@ import { AppError } from "@/utils/AppError.js"; -import { Monitor, MonitorTypes, type MonitorType } from "@/domain/monitors/monitor.types.js"; +import { Monitor, MonitorTypes, type MonitorType } from "@/domain/monitors/monitor.type.js"; import { UserRole } from "@/domain/users/user.type.js"; import sslChecker, { SSLDetails } from "ssl-checker"; type SSLCheckerType = typeof sslChecker; diff --git a/server/src/api/validation/checkValidation.ts b/server/src/api/validation/checkValidation.ts index d041c9e8f..e40d11024 100644 --- a/server/src/api/validation/checkValidation.ts +++ b/server/src/api/validation/checkValidation.ts @@ -1,7 +1,7 @@ import { z } from "zod"; import { booleanCoercion } from "./shared.js"; import { GeoContinents } from "@/domain/geo-checks/geo-check.type.js"; -import { MonitorTypes } from "@/domain/monitors/monitor.types.js"; +import { MonitorTypes } from "@/domain/monitors/monitor.type.js"; import { CheckFilters, DateRanges, SortOrders } from "@/types/query.js"; //**************************************** diff --git a/server/src/api/validation/monitorValidation.ts b/server/src/api/validation/monitorValidation.ts index 1ed9dca84..37a31fc6a 100644 --- a/server/src/api/validation/monitorValidation.ts +++ b/server/src/api/validation/monitorValidation.ts @@ -10,7 +10,7 @@ import { MonitorStatuses, MonitorTypes, PageSpeedStrategies, -} from "@/domain/monitors/monitor.types.js"; +} from "@/domain/monitors/monitor.type.js"; import { DateRanges, SortOrders } from "@/types/query.js"; const httpStatusCode = z.number().refine((code) => HttpStatusCodeSet.has(code), { message: "Must be a valid HTTP status code" }); diff --git a/server/src/domain/checks/check.hardware.aggregations.ts b/server/src/domain/checks/check.hardware.aggregations.ts index 176817315..6c672b630 100644 --- a/server/src/domain/checks/check.hardware.aggregations.ts +++ b/server/src/domain/checks/check.hardware.aggregations.ts @@ -1,9 +1,22 @@ import { CheckModel } from "@/domain/checks/check.model.js"; import mongoose from "mongoose"; +import type { HardwareDiskStats, HardwareNetStats } from "@/domain/checks/check.type.js"; type DateRange = { start: Date; end: Date }; type HardwareUpChecks = { totalChecks: number }; +// $avg yields null when no values are present, so metrics are nullable until the repository applies fallbacks +type NullableValues = { [K in keyof T]: T[K] | null }; + +export type HardwareStatsBucket = { + _id: string; + avgCpuUsage: number | null; + avgMemoryUsage: number | null; + avgTemperature: number[]; + disks: NullableValues[]; + net: NullableValues[]; +}; + const NET_RATE_FIELDS = [ ["bytesSentPerSecond", "bytes_sent"], ["deltaBytesRecv", "bytes_recv"], @@ -70,13 +83,13 @@ export const getHardwareUpChecks = async (monitorId: string, dates: DateRange): return { totalChecks: count }; }; -export const getHardwareStats = async (monitorId: string, dates: DateRange, dateString: string) => { +export const getHardwareStats = async (monitorId: string, dates: DateRange, dateString: string): Promise => { const netProjection = { name: { $arrayElemAt: ["$sampleDoc.net.name", "$$nIdx"] }, ...Object.fromEntries(NET_RATE_FIELDS.map(([outputKey, sourceField]) => [outputKey, netRatePerSecond(sourceField)])), }; - return await CheckModel.aggregate([ + return await CheckModel.aggregate([ { $match: { "metadata.monitorId": new mongoose.Types.ObjectId(monitorId), diff --git a/server/src/domain/checks/check.model.ts b/server/src/domain/checks/check.model.ts index c3fbc23ff..9f3c2fbc1 100644 --- a/server/src/domain/checks/check.model.ts +++ b/server/src/domain/checks/check.model.ts @@ -1,5 +1,5 @@ import { Schema, model, Types } from "mongoose"; -import { MonitorTypes, type MonitorType } from "@/domain/monitors/monitor.types.js"; +import { MonitorTypes, type MonitorType } from "@/domain/monitors/monitor.type.js"; import type { Check, CheckAudits, diff --git a/server/src/domain/checks/check.repository.interface.ts b/server/src/domain/checks/check.repository.interface.ts index 2db5df712..e6b7c6368 100644 --- a/server/src/domain/checks/check.repository.interface.ts +++ b/server/src/domain/checks/check.repository.interface.ts @@ -6,7 +6,7 @@ import type { PageSpeedChecksResult, UptimeChecksResult, } from "@/domain/checks/check.type.js"; -import type { MonitorType } from "@/domain/monitors/monitor.types.js"; +import type { MonitorType } from "@/domain/monitors/monitor.type.js"; import type { LatestChecksMap } from "@/domain/checks/check.repository.mongo.js"; import { CheckFilter, DateRange } from "@/types/query.js"; diff --git a/server/src/domain/checks/check.repository.mongo.ts b/server/src/domain/checks/check.repository.mongo.ts index 4687f8ffc..9767947d9 100644 --- a/server/src/domain/checks/check.repository.mongo.ts +++ b/server/src/domain/checks/check.repository.mongo.ts @@ -11,8 +11,9 @@ import type { CheckMetadata, CheckNetworkInterfaceInfo, GotTimings, + HardwareCheckStats, } from "@/domain/checks/check.type.js"; -import type { MonitorType } from "@/domain/monitors/monitor.types.js"; +import type { MonitorType } from "@/domain/monitors/monitor.type.js"; import { CheckModel, type CheckDocument } from "@/domain/checks/check.model.js"; import mongoose from "mongoose"; import { getDateFormat, getDateForRange } from "@/utils/dataUtils.js"; @@ -512,33 +513,35 @@ class MongoChecksRepository implements IChecksRepository { totalChecks: upChecksDoc?.totalChecks ?? 0, }; - const checks = (hardwareMetrics ?? []).map((metric) => ({ - bucketDate: metric._id, - avgCpuUsage: metric.avgCpuUsage ?? 0, - avgMemoryUsage: metric.avgMemoryUsage ?? 0, - avgTemperature: metric.avgTemperature ?? [], - disks: (metric.disks ?? []).map((disk: { [key: string]: number | string | undefined }) => ({ - name: disk?.name ?? "", - readSpeed: disk?.readSpeed ?? 0, - writeSpeed: disk?.writeSpeed ?? 0, - totalBytes: disk?.totalBytes ?? 0, - freeBytes: disk?.freeBytes ?? 0, - usagePercent: disk?.usagePercent ?? 0, - })), - net: (metric.net ?? []).map((iface: { [key: string]: number | string | undefined }) => ({ - name: iface?.name ?? "", - bytesSentPerSecond: iface?.bytesSentPerSecond ?? 0, - deltaBytesRecv: iface?.deltaBytesRecv ?? 0, - deltaPacketsSent: iface?.deltaPacketsSent ?? 0, - deltaPacketsRecv: iface?.deltaPacketsRecv ?? 0, - deltaErrIn: iface?.deltaErrIn ?? 0, - deltaErrOut: iface?.deltaErrOut ?? 0, - deltaDropIn: iface?.deltaDropIn ?? 0, - deltaDropOut: iface?.deltaDropOut ?? 0, - deltaFifoIn: iface?.deltaFifoIn ?? 0, - deltaFifoOut: iface?.deltaFifoOut ?? 0, - })), - })); + const checks = (hardwareMetrics ?? []).map( + (metric): HardwareCheckStats => ({ + bucketDate: metric._id, + avgCpuUsage: metric.avgCpuUsage ?? 0, + avgMemoryUsage: metric.avgMemoryUsage ?? 0, + avgTemperature: metric.avgTemperature ?? [], + disks: (metric.disks ?? []).map((disk) => ({ + name: disk?.name ?? "", + readSpeed: disk?.readSpeed ?? 0, + writeSpeed: disk?.writeSpeed ?? 0, + totalBytes: disk?.totalBytes ?? 0, + freeBytes: disk?.freeBytes ?? 0, + usagePercent: disk?.usagePercent ?? 0, + })), + net: (metric.net ?? []).map((iface) => ({ + name: iface?.name ?? "", + bytesSentPerSecond: iface?.bytesSentPerSecond ?? 0, + deltaBytesRecv: iface?.deltaBytesRecv ?? 0, + deltaPacketsSent: iface?.deltaPacketsSent ?? 0, + deltaPacketsRecv: iface?.deltaPacketsRecv ?? 0, + deltaErrIn: iface?.deltaErrIn ?? 0, + deltaErrOut: iface?.deltaErrOut ?? 0, + deltaDropIn: iface?.deltaDropIn ?? 0, + deltaDropOut: iface?.deltaDropOut ?? 0, + deltaFifoIn: iface?.deltaFifoIn ?? 0, + deltaFifoOut: iface?.deltaFifoOut ?? 0, + })), + }) + ); return { monitorType: "hardware" as const, diff --git a/server/src/domain/checks/check.type.ts b/server/src/domain/checks/check.type.ts index fe733e4e9..faac84cef 100644 --- a/server/src/domain/checks/check.type.ts +++ b/server/src/domain/checks/check.type.ts @@ -1,4 +1,4 @@ -import type { MonitorType } from "@/domain/monitors/monitor.types.js"; +import type { MonitorType } from "@/domain/monitors/monitor.type.js"; import type { Response } from "got"; export const CHECK_TTL_SENTINEL = 366; @@ -126,43 +126,6 @@ export interface PageSpeedChecksResult { groupedChecks: PageSpeedGroupedCheck[]; } -export interface HardwareChecksResult { - monitorType: "hardware"; - aggregateData: { - totalChecks: number; - }; - upChecks: { - totalChecks: number; - }; - checks: Array<{ - bucketDate: string; - avgCpuUsage: number; - avgMemoryUsage: number; - avgTemperature: number[]; - disks: Array<{ - name: string; - readSpeed: number; - writeSpeed: number; - totalBytes: number; - freeBytes: number; - usagePercent: number; - }>; - net: Array<{ - name: string; - bytesSentPerSecond: number; - deltaBytesRecv: number; - deltaPacketsSent: number; - deltaPacketsRecv: number; - deltaErrIn: number; - deltaErrOut: number; - deltaDropIn: number; - deltaDropOut: number; - deltaFifoIn: number; - deltaFifoOut: number; - }>; - }>; -} - export interface GroupedCheck { bucketDate: string; avgResponseTime: number; @@ -205,3 +168,49 @@ export type NormalizedUptimeCheck = T & { }; export type CheckSnapshot = Omit; + +export interface HardwareDiskStats { + name: string; + readSpeed: number; + writeSpeed: number; + totalBytes: number; + freeBytes: number; + usagePercent: number; +} + +export interface HardwareNetStats { + name: string; + bytesSentPerSecond: number; + deltaBytesRecv: number; + deltaPacketsSent: number; + deltaPacketsRecv: number; + deltaErrIn: number; + deltaErrOut: number; + deltaDropIn: number; + deltaDropOut: number; + deltaFifoIn: number; + deltaFifoOut: number; +} + +export interface HardwareCheckStats { + bucketDate: string; + avgCpuUsage: number; + avgMemoryUsage: number; + avgTemperature: number[]; + disks: HardwareDiskStats[]; + net: HardwareNetStats[]; +} + +export interface HardwareStats { + aggregateData: { + totalChecks: number; + }; + upChecks: { + totalChecks: number; + }; + checks: HardwareCheckStats[]; +} + +export interface HardwareChecksResult extends HardwareStats { + monitorType: "hardware"; +} diff --git a/server/src/domain/geo-checks/geo-check.model.ts b/server/src/domain/geo-checks/geo-check.model.ts index 0db895d0a..512979ea5 100644 --- a/server/src/domain/geo-checks/geo-check.model.ts +++ b/server/src/domain/geo-checks/geo-check.model.ts @@ -1,5 +1,5 @@ import { Schema, model, Types } from "mongoose"; -import { MonitorTypes, type MonitorType } from "@/domain/monitors/monitor.types.js"; +import { MonitorTypes, type MonitorType } from "@/domain/monitors/monitor.type.js"; import type { GeoCheck, GeoCheckLocation, GeoCheckMetadata, GeoCheckResult, GeoCheckTimings } from "@/domain/geo-checks/geo-check.type.js"; type GeoCheckMetadataDocument = Omit & { diff --git a/server/src/domain/geo-checks/geo-check.service.ts b/server/src/domain/geo-checks/geo-check.service.ts index 26d347228..3b9f19b4d 100644 --- a/server/src/domain/geo-checks/geo-check.service.ts +++ b/server/src/domain/geo-checks/geo-check.service.ts @@ -1,5 +1,5 @@ import type { GeoCheck } from "@/domain/geo-checks/geo-check.type.js"; -import type { Monitor } from "@/domain/monitors/monitor.types.js"; +import type { Monitor } from "@/domain/monitors/monitor.type.js"; import type { GeoCheckResult, GeoContinent } from "@/domain/geo-checks/geo-check.type.js"; import { Types } from "mongoose"; import type { FlatGeoChecksQueryResult, IGeoChecksRepository } from "@/domain/geo-checks/geo-check.repository.interface.js"; diff --git a/server/src/domain/geo-checks/geo-check.type.ts b/server/src/domain/geo-checks/geo-check.type.ts index 044bec3b0..e2eea9f25 100644 --- a/server/src/domain/geo-checks/geo-check.type.ts +++ b/server/src/domain/geo-checks/geo-check.type.ts @@ -1,4 +1,4 @@ -import type { MonitorType } from "@/domain/monitors/monitor.types.js"; +import type { MonitorType } from "@/domain/monitors/monitor.type.js"; export const GeoContinents = ["EU", "NA", "AS", "SA", "AF", "OC"] as const; export type GeoContinent = (typeof GeoContinents)[number]; diff --git a/server/src/domain/incidents/incident.service.ts b/server/src/domain/incidents/incident.service.ts index 9b8fbf25e..a9851d85e 100644 --- a/server/src/domain/incidents/incident.service.ts +++ b/server/src/domain/incidents/incident.service.ts @@ -1,5 +1,5 @@ const SERVICE_NAME = "incidentService"; -import type { Monitor } from "@/domain/monitors/monitor.types.js"; +import type { Monitor } from "@/domain/monitors/monitor.type.js"; import type { MonitorStatusResponse } from "@/types/network.js"; import { AppError } from "@/utils/AppError.js"; import { getDateForRange } from "@/utils/dataUtils.js"; diff --git a/server/src/domain/monitors/monitor.model.ts b/server/src/domain/monitors/monitor.model.ts index 47aa70b5e..446631f45 100644 --- a/server/src/domain/monitors/monitor.model.ts +++ b/server/src/domain/monitors/monitor.model.ts @@ -1,6 +1,6 @@ import { Schema, model, Types } from "mongoose"; -import type { Monitor, MonitorMatchMethod, CheckSnapshot } from "@/domain/monitors/monitor.types.js"; -import { DnsRecordTypes, MonitorTypes, MonitorStatuses, PageSpeedStrategies, HttpMethods } from "@/domain/monitors/monitor.types.js"; +import type { Monitor, MonitorMatchMethod, CheckSnapshot } from "@/domain/monitors/monitor.type.js"; +import { DnsRecordTypes, MonitorTypes, MonitorStatuses, PageSpeedStrategies, HttpMethods } from "@/domain/monitors/monitor.type.js"; import type { CheckAudits, CheckCaptureInfo, diff --git a/server/src/domain/monitors/monitor.repository.interface.ts b/server/src/domain/monitors/monitor.repository.interface.ts index a710e366f..d3dc0597e 100644 --- a/server/src/domain/monitors/monitor.repository.interface.ts +++ b/server/src/domain/monitors/monitor.repository.interface.ts @@ -1,4 +1,4 @@ -import type { MonitorType, Monitor, MonitorStatus, MonitorsSummary, CheckSnapshot } from "@/domain/monitors/monitor.types.js"; +import type { MonitorType, Monitor, MonitorStatus, MonitorsSummary, CheckSnapshot } from "@/domain/monitors/monitor.type.js"; export interface TeamQueryConfig { limit?: number; @@ -26,9 +26,9 @@ export interface IMonitorsRepository { findByIdLean(monitorId: string): Promise; // collection fetch - findAll(): Promise; - findByTeamId(teamId: string, config: TeamQueryConfig): Promise; - findByTeamIdWithStats(teamId: string, config: TeamQueryConfig): Promise; + findAll(): Promise; + findByTeamId(teamId: string, config: TeamQueryConfig): Promise; + findByTeamIdWithStats(teamId: string, config: TeamQueryConfig): Promise; findByIds(monitorIds: string[]): Promise; findByIdsWithChecks(monitorIds: string[], checksCount?: number): Promise; diff --git a/server/src/domain/monitors/monitor.repository.mongo.ts b/server/src/domain/monitors/monitor.repository.mongo.ts index d9e35855c..b96ec3907 100644 --- a/server/src/domain/monitors/monitor.repository.mongo.ts +++ b/server/src/domain/monitors/monitor.repository.mongo.ts @@ -1,7 +1,7 @@ import { MonitorModel } from "@/domain/monitors/monitor.model.js"; import type { MonitorDocument, CheckSnapshotDocument } from "@/domain/monitors/monitor.model.js"; import type { CheckSnapshot } from "@/domain/checks/check.type.js"; -import type { Monitor, MonitorStatus, MonitorsSummary } from "@/domain/monitors/monitor.types.js"; +import type { Monitor, MonitorStatus, MonitorsSummary } from "@/domain/monitors/monitor.type.js"; import mongoose, { type FilterQuery, type PipelineStage } from "mongoose"; import { MongoBulkWriteError } from "mongodb"; import { AppError } from "@/utils/AppError.js"; @@ -96,14 +96,14 @@ class MongoMonitorsRepository implements IMonitorsRepository { return { sort: { [field]: order === "asc" ? 1 : -1 } as const, skip: Math.max(page, 0) * rowsPerPage, limit: rowsPerPage }; }; - findByTeamId = async (teamId: string, config: TeamQueryConfig): Promise => { + findByTeamId = async (teamId: string, config: TeamQueryConfig): Promise => { const query = this.queryBuilder(config, teamId); const { sort, skip, limit } = this.pageOptions(config); const documents = await MonitorModel.find(query).sort(sort).skip(skip).limit(limit); return this.mapDocuments(documents); }; - findByTeamIdWithStats = async (teamId: string, config: TeamQueryConfig): Promise => { + findByTeamIdWithStats = async (teamId: string, config: TeamQueryConfig): Promise => { const { sort, skip, limit } = this.pageOptions(config); const query = this.queryBuilder(config, teamId); diff --git a/server/src/domain/monitors/monitor.service.ts b/server/src/domain/monitors/monitor.service.ts index 711fc9b9b..178da5225 100644 --- a/server/src/domain/monitors/monitor.service.ts +++ b/server/src/domain/monitors/monitor.service.ts @@ -1,5 +1,5 @@ import { NormalizeData, NormalizeDataUptimeDetails } from "@/utils/dataUtils.js"; -import { type Monitor } from "@/domain/monitors/monitor.types.js"; +import { type Monitor } from "@/domain/monitors/monitor.type.js"; import type { MonitorType, MonitorsWithChecksByTeamIdResult, @@ -8,8 +8,8 @@ import type { PageSpeedDetailsResult, GamesMap, GroupedGeoCheckResult, -} from "@/domain/monitors/monitor.types.js"; -import { supportsGeoCheck, supportsUptimeDetails } from "@/domain/monitors/monitor.types.js"; +} from "@/domain/monitors/monitor.type.js"; +import { supportsGeoCheck, supportsUptimeDetails } from "@/domain/monitors/monitor.type.js"; import type { UptimeChecksResult, HardwareChecksResult, PageSpeedChecksResult } from "@/domain/checks/check.type.js"; import type { GeoContinent } from "@/domain/geo-checks/geo-check.type.js"; import type { IChecksRepository } from "@/domain/checks/check.repository.interface.js"; @@ -318,7 +318,7 @@ export class MonitorService implements IMonitorService { type?: MonitorType | MonitorType[]; tags?: string | string[]; filter?: string; - }): Promise => { + }): Promise => { return await this.monitorsRepository.findByTeamId(teamId, { type, tags, filter }); }; @@ -356,13 +356,12 @@ export class MonitorService implements IMonitorService { order, }); - const monitorsList = (monitors ?? []) as Monitor[]; const snapshotTypes: MonitorType[] = ["hardware"]; const requestedTypes = Array.isArray(type) ? type : type ? [type] : []; const snapshotOnlyRequest = requestedTypes.length > 0 && requestedTypes.every((requestedType) => snapshotTypes.includes(requestedType as MonitorType)); - const monitorsWithChecks = monitorsList.map((monitor: Monitor) => { + const monitorsWithChecks = monitors.map((monitor: Monitor) => { const rawChecks = monitor.recentChecks ?? []; const isSnapshotType = snapshotOnlyRequest || snapshotTypes.includes(monitor.type); const checks = isSnapshotType ? rawChecks.slice(0, 1) : NormalizeData(rawChecks, 10, 100); @@ -523,7 +522,7 @@ export class MonitorService implements IMonitorService { exportMonitorsToJSON = async ({ teamId }: { teamId: string }): Promise => { const monitors = await this.monitorsRepository.findByTeamId(teamId, {}); - if (!monitors || monitors.length === 0) { + if (monitors.length === 0) { throw new AppError({ message: "No monitors found to export.", service: SERVICE_NAME, method: "exportMonitorsToJSON", status: 400 }); } diff --git a/server/src/domain/monitors/monitor.types.ts b/server/src/domain/monitors/monitor.type.ts similarity index 87% rename from server/src/domain/monitors/monitor.types.ts rename to server/src/domain/monitors/monitor.type.ts index 22090f68c..865bafd76 100644 --- a/server/src/domain/monitors/monitor.types.ts +++ b/server/src/domain/monitors/monitor.type.ts @@ -3,6 +3,7 @@ export type { CheckSnapshot } from "@/domain/checks/check.type.js"; import type { GeoContinent, GroupedGeoCheck } from "@/domain/geo-checks/geo-check.type.js"; export type { GeoContinent } from "@/domain/geo-checks/geo-check.type.js"; import http from "node:http"; +import { HardwareStats } from "@/domain/checks/check.type.js"; export const HttpStatusCodes = [ ...Object.keys(http.STATUS_CODES).map(Number), @@ -149,48 +150,6 @@ export interface UptimeDetailsResult { monitorStats: import("../monitor-stats/monitor-stats.type.js").MonitorStats | null; } -export interface HardwareDiskStats { - name: string; - readSpeed: number; - writeSpeed: number; - totalBytes: number; - freeBytes: number; - usagePercent: number; -} - -export interface HardwareNetStats { - name: string; - bytesSentPerSecond: number; - deltaBytesRecv: number; - deltaPacketsSent: number; - deltaPacketsRecv: number; - deltaErrIn: number; - deltaErrOut: number; - deltaDropIn: number; - deltaDropOut: number; - deltaFifoIn: number; - deltaFifoOut: number; -} - -export interface HardwareCheckStats { - bucketDate: string; - avgCpuUsage: number; - avgMemoryUsage: number; - avgTemperature: number[]; - disks: HardwareDiskStats[]; - net: HardwareNetStats[]; -} - -export interface HardwareStats { - aggregateData: { - totalChecks: number; - }; - upChecks: { - totalChecks: number; - }; - checks: HardwareCheckStats[]; -} - export interface HardwareDetailsResult { monitor: Monitor; stats: HardwareStats; diff --git a/server/src/domain/notifications/notification.message-builder.ts b/server/src/domain/notifications/notification.message-builder.ts index b11d99a94..76e9f6447 100644 --- a/server/src/domain/notifications/notification.message-builder.ts +++ b/server/src/domain/notifications/notification.message-builder.ts @@ -1,4 +1,4 @@ -import type { Monitor } from "@/domain/monitors/monitor.types.js"; +import type { Monitor } from "@/domain/monitors/monitor.type.js"; import type { HardwareStatusPayload, MonitorStatusResponse } from "@/types/network.js"; import type { MonitorActionDecision } from "@/worker/worker.helper.js"; import type { diff --git a/server/src/domain/notifications/notification.service.ts b/server/src/domain/notifications/notification.service.ts index 30141c3ea..61d8d09e3 100644 --- a/server/src/domain/notifications/notification.service.ts +++ b/server/src/domain/notifications/notification.service.ts @@ -1,4 +1,4 @@ -import type { Monitor } from "@/domain/monitors/monitor.types.js"; +import type { Monitor } from "@/domain/monitors/monitor.type.js"; import type { Notification } from "@/domain/notifications/notification.type.js"; import type { MonitorStatusResponse } from "@/types/network.js"; import type { NotificationMessage } from "@/domain/notifications/notification.type.js"; diff --git a/server/src/domain/status-pages/status-page.service.ts b/server/src/domain/status-pages/status-page.service.ts index f7827041a..834f87384 100644 --- a/server/src/domain/status-pages/status-page.service.ts +++ b/server/src/domain/status-pages/status-page.service.ts @@ -9,7 +9,7 @@ import { } from "@/domain/status-pages/status-page.type.js"; import { AppError } from "@/utils/AppError.js"; import { normalizeStatusPageDomain } from "@/utils/statusPageDomain.js"; -import { Monitor } from "@/domain/monitors/monitor.types.js"; +import { Monitor } from "@/domain/monitors/monitor.type.js"; import { NormalizeData } from "@/utils/dataUtils.js"; export interface IStatusPageService { diff --git a/server/src/domain/status-pages/status-page.type.ts b/server/src/domain/status-pages/status-page.type.ts index d4642af17..65f331ad9 100644 --- a/server/src/domain/status-pages/status-page.type.ts +++ b/server/src/domain/status-pages/status-page.type.ts @@ -1,4 +1,4 @@ -import type { Monitor } from "@/domain/monitors/monitor.types.js"; +import type { Monitor } from "@/domain/monitors/monitor.type.js"; import type { NormalizedCheck, CheckSnapshot } from "@/domain/checks/check.type.js"; export const StatusPageTypes = ["uptime", "infrastructure"] as const; export type StatusPageType = (typeof StatusPageTypes)[number]; diff --git a/server/src/service/globalPingService.ts b/server/src/service/globalPingService.ts index 4b0257df4..5a175485f 100644 --- a/server/src/service/globalPingService.ts +++ b/server/src/service/globalPingService.ts @@ -1,6 +1,6 @@ import type { GeoContinent, GeoCheckResult, GeoCheckTimings, GeoCheckLocation } from "@/domain/geo-checks/geo-check.type.js"; -import { supportsGeoCheck, type HttpStatusCode } from "@/domain/monitors/monitor.types.js"; -import { MonitorType } from "@/domain/monitors/monitor.types.js"; +import { supportsGeoCheck, type HttpStatusCode } from "@/domain/monitors/monitor.type.js"; +import { MonitorType } from "@/domain/monitors/monitor.type.js"; import type { ILogger } from "@/utils/logger.js"; import got from "got"; import { isStatusUp } from "@/service/network/utils.js"; diff --git a/server/src/service/network/AdvancedMatcher.ts b/server/src/service/network/AdvancedMatcher.ts index 8e77ef3ec..af0195061 100644 --- a/server/src/service/network/AdvancedMatcher.ts +++ b/server/src/service/network/AdvancedMatcher.ts @@ -1,4 +1,4 @@ -import { Monitor } from "@/domain/monitors/monitor.types.js"; +import { Monitor } from "@/domain/monitors/monitor.type.js"; import jmespath from "jmespath"; import RE2 from "re2"; type JmesPath = typeof jmespath; diff --git a/server/src/service/network/DNSProvider.ts b/server/src/service/network/DNSProvider.ts index ff136db0e..10eff8d74 100644 --- a/server/src/service/network/DNSProvider.ts +++ b/server/src/service/network/DNSProvider.ts @@ -1,7 +1,7 @@ import { DNSStatusPayload, MonitorStatusResponse } from "@/types/network.js"; import { IStatusProvider } from "@/service/network/IStatusProvider.js"; import type { Resolver } from "dns/promises"; -import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js"; +import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js"; import { AppError } from "@/utils/AppError.js"; import { timeRequest } from "@/service/network/utils.js"; import { NETWORK_ERROR } from "@/types/network.js"; diff --git a/server/src/service/network/DockerProvider.ts b/server/src/service/network/DockerProvider.ts index 5e5d7b630..9f2a99de7 100644 --- a/server/src/service/network/DockerProvider.ts +++ b/server/src/service/network/DockerProvider.ts @@ -1,6 +1,6 @@ import { IStatusProvider } from "@/service/network/IStatusProvider.js"; import { DockerStatusPayload, MonitorStatusResponse } from "@/types/network.js"; -import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js"; +import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js"; import { ILogger } from "@/utils/logger.js"; import { AppError } from "@/utils/AppError.js"; import Dockerode from "dockerode"; diff --git a/server/src/service/network/GameProvider.ts b/server/src/service/network/GameProvider.ts index 1a07de791..5ccfaee6e 100644 --- a/server/src/service/network/GameProvider.ts +++ b/server/src/service/network/GameProvider.ts @@ -1,6 +1,6 @@ import { IStatusProvider } from "@/service/network/IStatusProvider.js"; import { GameStatusPayload, MonitorStatusResponse } from "@/types/network.js"; -import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js"; +import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js"; import { GameDig } from "gamedig"; import { AppError } from "@/utils/AppError.js"; import { NETWORK_ERROR } from "@/types/network.js"; diff --git a/server/src/service/network/GrpcProvider.ts b/server/src/service/network/GrpcProvider.ts index 4e79cef7f..340fdc01a 100644 --- a/server/src/service/network/GrpcProvider.ts +++ b/server/src/service/network/GrpcProvider.ts @@ -1,6 +1,6 @@ import { IStatusProvider } from "@/service/network/IStatusProvider.js"; import { GrpcStatusPayload, MonitorStatusResponse } from "@/types/network.js"; -import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js"; +import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js"; import { AppError } from "@/utils/AppError.js"; import { timeRequest } from "@/service/network/utils.js"; import * as grpc from "@grpc/grpc-js"; diff --git a/server/src/service/network/HardwareProvider.ts b/server/src/service/network/HardwareProvider.ts index c612bdbad..840dbc2e8 100644 --- a/server/src/service/network/HardwareProvider.ts +++ b/server/src/service/network/HardwareProvider.ts @@ -1,6 +1,6 @@ import { IStatusProvider } from "@/service/network/IStatusProvider.js"; import { HardwareStatusPayload, MonitorStatusResponse } from "@/types/network.js"; -import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js"; +import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js"; import { HttpProvider } from "@/service/network/HttpProvider.js"; import { AppError } from "@/utils/AppError.js"; diff --git a/server/src/service/network/HttpProvider.ts b/server/src/service/network/HttpProvider.ts index fb974cac1..b1debd969 100644 --- a/server/src/service/network/HttpProvider.ts +++ b/server/src/service/network/HttpProvider.ts @@ -5,7 +5,7 @@ import { HttpStatusPayload } from "@/types/network.js"; import { MonitorStatusResponse } from "@/types/network.js"; import { Agent as HttpsAgent } from "https"; import { Agent as HttpAgent } from "http"; -import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js"; +import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js"; import { isStatusUp } from "@/service/network/utils.js"; import { NETWORK_ERROR } from "@/types/network.js"; import CacheableLookup from "cacheable-lookup"; diff --git a/server/src/service/network/IStatusProvider.ts b/server/src/service/network/IStatusProvider.ts index f077ff9b5..6da91b30f 100644 --- a/server/src/service/network/IStatusProvider.ts +++ b/server/src/service/network/IStatusProvider.ts @@ -1,4 +1,4 @@ -import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js"; +import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js"; import { MonitorStatusResponse } from "@/types/network.js"; export interface IStatusProvider { diff --git a/server/src/service/network/PageSpeedProvider.ts b/server/src/service/network/PageSpeedProvider.ts index a609ca80b..dfa29a5c9 100644 --- a/server/src/service/network/PageSpeedProvider.ts +++ b/server/src/service/network/PageSpeedProvider.ts @@ -1,6 +1,6 @@ import { IStatusProvider } from "@/service/network/IStatusProvider.js"; import { MonitorStatusResponse, PageSpeedStatusPayload } from "@/types/network.js"; -import { Monitor, MonitorType, DefaultPageSpeedStrategy } from "@/domain/monitors/monitor.types.js"; +import { Monitor, MonitorType, DefaultPageSpeedStrategy } from "@/domain/monitors/monitor.type.js"; import { HttpProvider } from "@/service/network/HttpProvider.js"; import { ISettingsService } from "@/domain/app-settings/app-settings.service.js"; import { ILogger } from "@/utils/logger.js"; diff --git a/server/src/service/network/PingProvider.ts b/server/src/service/network/PingProvider.ts index ee66046f9..53f6aad0d 100644 --- a/server/src/service/network/PingProvider.ts +++ b/server/src/service/network/PingProvider.ts @@ -1,6 +1,6 @@ import { PingStatusPayload } from "@/types/network.js"; import { IStatusProvider } from "./IStatusProvider.js"; -import { MonitorType, Monitor } from "@/domain/monitors/monitor.types.js"; +import { MonitorType, Monitor } from "@/domain/monitors/monitor.type.js"; import { MonitorStatusResponse } from "@/types/network.js"; import { AppError } from "@/utils/AppError.js"; import ping from "ping"; diff --git a/server/src/service/network/PortProvider.ts b/server/src/service/network/PortProvider.ts index b59eb5907..692ca40af 100644 --- a/server/src/service/network/PortProvider.ts +++ b/server/src/service/network/PortProvider.ts @@ -1,6 +1,6 @@ import { IStatusProvider } from "@/service/network/IStatusProvider.js"; import { PortStatusPayload, MonitorStatusResponse } from "@/types/network.js"; -import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js"; +import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js"; import { AppError } from "@/utils/AppError.js"; import { timeRequest } from "@/service/network/utils.js"; import { NETWORK_ERROR } from "@/types/network.js"; diff --git a/server/src/service/network/WebSocketProvider.ts b/server/src/service/network/WebSocketProvider.ts index b599e6fab..d27106989 100644 --- a/server/src/service/network/WebSocketProvider.ts +++ b/server/src/service/network/WebSocketProvider.ts @@ -1,6 +1,6 @@ import { IStatusProvider } from "@/service/network/IStatusProvider.js"; import { WebSocketStatusPayload, MonitorStatusResponse } from "@/types/network.js"; -import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js"; +import { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js"; import { AppError } from "@/utils/AppError.js"; import { timeRequest } from "@/service/network/utils.js"; import { NETWORK_ERROR } from "@/types/network.js"; diff --git a/server/src/service/network/utils.ts b/server/src/service/network/utils.ts index 5a23a9412..1a0e157ea 100644 --- a/server/src/service/network/utils.ts +++ b/server/src/service/network/utils.ts @@ -1,4 +1,4 @@ -import type { HttpStatusCode } from "@/domain/monitors/monitor.types.js"; +import type { HttpStatusCode } from "@/domain/monitors/monitor.type.js"; export const timeRequest = async (operation: () => Promise): Promise<{ response: T | null; responseTime: number; error: unknown }> => { const start = process.hrtime.bigint(); diff --git a/server/src/service/networkService.ts b/server/src/service/networkService.ts index ec54b8e49..75ff66bda 100644 --- a/server/src/service/networkService.ts +++ b/server/src/service/networkService.ts @@ -1,4 +1,4 @@ -import type { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js"; +import type { Monitor, MonitorType } from "@/domain/monitors/monitor.type.js"; import type { MonitorPayloadMap, MonitorStatusResponse } from "@/types/network.js"; import type { AxiosStatic } from "axios"; import { AppError } from "@/utils/AppError.js"; diff --git a/server/src/service/statusService.ts b/server/src/service/statusService.ts index 6435958cb..748960a37 100755 --- a/server/src/service/statusService.ts +++ b/server/src/service/statusService.ts @@ -1,7 +1,7 @@ import { IMonitorStatsRepository } from "@/domain/monitor-stats/monitor-stats.repository.interface.js"; import { IMonitorsRepository } from "@/domain/monitors/monitor.repository.interface.js"; import type { Check, CheckDiskInfo, CheckSnapshot } from "@/domain/checks/check.type.js"; -import type { Monitor, MonitorStatus } from "@/domain/monitors/monitor.types.js"; +import type { Monitor, MonitorStatus } from "@/domain/monitors/monitor.type.js"; import type { DockerStatusPayload, GameStatusPayload, @@ -17,7 +17,7 @@ import type { import { AppError } from "@/utils/AppError.js"; import { ILogger } from "@/utils/logger.js"; import type { HardwareStatusMetrics } from "@/types/network.js"; -import { MAX_RECENT_CHECKS } from "@/domain/monitors/monitor.types.js"; +import { MAX_RECENT_CHECKS } from "@/domain/monitors/monitor.type.js"; const SERVICE_NAME = "StatusService"; const HARDWARE_ALERT_COUNTER_START = 5; diff --git a/server/src/types/network.ts b/server/src/types/network.ts index b5dc1d949..2839ed95f 100644 --- a/server/src/types/network.ts +++ b/server/src/types/network.ts @@ -9,7 +9,7 @@ import type { GotTimings, ILighthouseAudit, } from "@/domain/checks/check.type.js"; -import type { DnsRecordType, Monitor, MonitorMatchMethod, MonitorStatus, MonitorType } from "@/domain/monitors/monitor.types.js"; +import type { DnsRecordType, Monitor, MonitorMatchMethod, MonitorStatus, MonitorType } from "@/domain/monitors/monitor.type.js"; import type { QueryResult } from "gamedig"; diff --git a/server/src/worker/worker.check-evaluator.ts b/server/src/worker/worker.check-evaluator.ts index 34c444271..da7e13dbe 100644 --- a/server/src/worker/worker.check-evaluator.ts +++ b/server/src/worker/worker.check-evaluator.ts @@ -1,7 +1,7 @@ import { MonitorStatusResponse } from "@/types/network.js"; import { MonitorEvaluation } from "@/worker/worker.interface.js"; import { Check } from "@/domain/checks/check.type.js"; -import { Monitor } from "@/domain/monitors/monitor.types.js"; +import { Monitor } from "@/domain/monitors/monitor.type.js"; import { IMonitorStatusPolicy } from "@/worker/worker.monitor-status-policy.js"; import { IStatusService } from "@/service/statusService.js"; diff --git a/server/src/worker/worker.check-pipeline.ts b/server/src/worker/worker.check-pipeline.ts index 045cea1ad..9b97de354 100644 --- a/server/src/worker/worker.check-pipeline.ts +++ b/server/src/worker/worker.check-pipeline.ts @@ -1,11 +1,11 @@ -import { Monitor } from "@/domain/monitors/monitor.types.js"; +import { Monitor } from "@/domain/monitors/monitor.type.js"; import { MonitorEvaluation } from "@/worker/worker.interface.js"; import { IMaintenanceWindowsRepository } from "@/domain/maintenance-windows/maintenance-window.repository.interface.js"; import { isWindowActive } from "@/utils/maintenanceWindow.js"; import { ILogger } from "@/utils/logger.js"; import { IBufferService } from "@/service/bufferService.js"; import { AppError } from "@/utils/AppError.js"; -import { supportsGeoCheck } from "@/domain/monitors/monitor.types.js"; +import { supportsGeoCheck } from "@/domain/monitors/monitor.type.js"; import { IGeoChecksService } from "@/domain/geo-checks/geo-check.service.js"; const SERVICE_NAME = "CheckPipeline"; diff --git a/server/src/worker/worker.check-producer.ts b/server/src/worker/worker.check-producer.ts index 3365ea93b..b73e2c6de 100644 --- a/server/src/worker/worker.check-producer.ts +++ b/server/src/worker/worker.check-producer.ts @@ -1,4 +1,4 @@ -import { Monitor } from "@/domain/monitors/monitor.types.js"; +import { Monitor } from "@/domain/monitors/monitor.type.js"; import { Check } from "@/domain/checks/check.type.js"; import { MonitorStatusResponse } from "@/types/network.js"; import { AppError } from "@/utils/AppError.js"; diff --git a/server/src/worker/worker.interface.ts b/server/src/worker/worker.interface.ts index e70af5f35..bb6cb0c53 100644 --- a/server/src/worker/worker.interface.ts +++ b/server/src/worker/worker.interface.ts @@ -1,4 +1,4 @@ -import { Monitor } from "@/domain/monitors/monitor.types.js"; +import { Monitor } from "@/domain/monitors/monitor.type.js"; import { Check } from "@/domain/checks/check.type.js"; import { JobType } from "@/domain/jobs/job.type.js"; import { MonitorPayloadMap, MonitorStatusResponse, StatusChangeResult } from "@/types/network.js"; diff --git a/server/src/worker/worker.job-scheduler.ts b/server/src/worker/worker.job-scheduler.ts index 433e69955..8d103e87f 100644 --- a/server/src/worker/worker.job-scheduler.ts +++ b/server/src/worker/worker.job-scheduler.ts @@ -1,7 +1,7 @@ import { IJobScheduler } from "@/worker/worker.interface.js"; import { IJobsRepository } from "@/domain/jobs/job.repository.interface.js"; import { IMonitorsRepository } from "@/domain/monitors/monitor.repository.interface.js"; -import { Monitor, supportsGeoCheck } from "@/domain/monitors/monitor.types.js"; +import { Monitor, supportsGeoCheck } from "@/domain/monitors/monitor.type.js"; import { type Job, type JobSeed, type JobType, jobId } from "@/domain/jobs/job.type.js"; import { IQueueWorkersRepository } from "@/domain/queue-workers/queue-worker.repository.interface.js"; import { WorkerJobsPagination, WorkerJobSummary, WorkerMetrics } from "@/worker/worker.interface.js"; @@ -187,7 +187,7 @@ export class JobScheduler implements IJobScheduler { // Seed queue protected reconcile = async () => { const now = Date.now(); - const monitors = (await this.monitorsRepository.findAll()) ?? []; + const monitors = await this.monitorsRepository.findAll(); for (const monitor of monitors) { await this.jobsRepository.upsertJob(this.toCheckJob(monitor, now)); if (supportsGeoCheck(monitor.type) && monitor.geoCheckEnabled) {