extract swtich

This commit is contained in:
Alex Holliday committed 2026-07-24 11:09:53 -07:00
1 parent 86eeda3f0e
commit c021d04f53
13 files changed
+56 -80

No files matched your search

@@ -8,7 +8,7 @@ import type {
} from "@/domain/checks/check.type.js";
import type { MonitorType } from "@/domain/monitors/monitor.types.js";
import type { LatestChecksMap } from "@/domain/checks/check.repository.mongo.js";
import { DateRange } from "@/types/query.js";
import { CheckFilter, DateRange } from "@/types/query.js";
export interface IChecksRepository {
// create
@@ -21,18 +21,18 @@ export interface IChecksRepository {
monitorId: string,
sortOrder: string,
dateRange: DateRange,
filter: string | undefined,
page: number,
rowsPerPage: number,
status: boolean | undefined
status: boolean | undefined,
filter?: CheckFilter
): Promise<ChecksQueryResult>;
findByTeamId(
sortOrder: string,
dateRange: DateRange,
filter: string | undefined,
page: number,
rowsPerPage: number,
teamId: string
teamId: string,
filter?: CheckFilter
): Promise<ChecksQueryResult>;
findLatestByMonitorIds(monitorIds: string[], options?: { limitPerMonitor?: number }): Promise<LatestChecksMap>;
findByDateRangeAndMonitorId(
@@ -20,8 +20,9 @@ import { ILogger } from "@/utils/logger.js";
import { toStringId, toDateString } from "@/utils/mongoMappers.js";
import { getHardwareUpChecks, getHardwareStats, getHardwareTotalChecks } from "@/domain/checks/check.hardware.aggregations.js";
import { DateRange } from "@/types/query.js";
import { CheckFilter, DateRange } from "@/types/query.js";
import { AppError } from "@/utils/AppError.js";
import { NETWORK_ERROR } from "@/types/network.js";
const SERVICE_NAME = "StatusService";
@@ -211,46 +212,41 @@ class MongoChecksRepository implements IChecksRepository {
return this.mapDocuments(inserted as unknown as CheckDocument[]);
};
private filterToMatch = (filter: CheckFilter | undefined): Record<string, unknown> => {
switch (filter) {
case "up":
return { status: true };
case "down":
return { status: false };
case "resolve":
return { status: false, statusCode: NETWORK_ERROR };
default:
this.logger.warn({
message: "invalid filter",
service: SERVICE_NAME,
method: "filterToMatch",
});
return {};
}
};
findByMonitorId = async (
monitorId: string,
sortOrder: string,
dateRange: DateRange,
filter: string | undefined,
page: number,
rowsPerPage: number,
status: boolean | undefined
status: boolean | undefined,
filter?: CheckFilter
) => {
// Match
const matchStage: Record<string, unknown> = {
"metadata.monitorId": new mongoose.Types.ObjectId(monitorId),
...(typeof status !== "undefined" && { status }),
createdAt: { $gte: getDateForRange(dateRange) },
...this.filterToMatch(filter),
};
if (filter !== undefined) {
switch (filter) {
case "all":
break;
case "up":
matchStage.status = true;
break;
case "down":
matchStage.status = false;
break;
case "resolve":
matchStage.status = false;
matchStage.statusCode = 5000;
break;
default:
this.logger.warn({
message: "invalid filter",
service: SERVICE_NAME,
method: "getChecks",
});
break;
}
}
//Sort
const convertedSortOrder = sortOrder === "asc" ? 1 : -1;
@@ -268,35 +264,12 @@ class MongoChecksRepository implements IChecksRepository {
return { checksCount, checks: this.mapDocuments(checks) };
};
findByTeamId = async (sortOrder: string, dateRange: DateRange, filter: string, page: number, rowsPerPage: number, teamId: string) => {
findByTeamId = async (sortOrder: string, dateRange: DateRange, page: number, rowsPerPage: number, teamId: string, filter?: CheckFilter) => {
const matchStage: Record<string, unknown> = {
"metadata.teamId": new mongoose.Types.ObjectId(teamId),
createdAt: { $gte: getDateForRange(dateRange) },
...this.filterToMatch(filter),
};
// Add filter to match stage
if (filter !== undefined) {
switch (filter) {
case "all":
break;
case "up":
matchStage.status = true;
break;
case "down":
matchStage.status = false;
break;
case "resolve":
matchStage.status = false;
matchStage.statusCode = 5000;
break;
default:
this.logger.warn({
message: "invalid filter",
service: SERVICE_NAME,
method: "getChecksByTeam",
});
break;
}
}
const parsedSortOrder = sortOrder === "asc" ? 1 : -1;
+8 -8
View File
@@ -6,7 +6,7 @@ import type { MonitorPayloadMap, MonitorStatusResponse } from "@/types/network.j
import type { HardwareStatusPayload, PageSpeedStatusPayload } from "@/types/network.js";
import { AppError } from "@/utils/AppError.js";
import { ILogger } from "@/utils/logger.js";
import { DateRange } from "@/types/query.js";
import { CheckFilter, DateRange } from "@/types/query.js";
const SERVICE_NAME = "checkService";
@@ -22,7 +22,7 @@ export interface ICheckService {
dateRange: DateRange;
page: number;
rowsPerPage: number;
filter?: string;
filter?: CheckFilter;
status?: boolean;
}): Promise<ChecksQueryResult>;
getChecksByTeam(params: {
@@ -31,7 +31,7 @@ export interface ICheckService {
dateRange: DateRange;
page: number;
rowsPerPage: number;
filter?: string;
filter?: CheckFilter;
}): Promise<ChecksQueryResult>;
getChecksSummaryByTeamId(params: { teamId: string; dateRange: DateRange }): Promise<ChecksSummary>;
deleteChecks(params: { monitorId: string; teamId: string }): Promise<number>;
@@ -169,7 +169,7 @@ export class CheckService implements ICheckService {
page: number;
rowsPerPage: number;
status?: boolean;
filter?: string;
filter: CheckFilter;
}) => {
if (!monitorId) {
throw new AppError({ message: "No monitor ID in request", service: SERVICE_NAME, method: "getChecksByMonitor", status: 400 });
@@ -184,7 +184,7 @@ export class CheckService implements ICheckService {
const parsedPage = page ?? 0;
const parsedRowsPerPage = rowsPerPage ?? 5;
const result = await this.checksRepository.findByMonitorId(monitorId, sortOrder, dateRange, filter, parsedPage, parsedRowsPerPage, status);
const result = await this.checksRepository.findByMonitorId(monitorId, sortOrder, dateRange, parsedPage, parsedRowsPerPage, status, filter);
return result;
};
@@ -193,21 +193,21 @@ export class CheckService implements ICheckService {
teamId,
sortOrder,
dateRange,
filter,
page,
rowsPerPage,
filter,
}: {
teamId: string;
sortOrder: string;
dateRange: DateRange;
page: number;
rowsPerPage: number;
filter?: string;
filter?: CheckFilter;
}) => {
const parsedPage = page ?? 0;
const parsedRowsPerPage = rowsPerPage ?? 5;
const checkData = await this.checksRepository.findByTeamId(sortOrder, dateRange, filter, parsedPage, parsedRowsPerPage, teamId);
const checkData = await this.checksRepository.findByTeamId(sortOrder, dateRange, parsedPage, parsedRowsPerPage, teamId, filter);
return checkData;
};
+2 -1
View File
@@ -3,7 +3,8 @@ import { IStatusProvider } from "@/service/network/IStatusProvider.js";
import type { Resolver } from "dns/promises";
import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js";
import { AppError } from "@/utils/AppError.js";
import { NETWORK_ERROR, timeRequest } from "@/service/network/utils.js";
import { timeRequest } from "@/service/network/utils.js";
import { NETWORK_ERROR } from "@/types/network.js";
const SERVICE_NAME = "DNSProvider";
+2 -2
View File
@@ -4,8 +4,8 @@ import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js";
import { ILogger } from "@/utils/logger.js";
import { AppError } from "@/utils/AppError.js";
import Dockerode from "dockerode";
import { NETWORK_ERROR, timeRequest } from "@/service/network/utils.js";
import { timeRequest } from "@/service/network/utils.js";
import { NETWORK_ERROR } from "@/types/network.js";
type DockerodeType = typeof Dockerode;
const SERVICE_NAME = "DockerProvider";
+1 -1
View File
@@ -3,7 +3,7 @@ import { GameStatusPayload, MonitorStatusResponse } from "@/types/network.js";
import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js";
import { GameDig } from "gamedig";
import { AppError } from "@/utils/AppError.js";
import { NETWORK_ERROR } from "@/service/network/utils.js";
import { NETWORK_ERROR } from "@/types/network.js";
import { ILogger } from "@/utils/logger.js";
type GameDigType = typeof GameDig;
+2 -1
View File
@@ -6,7 +6,8 @@ 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 { NETWORK_ERROR, isStatusUp } from "@/service/network/utils.js";
import { isStatusUp } from "@/service/network/utils.js";
import { NETWORK_ERROR } from "@/types/network.js";
import CacheableLookup from "cacheable-lookup";
export class HttpProvider implements IStatusProvider<HttpStatusPayload> {
+2 -1
View File
@@ -2,7 +2,8 @@ import { IStatusProvider } from "@/service/network/IStatusProvider.js";
import { PortStatusPayload, MonitorStatusResponse } from "@/types/network.js";
import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js";
import { AppError } from "@/utils/AppError.js";
import { NETWORK_ERROR, timeRequest } from "@/service/network/utils.js";
import { timeRequest } from "@/service/network/utils.js";
import { NETWORK_ERROR } from "@/types/network.js";
import * as net from "net";
type NetType = typeof net;
@@ -2,7 +2,8 @@ import { IStatusProvider } from "@/service/network/IStatusProvider.js";
import { WebSocketStatusPayload, MonitorStatusResponse } from "@/types/network.js";
import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js";
import { AppError } from "@/utils/AppError.js";
import { NETWORK_ERROR, timeRequest } from "@/service/network/utils.js";
import { timeRequest } from "@/service/network/utils.js";
import { NETWORK_ERROR } from "@/types/network.js";
import type WebSocket from "ws";
type WebSocketConstructor = typeof WebSocket;
-3
View File
@@ -12,9 +12,6 @@ export const timeRequest = async <T>(operation: () => Promise<T>): Promise<{ res
}
};
export const NETWORK_ERROR = 5000;
export const PING_ERROR = 5001;
export const isStatusUp = (statusCode: number | undefined, customUpCodes: HttpStatusCode[] = []): boolean => {
if (statusCode === undefined) return false;
return (statusCode >= 200 && statusCode < 300) || customUpCodes.includes(statusCode);
+1 -1
View File
@@ -2,7 +2,7 @@ import type { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js";
import type { MonitorPayloadMap, MonitorStatusResponse } from "@/types/network.js";
import type { AxiosStatic } from "axios";
import { AppError } from "@/utils/AppError.js";
import { NETWORK_ERROR } from "@/service/network/utils.js";
import { NETWORK_ERROR } from "@/types/network.js";
import { ILogger } from "@/utils/logger.js";
import { IStatusProvider } from "./network/IStatusProvider.js";
const SERVICE_NAME = "NetworkService";
+2
View File
@@ -13,6 +13,8 @@ import type { DnsRecordType, Monitor, MonitorMatchMethod, MonitorStatus, Monitor
import type { QueryResult } from "gamedig";
export const NETWORK_ERROR = 5000;
export interface MonitorStatusResponse<
T =
| HttpStatusPayload
@@ -375,7 +375,7 @@ describe("CheckService", () => {
rowsPerPage: null as any,
});
expect(checksRepository.findByMonitorId).toHaveBeenCalledWith("mon-1", "desc", "day", undefined, 0, 5, undefined);
expect(checksRepository.findByMonitorId).toHaveBeenCalledWith("mon-1", "desc", "day", 0, 5, undefined, undefined);
});
it("passes filter and status parameters", async () => {
@@ -388,11 +388,11 @@ describe("CheckService", () => {
dateRange: "week",
page: 2,
rowsPerPage: 20,
filter: "error",
filter: "resolve",
status: false,
});
expect(checksRepository.findByMonitorId).toHaveBeenCalledWith("mon-1", "asc", "week", "error", 2, 20, false);
expect(checksRepository.findByMonitorId).toHaveBeenCalledWith("mon-1", "asc", "week", 2, 20, false, "resolve");
});
it("throws when monitorId is missing", async () => {
@@ -443,7 +443,7 @@ describe("CheckService", () => {
await service.getChecksByTeam({ teamId: "team-1", sortOrder: "desc", dateRange: "day", page: null as any, rowsPerPage: null as any });
expect(checksRepository.findByTeamId).toHaveBeenCalledWith("desc", "day", undefined, 0, 5, "team-1");
expect(checksRepository.findByTeamId).toHaveBeenCalledWith("desc", "day", 0, 5, "team-1", undefined);
});
});