From 4e31499f78df18e459ee193b665dbe6040d0dfde Mon Sep 17 00:00:00 2001 From: harsh-aghara Date: Mon, 1 Jun 2026 00:03:03 +0530 Subject: [PATCH 01/14] feat(backend): add customUpCodes support for HTTP monitors Adds a customUpCodes field to the monitor schema to allow users to specify which HTTP status codes should be treated as UP instead of DOWN. Includes core logic in HttpProvider and unit tests. Refs #3657 --- server/src/db/models/Monitor.ts | 4 ++ .../monitors/MongoMonitorsRepository.ts | 2 + .../src/service/business/geoChecksService.ts | 2 +- .../infrastructure/globalPingService.ts | 11 ++-- .../infrastructure/network/HttpProvider.ts | 6 +- server/src/types/monitor.ts | 1 + server/src/validation/monitorValidation.ts | 4 ++ .../providers/network/httpProvider.test.ts | 64 +++++++++++++++++++ 8 files changed, 86 insertions(+), 8 deletions(-) diff --git a/server/src/db/models/Monitor.ts b/server/src/db/models/Monitor.ts index e6bffddd8..5b982c004 100644 --- a/server/src/db/models/Monitor.ts +++ b/server/src/db/models/Monitor.ts @@ -291,6 +291,10 @@ const MonitorSchema = new Schema( ref: "Tag", }, ], + customUpCodes: { + type: [Number], + default: [], + }, secret: { type: String, }, diff --git a/server/src/repositories/monitors/MongoMonitorsRepository.ts b/server/src/repositories/monitors/MongoMonitorsRepository.ts index 3d1f9c3a5..28979890f 100644 --- a/server/src/repositories/monitors/MongoMonitorsRepository.ts +++ b/server/src/repositories/monitors/MongoMonitorsRepository.ts @@ -456,6 +456,7 @@ class MongoMonitorsRepository implements IMonitorsRepository { uptimePercentage: doc.uptimePercentage ?? undefined, notifications: notificationIds, tags: tagIds, + customUpCodes: doc.customUpCodes ?? [], secret: doc.secret ?? undefined, cpuAlertThreshold: doc.cpuAlertThreshold, cpuAlertCounter: doc.cpuAlertCounter, @@ -520,6 +521,7 @@ class MongoMonitorsRepository implements IMonitorsRepository { uptimePercentage: doc.uptimePercentage ?? undefined, notifications: notificationIds, tags: tagIds, + customUpCodes: doc.customUpCodes ?? [], secret: doc.secret ?? undefined, cpuAlertThreshold: doc.cpuAlertThreshold, cpuAlertCounter: doc.cpuAlertCounter, diff --git a/server/src/service/business/geoChecksService.ts b/server/src/service/business/geoChecksService.ts index 95b945f2a..5f557506f 100644 --- a/server/src/service/business/geoChecksService.ts +++ b/server/src/service/business/geoChecksService.ts @@ -89,7 +89,7 @@ export class GeoChecksService implements IGeoChecksService { } // Step 2: Poll for results - const results = await this.globalPingService.pollForResults(measurementId); + const results = await this.globalPingService.pollForResults(measurementId, undefined, monitor.customUpCodes ?? []); if (results.length === 0) { // No successful results (all locations timed out or failed) diff --git a/server/src/service/infrastructure/globalPingService.ts b/server/src/service/infrastructure/globalPingService.ts index 41f96b286..6050cc5eb 100644 --- a/server/src/service/infrastructure/globalPingService.ts +++ b/server/src/service/infrastructure/globalPingService.ts @@ -62,7 +62,7 @@ interface GlobalPingProbeResult { export interface IGlobalPingService { readonly serviceName: string; createMeasurement(monitorType: MonitorType, url: string, locations: GeoContinent[]): Promise; - pollForResults(measurementId: string, timeoutMs?: number): Promise; + pollForResults(measurementId: string, timeoutMs?: number, customUpCodes?: number[]): Promise; } export class GlobalPingService implements IGlobalPingService { @@ -119,7 +119,7 @@ export class GlobalPingService implements IGlobalPingService { } } - async pollForResults(measurementId: string, timeoutMs: number = MAX_POLL_TIMEOUT_MS): Promise { + async pollForResults(measurementId: string, timeoutMs: number = MAX_POLL_TIMEOUT_MS, customUpCodes: number[] = []): Promise { const startTime = Date.now(); while (Date.now() - startTime < timeoutMs) { @@ -132,7 +132,7 @@ export class GlobalPingService implements IGlobalPingService { const measurement = response.body; if (measurement.status === "finished") { - const results = this.transformResults(measurement.results || []); + const results = this.transformResults(measurement.results || [], customUpCodes); this.logger.debug({ message: `GlobalPing measurement completed: ${measurementId}`, service: SERVICE_NAME, @@ -174,7 +174,7 @@ export class GlobalPingService implements IGlobalPingService { return []; } - private transformResults(probeResults: GlobalPingProbeResult[]): GeoCheckResult[] { + private transformResults(probeResults: GlobalPingProbeResult[], customUpCodes: number[] = []): GeoCheckResult[] { const successfulResults: GeoCheckResult[] = []; for (const probeResult of probeResults) { @@ -205,7 +205,8 @@ export class GlobalPingService implements IGlobalPingService { successfulResults.push({ location, - status: probeResult.result.statusCode >= 200 && probeResult.result.statusCode < 300, + status: + customUpCodes.includes(probeResult.result.statusCode) || (probeResult.result.statusCode >= 200 && probeResult.result.statusCode < 300), statusCode: probeResult.result.statusCode, timings, }); diff --git a/server/src/service/infrastructure/network/HttpProvider.ts b/server/src/service/infrastructure/network/HttpProvider.ts index bbc0934f8..2ae177819 100644 --- a/server/src/service/infrastructure/network/HttpProvider.ts +++ b/server/src/service/infrastructure/network/HttpProvider.ts @@ -31,11 +31,13 @@ export class HttpProvider implements IStatusProvider { private handleHttpError(error: unknown, monitor: Monitor): MonitorStatusResponse { if (error instanceof HTTPError || error instanceof RequestError) { + const isCustomUp = error instanceof HTTPError && (monitor.customUpCodes ?? []).includes(error.response?.statusCode); + return { monitorId: monitor.id, teamId: monitor.teamId, type: monitor.type, - status: false, + status: isCustomUp, code: error.response?.statusCode ?? NETWORK_ERROR, message: error.message, responseTime: error.timings?.phases?.total ?? 0, @@ -106,7 +108,7 @@ export class HttpProvider implements IStatusProvider { monitorId: monitor.id, teamId: monitor.teamId, type: monitor.type, - status: response.ok && matchResult.ok, + status: ((monitor.customUpCodes ?? []).includes(response.statusCode) || response.ok) && matchResult.ok, code: response.statusCode, message: matchResult.ok ? (response.statusMessage ?? "OK") : matchResult.message, responseTime: response.timings.phases.total ?? 0, diff --git a/server/src/types/monitor.ts b/server/src/types/monitor.ts index 0708297f3..415b7dff0 100644 --- a/server/src/types/monitor.ts +++ b/server/src/types/monitor.ts @@ -60,6 +60,7 @@ export interface Monitor { uptimePercentage?: number; notifications: string[]; tags: string[]; + customUpCodes: number[]; secret?: string; cpuAlertThreshold: number; cpuAlertCounter: number; diff --git a/server/src/validation/monitorValidation.ts b/server/src/validation/monitorValidation.ts index d5164b8ef..53a8ec6ca 100644 --- a/server/src/validation/monitorValidation.ts +++ b/server/src/validation/monitorValidation.ts @@ -81,6 +81,7 @@ export const createMonitorBodyValidation = z tempAlertThreshold: z.number().optional(), notifications: z.array(z.string()).optional(), tags: z.array(z.string()).optional(), + customUpCodes: z.array(z.number()).default([]), secret: z.string().optional(), jsonPath: z.union([z.string(), z.literal("")]).optional(), expectedValue: z.union([z.string(), z.literal("")]).optional(), @@ -110,6 +111,7 @@ export const editMonitorBodyValidation = z interval: z.number().optional(), notifications: z.array(z.string()).optional(), tags: z.array(z.string()).optional(), + customUpCodes: z.array(z.number()).optional(), secret: z.string().optional(), ignoreTlsErrors: z.boolean().optional(), useAdvancedMatching: z.boolean().optional(), @@ -180,6 +182,7 @@ const importedMonitorSchema = z uptimePercentage: z.number().optional(), notifications: z.array(z.string()).default([]), tags: z.array(z.string()).default([]), + customUpCodes: z.array(z.number()).default([]), secret: z.string().optional(), cpuAlertThreshold: z.number().default(100), cpuAlertCounter: z.number().default(5), @@ -241,6 +244,7 @@ export const monitorResponseSchema = z matchMethod: z.enum(MonitorMatchMethods).optional(), notifications: z.array(z.string()), tags: z.array(z.string()), + customUpCodes: z.array(z.number()).optional(), secret: z.string().optional(), cpuAlertThreshold: z.number(), memoryAlertThreshold: z.number(), diff --git a/server/test/unit/providers/network/httpProvider.test.ts b/server/test/unit/providers/network/httpProvider.test.ts index 1b814d7b2..afd3710d9 100644 --- a/server/test/unit/providers/network/httpProvider.test.ts +++ b/server/test/unit/providers/network/httpProvider.test.ts @@ -345,4 +345,68 @@ describe("HttpProvider", () => { await expect(provider.handle(makeMonitor({ url: "" }))).rejects.toThrow("URL is required for HTTP monitor"); }); }); + + // ── customUpCodes ──────────────────────────────────────────────────── + + describe("customUpCodes", () => { + it("returns status true when HTTPError status code is in customUpCodes", async () => { + const err = new HTTPError("Unauthorized"); + (err as any).response = { statusCode: 401 }; + (err as any).timings = { phases: { total: 30 } }; + mockGot.mockRejectedValue(err); + const { provider } = createProvider(); + + const result = await provider.handle(makeMonitor({ customUpCodes: [401] })); + + expect(result.status).toBe(true); + expect(result.code).toBe(401); + }); + + it("returns status false when HTTPError status code is not in customUpCodes", async () => { + const err = new HTTPError("Internal Server Error"); + (err as any).response = { statusCode: 500 }; + (err as any).timings = { phases: { total: 40 } }; + mockGot.mockRejectedValue(err); + const { provider } = createProvider(); + + const result = await provider.handle(makeMonitor({ customUpCodes: [401, 403] })); + + expect(result.status).toBe(false); + expect(result.code).toBe(500); + }); + + it("returns status false when customUpCodes is empty", async () => { + const err = new HTTPError("Unauthorized"); + (err as any).response = { statusCode: 401 }; + (err as any).timings = { phases: { total: 25 } }; + mockGot.mockRejectedValue(err); + const { provider } = createProvider(); + + const result = await provider.handle(makeMonitor({ customUpCodes: [] })); + + expect(result.status).toBe(false); + expect(result.code).toBe(401); + }); + + it("treats non-2xx success response as up when status code is in customUpCodes", async () => { + mockGot.mockResolvedValue(makeGotResponse({ ok: false, statusCode: 301, statusMessage: "Moved Permanently" })); + const { provider } = createProvider(); + + const result = await provider.handle(makeMonitor({ customUpCodes: [301] })); + + expect(result.status).toBe(true); + expect(result.code).toBe(301); + }); + + it("does not override matcher failure even when status code is in customUpCodes", async () => { + mockGot.mockResolvedValue(makeGotResponse({ ok: false, statusCode: 301 })); + const matcher = createMockMatcher({ ok: false, message: "Body mismatch" }); + const { provider } = createProvider(matcher); + + const result = await provider.handle(makeMonitor({ customUpCodes: [301] })); + + expect(result.status).toBe(false); + expect(result.message).toBe("Body mismatch"); + }); + }); }); From 87a6640c1d007aabe28d7f5001aa27f46e290c13 Mon Sep 17 00:00:00 2001 From: harsh-aghara Date: Mon, 1 Jun 2026 13:21:30 +0530 Subject: [PATCH 02/14] fix(backend): validate customUpCodes against standard HTTP status codes Addresses reviewer feedback by enforcing strict validation on the array. Previously, the Zod schema accepted any arbitrary number, which could allow invalid or self-defined HTTP codes (e.g., 5000) to be saved to the database. Refs #3657 --- server/src/validation/monitorValidation.ts | 11 ++- .../unit/validation/monitorValidation.test.ts | 90 +++++++++++++++++++ 2 files changed, 97 insertions(+), 4 deletions(-) diff --git a/server/src/validation/monitorValidation.ts b/server/src/validation/monitorValidation.ts index 53a8ec6ca..22a1a241e 100644 --- a/server/src/validation/monitorValidation.ts +++ b/server/src/validation/monitorValidation.ts @@ -2,6 +2,9 @@ import { z } from "zod"; import { booleanCoercion, dnsHostnameRegex, dnsServerValidation } from "./shared.js"; import { GeoContinents } from "@/types/geoCheck.js"; import { DnsRecordTypes, MonitorMatchMethods, MonitorStatuses, MonitorTypes, PageSpeedStrategies } from "@/types/monitor.js"; +import http from "node:http"; + +const httpStatusCode = z.number().refine((code) => code.toString() in http.STATUS_CODES, { message: "Must be a valid HTTP status code" }); export const getMonitorByIdParamValidation = z.object({ monitorId: z.string().min(1, "Monitor ID is required"), @@ -81,7 +84,7 @@ export const createMonitorBodyValidation = z tempAlertThreshold: z.number().optional(), notifications: z.array(z.string()).optional(), tags: z.array(z.string()).optional(), - customUpCodes: z.array(z.number()).default([]), + customUpCodes: z.array(httpStatusCode).default([]), secret: z.string().optional(), jsonPath: z.union([z.string(), z.literal("")]).optional(), expectedValue: z.union([z.string(), z.literal("")]).optional(), @@ -111,7 +114,7 @@ export const editMonitorBodyValidation = z interval: z.number().optional(), notifications: z.array(z.string()).optional(), tags: z.array(z.string()).optional(), - customUpCodes: z.array(z.number()).optional(), + customUpCodes: z.array(httpStatusCode).optional(), secret: z.string().optional(), ignoreTlsErrors: z.boolean().optional(), useAdvancedMatching: z.boolean().optional(), @@ -182,7 +185,7 @@ const importedMonitorSchema = z uptimePercentage: z.number().optional(), notifications: z.array(z.string()).default([]), tags: z.array(z.string()).default([]), - customUpCodes: z.array(z.number()).default([]), + customUpCodes: z.array(httpStatusCode).default([]), secret: z.string().optional(), cpuAlertThreshold: z.number().default(100), cpuAlertCounter: z.number().default(5), @@ -244,7 +247,7 @@ export const monitorResponseSchema = z matchMethod: z.enum(MonitorMatchMethods).optional(), notifications: z.array(z.string()), tags: z.array(z.string()), - customUpCodes: z.array(z.number()).optional(), + customUpCodes: z.array(httpStatusCode).optional(), secret: z.string().optional(), cpuAlertThreshold: z.number(), memoryAlertThreshold: z.number(), diff --git a/server/test/unit/validation/monitorValidation.test.ts b/server/test/unit/validation/monitorValidation.test.ts index 057ff6ae1..04cf2537e 100644 --- a/server/test/unit/validation/monitorValidation.test.ts +++ b/server/test/unit/validation/monitorValidation.test.ts @@ -222,3 +222,93 @@ describe("monitorValidation — strategy gating", () => { }); }); }); + +describe("monitorValidation — customUpCodes", () => { + const baseHttpBody = { + name: "HTTP check", + type: "http" as const, + url: "https://example.com", + }; + + describe("createMonitorBodyValidation", () => { + it("accepts valid HTTP status codes", () => { + const parsed = createMonitorBodyValidation.parse({ + ...baseHttpBody, + customUpCodes: [200, 301, 404, 503], + }); + expect(parsed.customUpCodes).toEqual([200, 301, 404, 503]); + }); + + it("rejects invalid HTTP status codes", () => { + expect(() => + createMonitorBodyValidation.parse({ + ...baseHttpBody, + customUpCodes: [5000], + }) + ).toThrow(); + + expect(() => + createMonitorBodyValidation.parse({ + ...baseHttpBody, + customUpCodes: [-1], + }) + ).toThrow(); + }); + + it("defaults to an empty array when not provided", () => { + const parsed = createMonitorBodyValidation.parse(baseHttpBody); + expect(parsed.customUpCodes).toEqual([]); + }); + }); + + describe("editMonitorBodyValidation", () => { + it("accepts valid HTTP status codes on edits", () => { + const parsed = editMonitorBodyValidation.parse({ + customUpCodes: [200, 201], + }); + expect(parsed.customUpCodes).toEqual([200, 201]); + }); + + it("rejects invalid HTTP status codes on edits", () => { + expect(() => + editMonitorBodyValidation.parse({ + customUpCodes: [9999], + }) + ).toThrow(); + }); + }); + + describe("importMonitorsBodyValidation", () => { + it("retains valid HTTP status codes on imported HTTP monitors", () => { + const parsed = importMonitorsBodyValidation.parse({ + monitors: [ + { + ...baseHttpBody, + customUpCodes: [404], + }, + ], + }); + expect(parsed.monitors[0].customUpCodes).toEqual([404]); + }); + + it("rejects invalid HTTP status codes on imported HTTP monitors", () => { + expect(() => + importMonitorsBodyValidation.parse({ + monitors: [ + { + ...baseHttpBody, + customUpCodes: [5000], + }, + ], + }) + ).toThrow(); + }); + + it("defaults to an empty array when not provided on import", () => { + const parsed = importMonitorsBodyValidation.parse({ + monitors: [baseHttpBody], + }); + expect(parsed.monitors[0].customUpCodes).toEqual([]); + }); + }); +}); From 372fc9869bd01af902dba50eeefe04fd7d5d612a Mon Sep 17 00:00:00 2001 From: harsh-aghara Date: Wed, 3 Jun 2026 23:27:10 +0530 Subject: [PATCH 03/14] refactor(monitor): address PR feedback for customUpCodes Add HttpStatusCode types and simplify provider logic --- .../src/service/infrastructure/globalPingService.ts | 12 ++++++++---- .../service/infrastructure/network/HttpProvider.ts | 10 ++++++---- server/src/types/monitor.ts | 7 ++++++- server/src/validation/monitorValidation.ts | 5 ++--- .../test/unit/providers/network/httpProvider.test.ts | 1 + 5 files changed, 23 insertions(+), 12 deletions(-) diff --git a/server/src/service/infrastructure/globalPingService.ts b/server/src/service/infrastructure/globalPingService.ts index 6050cc5eb..e261c7b19 100644 --- a/server/src/service/infrastructure/globalPingService.ts +++ b/server/src/service/infrastructure/globalPingService.ts @@ -1,5 +1,5 @@ import type { GeoContinent, GeoCheckResult, GeoCheckTimings, GeoCheckLocation } from "@/types/geoCheck.js"; -import { supportsGeoCheck } from "@/types/monitor.js"; +import { supportsGeoCheck, type HttpStatusCode } from "@/types/monitor.js"; import { MonitorType } from "@/types/index.js"; import type { ILogger } from "@/utils/logger.js"; import got from "got"; @@ -62,7 +62,7 @@ interface GlobalPingProbeResult { export interface IGlobalPingService { readonly serviceName: string; createMeasurement(monitorType: MonitorType, url: string, locations: GeoContinent[]): Promise; - pollForResults(measurementId: string, timeoutMs?: number, customUpCodes?: number[]): Promise; + pollForResults(measurementId: string, timeoutMs?: number, customUpCodes?: HttpStatusCode[]): Promise; } export class GlobalPingService implements IGlobalPingService { @@ -119,7 +119,11 @@ export class GlobalPingService implements IGlobalPingService { } } - async pollForResults(measurementId: string, timeoutMs: number = MAX_POLL_TIMEOUT_MS, customUpCodes: number[] = []): Promise { + async pollForResults( + measurementId: string, + timeoutMs: number = MAX_POLL_TIMEOUT_MS, + customUpCodes: HttpStatusCode[] = [] + ): Promise { const startTime = Date.now(); while (Date.now() - startTime < timeoutMs) { @@ -174,7 +178,7 @@ export class GlobalPingService implements IGlobalPingService { return []; } - private transformResults(probeResults: GlobalPingProbeResult[], customUpCodes: number[] = []): GeoCheckResult[] { + private transformResults(probeResults: GlobalPingProbeResult[], customUpCodes: HttpStatusCode[] = []): GeoCheckResult[] { const successfulResults: GeoCheckResult[] = []; for (const probeResult of probeResults) { diff --git a/server/src/service/infrastructure/network/HttpProvider.ts b/server/src/service/infrastructure/network/HttpProvider.ts index 2ae177819..971c4e6c2 100644 --- a/server/src/service/infrastructure/network/HttpProvider.ts +++ b/server/src/service/infrastructure/network/HttpProvider.ts @@ -31,14 +31,15 @@ export class HttpProvider implements IStatusProvider { private handleHttpError(error: unknown, monitor: Monitor): MonitorStatusResponse { if (error instanceof HTTPError || error instanceof RequestError) { - const isCustomUp = error instanceof HTTPError && (monitor.customUpCodes ?? []).includes(error.response?.statusCode); + const statusCode = error.response?.statusCode; + const statusUp = statusCode !== undefined && monitor.customUpCodes.includes(statusCode); return { monitorId: monitor.id, teamId: monitor.teamId, type: monitor.type, - status: isCustomUp, - code: error.response?.statusCode ?? NETWORK_ERROR, + status: statusUp, + code: statusCode ?? NETWORK_ERROR, message: error.message, responseTime: error.timings?.phases?.total ?? 0, timings: error.timings, @@ -104,11 +105,12 @@ export class HttpProvider implements IStatusProvider { } const matchResult = this.advancedMatcher.validate(payload, monitor); + const statusUp = monitor.customUpCodes.includes(response.statusCode) || response.ok; return { monitorId: monitor.id, teamId: monitor.teamId, type: monitor.type, - status: ((monitor.customUpCodes ?? []).includes(response.statusCode) || response.ok) && matchResult.ok, + status: statusUp && matchResult.ok, code: response.statusCode, message: matchResult.ok ? (response.statusMessage ?? "OK") : matchResult.message, responseTime: response.timings.phases.total ?? 0, diff --git a/server/src/types/monitor.ts b/server/src/types/monitor.ts index 415b7dff0..3c543616c 100644 --- a/server/src/types/monitor.ts +++ b/server/src/types/monitor.ts @@ -2,6 +2,11 @@ import type { CheckSnapshot } from "@/types/check.js"; export type { CheckSnapshot } from "@/types/check.js"; import type { GeoContinent, GroupedGeoCheck } from "@/types/geoCheck.js"; export type { GeoContinent } from "@/types/geoCheck.js"; +import http from "node:http"; + +export const HttpStatusCodes = Object.keys(http.STATUS_CODES).map(Number); +export const HttpStatusCodeSet = new Set(HttpStatusCodes); +export type HttpStatusCode = number; export const MonitorTypes = ["http", "ping", "pagespeed", "hardware", "docker", "port", "game", "grpc", "websocket", "dns", "unknown"] as const; export type MonitorType = (typeof MonitorTypes)[number]; @@ -60,7 +65,7 @@ export interface Monitor { uptimePercentage?: number; notifications: string[]; tags: string[]; - customUpCodes: number[]; + customUpCodes: HttpStatusCode[]; secret?: string; cpuAlertThreshold: number; cpuAlertCounter: number; diff --git a/server/src/validation/monitorValidation.ts b/server/src/validation/monitorValidation.ts index 22a1a241e..2d70830b7 100644 --- a/server/src/validation/monitorValidation.ts +++ b/server/src/validation/monitorValidation.ts @@ -1,10 +1,9 @@ import { z } from "zod"; import { booleanCoercion, dnsHostnameRegex, dnsServerValidation } from "./shared.js"; import { GeoContinents } from "@/types/geoCheck.js"; -import { DnsRecordTypes, MonitorMatchMethods, MonitorStatuses, MonitorTypes, PageSpeedStrategies } from "@/types/monitor.js"; -import http from "node:http"; +import { DnsRecordTypes, HttpStatusCodeSet, MonitorMatchMethods, MonitorStatuses, MonitorTypes, PageSpeedStrategies } from "@/types/monitor.js"; -const httpStatusCode = z.number().refine((code) => code.toString() in http.STATUS_CODES, { message: "Must be a valid HTTP status code" }); +const httpStatusCode = z.number().refine((code) => HttpStatusCodeSet.has(code), { message: "Must be a valid HTTP status code" }); export const getMonitorByIdParamValidation = z.object({ monitorId: z.string().min(1, "Monitor ID is required"), diff --git a/server/test/unit/providers/network/httpProvider.test.ts b/server/test/unit/providers/network/httpProvider.test.ts index afd3710d9..9252493e0 100644 --- a/server/test/unit/providers/network/httpProvider.test.ts +++ b/server/test/unit/providers/network/httpProvider.test.ts @@ -56,6 +56,7 @@ const makeMonitor = (overrides?: Partial): Monitor => useAdvancedMatching: false, matchMethod: undefined, expectedValue: undefined, + customUpCodes: [], ...overrides, }) as Monitor; From 5628c202f706d337ed0edb2ab1e5a07ae2637f8b Mon Sep 17 00:00:00 2001 From: harsh-aghara Date: Thu, 4 Jun 2026 22:43:43 +0530 Subject: [PATCH 04/14] refactor: extract isStatusUp utility to decouple from got's response.ok and modified utils test accordingly --- .../infrastructure/globalPingService.ts | 4 +- .../infrastructure/network/HttpProvider.ts | 6 +-- .../service/infrastructure/network/utils.ts | 7 ++++ .../providers/network/httpProvider.test.ts | 3 +- .../test/unit/providers/network/utils.test.ts | 38 ++++++++++++++++++- 5 files changed, 50 insertions(+), 8 deletions(-) diff --git a/server/src/service/infrastructure/globalPingService.ts b/server/src/service/infrastructure/globalPingService.ts index e261c7b19..4d7a67113 100644 --- a/server/src/service/infrastructure/globalPingService.ts +++ b/server/src/service/infrastructure/globalPingService.ts @@ -3,6 +3,7 @@ import { supportsGeoCheck, type HttpStatusCode } from "@/types/monitor.js"; import { MonitorType } from "@/types/index.js"; import type { ILogger } from "@/utils/logger.js"; import got from "got"; +import { isStatusUp } from "@/service/infrastructure/network/utils.js"; const SERVICE_NAME = "GlobalPingService"; const GLOBAL_PING_API_BASE = "https://api.globalping.io/v1"; @@ -209,8 +210,7 @@ export class GlobalPingService implements IGlobalPingService { successfulResults.push({ location, - status: - customUpCodes.includes(probeResult.result.statusCode) || (probeResult.result.statusCode >= 200 && probeResult.result.statusCode < 300), + status: isStatusUp(probeResult.result.statusCode, customUpCodes), statusCode: probeResult.result.statusCode, timings, }); diff --git a/server/src/service/infrastructure/network/HttpProvider.ts b/server/src/service/infrastructure/network/HttpProvider.ts index 971c4e6c2..73cdd6faf 100644 --- a/server/src/service/infrastructure/network/HttpProvider.ts +++ b/server/src/service/infrastructure/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 { Monitor, MonitorType } from "@/types/monitor.js"; -import { NETWORK_ERROR } from "@/service/infrastructure/network/utils.js"; +import { NETWORK_ERROR, isStatusUp } from "@/service/infrastructure/network/utils.js"; import CacheableLookup from "cacheable-lookup"; export class HttpProvider implements IStatusProvider { @@ -32,7 +32,7 @@ export class HttpProvider implements IStatusProvider { private handleHttpError(error: unknown, monitor: Monitor): MonitorStatusResponse { if (error instanceof HTTPError || error instanceof RequestError) { const statusCode = error.response?.statusCode; - const statusUp = statusCode !== undefined && monitor.customUpCodes.includes(statusCode); + const statusUp = isStatusUp(statusCode, monitor.customUpCodes); return { monitorId: monitor.id, @@ -105,7 +105,7 @@ export class HttpProvider implements IStatusProvider { } const matchResult = this.advancedMatcher.validate(payload, monitor); - const statusUp = monitor.customUpCodes.includes(response.statusCode) || response.ok; + const statusUp = isStatusUp(response.statusCode, monitor.customUpCodes); return { monitorId: monitor.id, teamId: monitor.teamId, diff --git a/server/src/service/infrastructure/network/utils.ts b/server/src/service/infrastructure/network/utils.ts index ddb962f47..994e19d9d 100644 --- a/server/src/service/infrastructure/network/utils.ts +++ b/server/src/service/infrastructure/network/utils.ts @@ -1,3 +1,5 @@ +import type { HttpStatusCode } from "@/types/monitor.js"; + export const timeRequest = async (operation: () => Promise): Promise<{ response: T | null; responseTime: number; error: unknown }> => { const start = process.hrtime.bigint(); try { @@ -12,3 +14,8 @@ export const timeRequest = async (operation: () => Promise): 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); +}; diff --git a/server/test/unit/providers/network/httpProvider.test.ts b/server/test/unit/providers/network/httpProvider.test.ts index 9252493e0..ea24b9872 100644 --- a/server/test/unit/providers/network/httpProvider.test.ts +++ b/server/test/unit/providers/network/httpProvider.test.ts @@ -254,14 +254,13 @@ describe("HttpProvider", () => { expect(result.extracted).toBe("value"); }); - it("sets status to false when response.ok is false even if matcher passes", async () => { + it("sets status to false when status code is non-2xx even if matcher passes", async () => { mockGot.mockResolvedValue(makeGotResponse({ ok: false, statusCode: 301 })); const matcher = createMockMatcher({ ok: true, message: "Success" }); const { provider } = createProvider(matcher); const result = await provider.handle(makeMonitor()); - // status = response.ok && matchResult.ok expect(result.status).toBe(false); }); }); diff --git a/server/test/unit/providers/network/utils.test.ts b/server/test/unit/providers/network/utils.test.ts index 56d8e7f9c..84427152e 100644 --- a/server/test/unit/providers/network/utils.test.ts +++ b/server/test/unit/providers/network/utils.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "@jest/globals"; -import { timeRequest, NETWORK_ERROR, PING_ERROR } from "../../../../src/service/infrastructure/network/utils.ts"; +import { timeRequest, NETWORK_ERROR, PING_ERROR, isStatusUp } from "../../../../src/service/infrastructure/network/utils.ts"; describe("network utils", () => { describe("timeRequest", () => { @@ -41,4 +41,40 @@ describe("network utils", () => { expect(PING_ERROR).toBe(5001); }); }); + + describe("isStatusUp", () => { + it("returns true for 2xx status codes", () => { + expect(isStatusUp(200)).toBe(true); + expect(isStatusUp(201)).toBe(true); + expect(isStatusUp(204)).toBe(true); + expect(isStatusUp(299)).toBe(true); + }); + + it("returns false for non-2xx status codes without customUpCodes", () => { + expect(isStatusUp(100)).toBe(false); + expect(isStatusUp(301)).toBe(false); + expect(isStatusUp(404)).toBe(false); + expect(isStatusUp(500)).toBe(false); + }); + + it("returns true when status code is in customUpCodes", () => { + expect(isStatusUp(301, [301])).toBe(true); + expect(isStatusUp(404, [200, 404])).toBe(true); + expect(isStatusUp(401, [401, 403])).toBe(true); + }); + + it("returns false when status code is not in customUpCodes", () => { + expect(isStatusUp(500, [401, 403])).toBe(false); + }); + + it("returns false when statusCode is undefined", () => { + expect(isStatusUp(undefined)).toBe(false); + expect(isStatusUp(undefined, [200])).toBe(false); + }); + + it("defaults customUpCodes to empty array", () => { + expect(isStatusUp(200)).toBe(true); + expect(isStatusUp(404)).toBe(false); + }); + }); }); From dd16ac060acddb4721e8600e538acbd80b73584e Mon Sep 17 00:00:00 2001 From: harsh-aghara Date: Fri, 5 Jun 2026 00:35:30 +0530 Subject: [PATCH 05/14] fix: run advanced matcher on HTTP errors with custom up codes When customUpCodes mark an HTTPError as up, parse the response body, apply advancedMatcher.validate, and set status to statusUp && matchResult.ok. Return parsed payload and extracted values to match the success path. --- .../infrastructure/network/HttpProvider.ts | 56 +++++++++++++++++-- .../providers/network/httpProvider.test.ts | 24 ++++++++ 2 files changed, 76 insertions(+), 4 deletions(-) diff --git a/server/src/service/infrastructure/network/HttpProvider.ts b/server/src/service/infrastructure/network/HttpProvider.ts index 73cdd6faf..500f93771 100644 --- a/server/src/service/infrastructure/network/HttpProvider.ts +++ b/server/src/service/infrastructure/network/HttpProvider.ts @@ -33,17 +33,65 @@ export class HttpProvider implements IStatusProvider { if (error instanceof HTTPError || error instanceof RequestError) { const statusCode = error.response?.statusCode; const statusUp = isStatusUp(statusCode, monitor.customUpCodes); + const responseTime = error.timings?.phases?.total ?? 0; + + if (!statusUp) { + return { + monitorId: monitor.id, + teamId: monitor.teamId, + type: monitor.type, + status: false, + code: statusCode ?? NETWORK_ERROR, + message: error.message, + responseTime, + timings: error.timings, + payload: null as T, + }; + } + + const { jsonPath } = monitor; + const body = error.response?.body ?? ""; + const contentType = error.response?.headers?.["content-type"] || ""; + const isJson = contentType.includes("application/json"); + + if (jsonPath && !isJson) { + return { + monitorId: monitor.id, + teamId: monitor.teamId, + type: monitor.type, + status: false, + code: statusCode ?? NETWORK_ERROR, + message: "Response is not JSON", + responseTime, + timings: error.timings, + payload: body as unknown as T, + }; + } + + let payload: T; + if (isJson) { + try { + payload = JSON.parse(body) as T; + } catch { + payload = body as unknown as T; + } + } else { + payload = body as unknown as T; + } + + const matchResult = this.advancedMatcher.validate(payload, monitor); return { monitorId: monitor.id, teamId: monitor.teamId, type: monitor.type, - status: statusUp, + status: statusUp && matchResult.ok, code: statusCode ?? NETWORK_ERROR, - message: error.message, - responseTime: error.timings?.phases?.total ?? 0, + message: matchResult.ok ? error.message : matchResult.message, + responseTime, timings: error.timings, - payload: null as T, + payload, + extracted: matchResult.extracted, }; } diff --git a/server/test/unit/providers/network/httpProvider.test.ts b/server/test/unit/providers/network/httpProvider.test.ts index ea24b9872..bd6d05b43 100644 --- a/server/test/unit/providers/network/httpProvider.test.ts +++ b/server/test/unit/providers/network/httpProvider.test.ts @@ -408,5 +408,29 @@ describe("HttpProvider", () => { expect(result.status).toBe(false); expect(result.message).toBe("Body mismatch"); }); + + it("does not override matcher failure on HTTPError when status code is in customUpCodes", async () => { + const err = new HTTPError("Unauthorized"); + (err as any).response = { + statusCode: 401, + body: '{"status":"down"}', + headers: { "content-type": "application/json" }, + }; + (err as any).timings = { phases: { total: 30 } }; + mockGot.mockRejectedValue(err); + const matcher = createMockMatcher({ + ok: false, + message: "Body mismatch", + extracted: "down", + }); + const { provider } = createProvider(matcher); + + const result = await provider.handle(makeMonitor({ customUpCodes: [401], useAdvancedMatching: true })); + + expect(result.status).toBe(false); + expect(result.message).toBe("Body mismatch"); + expect(result.payload).toEqual({ status: "down" }); + expect(result.extracted).toBe("down"); + }); }); }); From 6a566c3693b82a499e4ed53ca4ff2166c5b9824b Mon Sep 17 00:00:00 2001 From: Rabson Date: Sun, 7 Jun 2026 08:53:56 +0800 Subject: [PATCH 06/14] fix(diagnostics): derive Mongo totalSize when dbStats omits it MongoDB Atlas shared/free tiers return a legacy dbStats shape that omits `totalSize` (while still returning storageSize/indexSize). diagnosticService passed that undefined straight through, so the Diagnostics UI crashed with "Expected a finite number, got undefined". Derive totalSize (storageSize + indexSize) at the DB and per-collection level so it always satisfies the non-optional `totalSize: number` type. Confirmed it is not a version removal (stock mongo:8 returns totalSize) nor a permissions issue (missing even with atlasAdmin). Adds unit tests for the derivation. --- .../src/service/business/diagnosticService.ts | 8 ++--- .../unit/services/diagnosticService.test.ts | 36 +++++++++++++++++++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/server/src/service/business/diagnosticService.ts b/server/src/service/business/diagnosticService.ts index 2d9968240..c5debf0e1 100644 --- a/server/src/service/business/diagnosticService.ts +++ b/server/src/service/business/diagnosticService.ts @@ -87,9 +87,9 @@ export class DiagnosticService implements IDiagnosticService { const entry: CollectionDiagnostics = { name: collection.collectionName, documentCount, - storageSize: stats.storageSize, - totalIndexSize: stats.totalIndexSize, - totalSize: stats.totalSize, + storageSize: stats.storageSize ?? 0, + totalIndexSize: stats.totalIndexSize ?? 0, + totalSize: stats.totalSize ?? (stats.storageSize ?? 0) + (stats.totalIndexSize ?? 0), }; if (stats.timeseries?.bucketCount !== undefined) { entry.bucketCount = stats.timeseries.bucketCount; @@ -103,7 +103,7 @@ export class DiagnosticService implements IDiagnosticService { host: mongo.connection.host, port: mongo.connection.port, dbName: mongo.connection.name, - totalSize: dbStats.totalSize, + totalSize: dbStats.totalSize ?? (dbStats.storageSize ?? 0) + (dbStats.indexSize ?? 0), collections, }; }; diff --git a/server/test/unit/services/diagnosticService.test.ts b/server/test/unit/services/diagnosticService.test.ts index ae57613a1..402c0c527 100644 --- a/server/test/unit/services/diagnosticService.test.ts +++ b/server/test/unit/services/diagnosticService.test.ts @@ -147,6 +147,42 @@ describe("DiagnosticService", () => { }); }); + it("derives mongoStats.totalSize from storageSize + indexSize when the server omits it (e.g. Atlas shared tier)", async () => { + const db = makeDb({ + collections: [{ collectionName: "monitors" }], + dbStats: { storageSize: 376832, indexSize: 1155072 }, + }); + const service = new DiagnosticService(db); + const promise = service.getSystemStats(); + jest.advanceTimersByTime(1000); + await jest.advanceTimersByTimeAsync(10); + const result = await promise; + + expect(result.mongoStats.totalSize).toBe(376832 + 1155072); + expect(Number.isFinite(result.mongoStats.totalSize)).toBe(true); + }); + + it("derives collection totalSize and defaults missing size fields to 0 when collStats omits them", async () => { + const db = makeDb({ + collections: [{ collectionName: "checks" }], + collStats: { storageSize: 200 }, + }); + const service = new DiagnosticService(db); + const promise = service.getSystemStats(); + jest.advanceTimersByTime(1000); + await jest.advanceTimersByTimeAsync(10); + const result = await promise; + + const coll = result.mongoStats.collections[0]; + expect(coll).toMatchObject({ + name: "checks", + storageSize: 200, + totalIndexSize: 0, + totalSize: 200, // storageSize (200) + totalIndexSize (0) + }); + expect(Number.isFinite(coll?.totalSize)).toBe(true); + }); + it("includes bucketCount on timeseries collections, omits it elsewhere", async () => { const db = makeDb({ collections: [{ collectionName: "checks" }], From f637b01631a3c7389e96cd6b7c840229b9ace1e2 Mon Sep 17 00:00:00 2001 From: harsh-aghara Date: Fri, 5 Jun 2026 22:43:00 +0530 Subject: [PATCH 07/14] refactor: introduced helper method to remove redundant code --- .../infrastructure/network/HttpProvider.ts | 154 ++++++++---------- .../notificationMessageBuilder.ts | 2 +- server/src/types/network.ts | 2 +- 3 files changed, 74 insertions(+), 84 deletions(-) diff --git a/server/src/service/infrastructure/network/HttpProvider.ts b/server/src/service/infrastructure/network/HttpProvider.ts index 5046208c1..a31bdf770 100644 --- a/server/src/service/infrastructure/network/HttpProvider.ts +++ b/server/src/service/infrastructure/network/HttpProvider.ts @@ -40,6 +40,62 @@ export class HttpProvider implements IStatusProvider { return type === "http"; } + private buildResponse( + monitor: Monitor, + opts: { + body: string; + contentType: string; + statusCode: number; + statusUp: boolean; + message: string; + responseTime: number; + timings?: MonitorStatusResponse["timings"]; + } + ): MonitorStatusResponse { + const { body, contentType, statusCode, statusUp, message, responseTime, timings } = opts; + const isJson = contentType.includes("application/json"); + + if (monitor.jsonPath && !isJson) { + return { + monitorId: monitor.id, + teamId: monitor.teamId, + type: monitor.type, + status: false, + code: statusCode, + message: "Response is not JSON", + responseTime, + timings, + payload: body, + }; + } + + let payload: T | string; + if (isJson) { + try { + payload = JSON.parse(body) as T; + } catch { + payload = body; + } + } else { + payload = body; + } + + const matchResult = this.advancedMatcher.validate(payload, monitor); + + return { + monitorId: monitor.id, + teamId: monitor.teamId, + type: monitor.type, + status: statusUp && matchResult.ok, + code: statusCode, + message: matchResult.ok ? message : matchResult.message, + responseTime, + timings, + payload, + extracted: matchResult.extracted, + }; + } + private handleHttpError(error: unknown, monitor: Monitor): MonitorStatusResponse { if (error instanceof HTTPError || error instanceof RequestError) { const statusCode = error.response?.statusCode; @@ -60,50 +116,15 @@ export class HttpProvider implements IStatusProvider { }; } - const { jsonPath } = monitor; - const body = error.response?.body ?? ""; - const contentType = error.response?.headers?.["content-type"] || ""; - const isJson = contentType.includes("application/json"); - - if (jsonPath && !isJson) { - return { - monitorId: monitor.id, - teamId: monitor.teamId, - type: monitor.type, - status: false, - code: statusCode ?? NETWORK_ERROR, - message: "Response is not JSON", - responseTime, - timings: error.timings, - payload: body as unknown as T, - }; - } - - let payload: T; - if (isJson) { - try { - payload = JSON.parse(body) as T; - } catch { - payload = body as unknown as T; - } - } else { - payload = body as unknown as T; - } - - const matchResult = this.advancedMatcher.validate(payload, monitor); - - return { - monitorId: monitor.id, - teamId: monitor.teamId, - type: monitor.type, - status: statusUp && matchResult.ok, - code: statusCode ?? NETWORK_ERROR, - message: matchResult.ok ? error.message : matchResult.message, + return this.buildResponse(monitor, { + body: (error.response?.body ?? "") as string, + contentType: error.response?.headers?.["content-type"] || "", + statusCode: statusCode ?? NETWORK_ERROR, + statusUp, + message: error.message, responseTime, timings: error.timings, - payload, - extracted: matchResult.extracted, - }; + }); } return { @@ -119,7 +140,7 @@ export class HttpProvider implements IStatusProvider { } async handle(monitor: Monitor): Promise> { - const { url, secret, jsonPath, ignoreTlsErrors } = monitor; + const { url, secret, ignoreTlsErrors } = monitor; if (!url) { throw new Error("URL is required for HTTP monitor"); @@ -136,48 +157,17 @@ export class HttpProvider implements IStatusProvider { try { const response = await this.got(url, options); - const contentType = response.headers["content-type"] || ""; - const isJson = contentType.includes("application/json"); - - if (jsonPath && !isJson) { - return { - monitorId: monitor.id, - teamId: monitor.teamId, - type: monitor.type, - status: false, - code: response.statusCode, - message: "Response is not JSON", - responseTime: response.timings.phases.firstByte ?? 0, - timings: response.timings, - payload: response.body as unknown as T, - }; - } - - let payload: T; - if (isJson) { - try { - payload = JSON.parse(response.body) as T; - } catch { - payload = response.body as unknown as T; - } - } else { - payload = response.body as unknown as T; - } - - const matchResult = this.advancedMatcher.validate(payload, monitor); const statusUp = isStatusUp(response.statusCode, monitor.customUpCodes); - return { - monitorId: monitor.id, - teamId: monitor.teamId, - type: monitor.type, - status: statusUp && matchResult.ok, - code: response.statusCode, - message: matchResult.ok ? (response.statusMessage ?? "OK") : matchResult.message, + + return this.buildResponse(monitor, { + body: response.body, + contentType: response.headers["content-type"] || "", + statusCode: response.statusCode, + statusUp, + message: response.statusMessage ?? "OK", responseTime: response.timings.phases.firstByte ?? 0, timings: response.timings, - payload, - extracted: matchResult.extracted, - }; + }); } catch (error: unknown) { return this.handleHttpError(error, monitor); } diff --git a/server/src/service/infrastructure/notificationMessageBuilder.ts b/server/src/service/infrastructure/notificationMessageBuilder.ts index bc1d7ac82..2035439c2 100644 --- a/server/src/service/infrastructure/notificationMessageBuilder.ts +++ b/server/src/service/infrastructure/notificationMessageBuilder.ts @@ -186,7 +186,7 @@ export class NotificationMessageBuilder implements INotificationMessageBuilder { const breaches: ThresholdBreach[] = []; // Check if this is a hardware monitor with threshold data - if (monitor.type !== "hardware" || !monitorStatusResponse.payload) { + if (monitor.type !== "hardware" || !monitorStatusResponse.payload || typeof monitorStatusResponse.payload === "string") { return breaches; } diff --git a/server/src/types/network.ts b/server/src/types/network.ts index 19f063cc6..246422bf2 100644 --- a/server/src/types/network.ts +++ b/server/src/types/network.ts @@ -35,7 +35,7 @@ export interface MonitorStatusResponse< code: number; message: string; responseTime?: number; - payload?: T | null; + payload?: T | string | null; timings?: GotTimings; first_byte_took?: number; body_read_took?: number; From d022f7d849cf055eb51d3cfb2e4c92a539046a42 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Tue, 9 Jun 2026 12:34:15 -0700 Subject: [PATCH 08/14] reorg to domain and api --- .../{ => api}/controllers/authController.ts | 8 +- .../{ => api}/controllers/checkController.ts | 6 +- .../{ => api}/controllers/controllerUtils.ts | 3 +- .../controllers/diagnosticController.ts | 2 +- .../controllers/geoCheckController.ts | 5 +- .../controllers/incidentController.ts | 4 +- .../{ => api}/controllers/inviteController.ts | 6 +- .../{ => api}/controllers/logController.ts | 0 .../maintenanceWindowController.ts | 6 +- .../controllers/monitorController.ts | 9 +- .../controllers/notificationController.ts | 6 +- .../{ => api}/controllers/queueController.ts | 4 +- .../controllers/settingsController.ts | 9 +- .../controllers/statusPageController.ts | 10 +- .../controllers/statusPageThemeFlag.ts | 2 +- .../{ => api}/controllers/tagController.ts | 4 +- .../src/{ => api}/middleware/handleErrors.ts | 0 server/src/{ => api}/middleware/isAllowed.ts | 2 +- .../src/{ => api}/middleware/rateLimiter.ts | 0 .../src/{ => api}/middleware/sanitization.ts | 0 server/src/{ => api}/middleware/verifyJWT.ts | 4 +- .../middleware/verifyStatusPageAccess.ts | 2 +- server/src/{ => api}/routes/authRoute.ts | 2 +- server/src/{ => api}/routes/checkRoute.ts | 2 +- .../src/{ => api}/routes/diagnosticRoute.ts | 2 +- server/src/{ => api}/routes/geoCheckRoutes.ts | 2 +- server/src/{ => api}/routes/incidentRoute.ts | 2 +- server/src/{ => api}/routes/inviteRoute.ts | 2 +- server/src/{ => api}/routes/logRoutes.ts | 4 +- .../routes/maintenanceWindowRoute.ts | 2 +- server/src/{ => api}/routes/monitorRoute.ts | 4 +- .../src/{ => api}/routes/notificationRoute.ts | 2 +- server/src/{ => api}/routes/queueRoute.ts | 4 +- server/src/{ => api}/routes/settingsRoute.ts | 2 +- .../src/{ => api}/routes/statusPageRoute.ts | 2 +- server/src/{ => api}/routes/tagRoutes.ts | 2 +- .../{ => api}/validation/authValidation.ts | 2 +- .../{ => api}/validation/checkValidation.ts | 4 +- .../validation/incidentValidation.ts | 0 server/src/{ => api}/validation/index.ts | 2 +- .../validation/maintenanceWindowValidation.ts | 2 +- .../{ => api}/validation/monitorValidation.ts | 11 +- .../validation/notificationValidation.ts | 0 .../{ => api}/validation/queueValidation.ts | 0 .../validation/settingsValidation.ts | 2 +- server/src/{ => api}/validation/shared.ts | 2 +- .../validation/statusPageValidation.ts | 2 +- .../src/{ => api}/validation/tagValidation.ts | 0 .../{ => api}/validation/userValidation.ts | 2 +- server/src/app.ts | 8 +- server/src/config/controllers.ts | 28 +-- .../{validation => config}/envValidation.ts | 4 +- server/src/config/routes.ts | 34 ++-- server/src/config/services.ts | 177 ++++++++---------- server/src/db/{IDb.ts => db.interface.ts} | 0 server/src/db/{MongoDB.ts => db.mongo.ts} | 6 +- .../0001_migrateStatusWindowThreshold.ts | 2 +- .../0003_cleanupDuplicateMonitorStats.ts | 2 +- .../0004_fixInfrastructureThresholds.ts | 2 +- .../0005_migrateStatusPageTypeToArray.ts | 2 +- ...anupDuplicateMonitorStatsForUniqueIndex.ts | 2 +- ...igrateMaintenanceWindowMonitorIdToArray.ts | 2 +- server/src/db/migration/index.ts | 2 +- server/src/db/models/index.ts | 46 ----- .../app-settings-repository.interface.ts} | 2 +- .../app-settings/app-settings.model.ts} | 2 +- .../app-settings.repository.mongo.ts} | 6 +- .../app-settings/app-settings.service.ts} | 6 +- .../app-settings/app-settings.type.ts} | 23 ++- .../Check.ts => domain/checks/check.model.ts} | 4 +- .../checks/check.repository.interface.ts} | 8 +- .../checks/check.repository.mongo.ts} | 8 +- .../checks/check.service.ts} | 14 +- .../check.ts => domain/checks/check.type.ts} | 2 +- .../diagnostics/diagnostic.service.ts} | 2 +- .../DLQItem.ts => domain/dlq/dlq.model.ts} | 2 +- .../dlq/dlq.repository.interface.ts} | 2 +- .../dlq/dlq.repository.mongo.ts} | 8 +- .../dlqItem.ts => domain/dlq/dlq.type.ts} | 0 .../geo-checks/geo-check.model.ts} | 4 +- .../geo-check.repository.interface.ts} | 4 +- .../geo-checks/geo-check.repository.mongo.ts} | 8 +- .../geo-checks/geo-check.service.ts} | 11 +- .../geo-checks/geo-check.type.ts} | 2 +- .../incidents/incident.model.ts} | 2 +- .../incident.repository.interface.ts} | 4 +- .../incidents/incident.repository.mongo.ts} | 8 +- .../incidents/incident.service.ts} | 13 +- .../incidents/incident.type.ts} | 0 .../invites/invite.model.ts} | 2 +- .../invites/invite.repository.interface.ts} | 2 +- .../invites/invite.repository.mongo.ts} | 6 +- .../invites/invite.service.ts} | 11 +- .../invites/invite.type.ts} | 2 +- .../maintenance-window.model.ts} | 2 +- ...aintenance-window.repository.interface.ts} | 2 +- .../maintenance-window.repository.mongo.ts} | 6 +- .../maintenance-window.service.ts} | 5 +- .../maintenance-window.type.ts} | 0 .../migrations/migration.model.ts} | 0 .../monitor-stats/monitor-stats.model.ts} | 2 +- .../monitor-stats.repository.interface.ts} | 2 +- .../monitor-stats.repository.mongo.ts} | 6 +- .../monitor-stats/monitor-stats.type.ts} | 0 .../monitors/monitor.model.ts} | 6 +- .../monitors/monitor.repository.interface.ts} | 2 +- .../monitors/monitor.repository.mongo.ts} | 10 +- .../monitors/monitor.service.ts} | 28 ++- .../monitors/monitor.types.ts} | 22 +-- .../notification.message-builder.ts} | 7 +- .../notifications/notification.model.ts} | 2 +- .../notification.repository.interface.ts} | 2 +- .../notification.repository.mongo.ts} | 6 +- .../notifications/notification.service.ts} | 17 +- .../notifications/notification.type.ts} | 59 ++++++ .../providers}/INotificationProvider.ts | 4 +- .../notifications/providers}/discord.ts | 8 +- .../notifications/providers}/email.ts | 10 +- .../notifications/providers}/matrix.ts | 8 +- .../notifications/providers}/ntfy.ts | 8 +- .../notifications/providers}/pagerduty.ts | 10 +- .../notifications/providers}/pushover.ts | 8 +- .../notifications/providers}/slack.ts | 8 +- .../notifications/providers}/teams.ts | 8 +- .../notifications/providers}/telegram.ts | 8 +- .../notifications/providers}/twilio.ts | 8 +- .../notifications/providers}/utils.ts | 2 +- .../notifications/providers}/webhook.ts | 8 +- .../queue-workers/queue-worker.model.ts} | 14 +- .../queue-worker.repository.interface.ts} | 3 +- .../queue-worker.repository.mongo.ts} | 8 +- .../domain/queue-workers/queue-worker.type.ts | 18 ++ .../recovery-tokens/recovery-token.model.ts} | 2 +- .../recovery-token.repository.interface.ts} | 2 +- .../recovery-token.repository.mongo.ts} | 8 +- .../recovery-tokens/recovery-token.type.ts} | 0 .../status-page-repository.interface.ts} | 2 +- .../status-page-repository.mongo.ts} | 6 +- .../status-pages/status-page.model.ts} | 4 +- .../status-pages/status-page.service.ts} | 6 +- .../status-pages/status-page.type.ts} | 0 .../Tag.ts => domain/tags/tag.model.ts} | 2 +- .../tags/tag.repository.interface.ts} | 2 +- .../tags/tag.repository.mongo.ts} | 6 +- .../tags/tag.service.ts} | 5 +- .../{types/tag.ts => domain/tags/tag.type.ts} | 0 .../Team.ts => domain/teams/team.model.ts} | 2 +- .../teams/team.repository.interface.ts} | 2 +- .../teams/team.repository.model.ts} | 6 +- .../team.ts => domain/teams/team.type.ts} | 0 .../User.ts => domain/users/user.model.ts} | 8 +- .../users/user.repository.interface.ts} | 2 +- .../users/user.repository.mongo.ts} | 6 +- .../users/user.service.ts} | 24 ++- .../user.ts => domain/users/user.type.ts} | 0 server/src/index.ts | 5 +- server/src/repositories/index.ts | 47 ----- .../{infrastructure => }/bufferService.ts | 10 +- .../{infrastructure => }/emailService.ts | 4 +- .../{infrastructure => }/globalPingService.ts | 8 +- server/src/service/index.ts | 41 ---- .../job-queue.helper.ts} | 41 ++-- .../job-queue.interface.ts} | 4 +- .../job-queue.less-simple.ts} | 13 +- .../job-queue.sumper-simple.ts} | 10 +- .../network/AdvancedMatcher.ts | 2 +- .../network/DNSProvider.ts | 6 +- .../network/DockerProvider.ts | 6 +- .../network/GameProvider.ts | 6 +- .../network/GrpcProvider.ts | 6 +- .../network/HardwareProvider.ts | 6 +- .../network/HttpProvider.ts | 8 +- .../network/IStatusProvider.ts | 2 +- .../network/PageSpeedProvider.ts | 8 +- .../network/PingProvider.ts | 4 +- .../network/PortProvider.ts | 6 +- .../network/WebSocketProvider.ts | 6 +- .../{infrastructure => }/network/utils.ts | 2 +- .../{infrastructure => }/networkService.ts | 5 +- .../{infrastructure => }/protos/health.proto | 0 .../{infrastructure => }/statusService.ts | 29 ++- server/src/types/alert.ts | 42 ----- server/src/types/email.ts | 18 -- server/src/types/express.d.ts | 2 +- server/src/types/index.ts | 18 -- server/src/types/network.ts | 8 +- server/src/types/notification.ts | 32 ---- server/src/utils/dataUtils.ts | 2 +- server/src/utils/logger.ts | 2 +- server/src/utils/maintenanceWindow.ts | 2 +- 190 files changed, 643 insertions(+), 830 deletions(-) rename server/src/{ => api}/controllers/authController.ts (97%) rename server/src/{ => api}/controllers/checkController.ts (95%) rename server/src/{ => api}/controllers/controllerUtils.ts (96%) rename server/src/{ => api}/controllers/diagnosticController.ts (91%) rename server/src/{ => api}/controllers/geoCheckController.ts (90%) rename server/src/{ => api}/controllers/incidentController.ts (96%) rename server/src/{ => api}/controllers/inviteController.ts (94%) rename server/src/{ => api}/controllers/logController.ts (100%) rename server/src/{ => api}/controllers/maintenanceWindowController.ts (95%) rename server/src/{ => api}/controllers/monitorController.ts (97%) rename server/src/{ => api}/controllers/notificationController.ts (95%) rename server/src/{ => api}/controllers/queueController.ts (93%) rename server/src/{ => api}/controllers/settingsController.ts (91%) rename server/src/{ => api}/controllers/statusPageController.ts (93%) rename server/src/{ => api}/controllers/statusPageThemeFlag.ts (95%) rename server/src/{ => api}/controllers/tagController.ts (96%) rename server/src/{ => api}/middleware/handleErrors.ts (100%) rename server/src/{ => api}/middleware/isAllowed.ts (92%) rename server/src/{ => api}/middleware/rateLimiter.ts (100%) rename server/src/{ => api}/middleware/sanitization.ts (100%) rename server/src/{ => api}/middleware/verifyJWT.ts (93%) rename server/src/{ => api}/middleware/verifyStatusPageAccess.ts (88%) rename server/src/{ => api}/routes/authRoute.ts (96%) mode change 100755 => 100644 rename server/src/{ => api}/routes/checkRoute.ts (91%) mode change 100755 => 100644 rename server/src/{ => api}/routes/diagnosticRoute.ts (88%) mode change 100755 => 100644 rename server/src/{ => api}/routes/geoCheckRoutes.ts (85%) rename server/src/{ => api}/routes/incidentRoute.ts (91%) rename server/src/{ => api}/routes/inviteRoute.ts (91%) mode change 100755 => 100644 rename server/src/{ => api}/routes/logRoutes.ts (77%) mode change 100755 => 100644 rename server/src/{ => api}/routes/maintenanceWindowRoute.ts (90%) mode change 100755 => 100644 rename server/src/{ => api}/routes/monitorRoute.ts (95%) mode change 100755 => 100644 rename server/src/{ => api}/routes/notificationRoute.ts (91%) mode change 100755 => 100644 rename server/src/{ => api}/routes/queueRoute.ts (84%) mode change 100755 => 100644 rename server/src/{ => api}/routes/settingsRoute.ts (90%) mode change 100755 => 100644 rename server/src/{ => api}/routes/statusPageRoute.ts (93%) mode change 100755 => 100644 rename server/src/{ => api}/routes/tagRoutes.ts (90%) rename server/src/{ => api}/validation/authValidation.ts (96%) rename server/src/{ => api}/validation/checkValidation.ts (91%) rename server/src/{ => api}/validation/incidentValidation.ts (100%) rename server/src/{ => api}/validation/index.ts (94%) rename server/src/{ => api}/validation/maintenanceWindowValidation.ts (96%) rename server/src/{ => api}/validation/monitorValidation.ts (97%) rename server/src/{ => api}/validation/notificationValidation.ts (100%) rename server/src/{ => api}/validation/queueValidation.ts (100%) rename server/src/{ => api}/validation/settingsValidation.ts (95%) rename server/src/{ => api}/validation/shared.ts (97%) rename server/src/{ => api}/validation/statusPageValidation.ts (97%) rename server/src/{ => api}/validation/tagValidation.ts (100%) rename server/src/{ => api}/validation/userValidation.ts (97%) rename server/src/{validation => config}/envValidation.ts (90%) rename server/src/db/{IDb.ts => db.interface.ts} (100%) rename server/src/db/{MongoDB.ts => db.mongo.ts} (93%) delete mode 100644 server/src/db/models/index.ts rename server/src/{repositories/settings/ISettingsRepository.ts => domain/app-settings/app-settings-repository.interface.ts} (75%) rename server/src/{db/models/AppSettings.ts => domain/app-settings/app-settings.model.ts} (94%) rename server/src/{repositories/settings/MongoSettingsRepository.ts => domain/app-settings/app-settings.repository.mongo.ts} (91%) rename server/src/{service/system/settingsService.ts => domain/app-settings/app-settings.service.ts} (89%) rename server/src/{types/settings.ts => domain/app-settings/app-settings.type.ts} (75%) rename server/src/{db/models/Check.ts => domain/checks/check.model.ts} (98%) rename server/src/{repositories/checks/IChecksRepository.ts => domain/checks/check.repository.interface.ts} (87%) rename server/src/{repositories/checks/MongoChecksRepistory.ts => domain/checks/check.repository.mongo.ts} (98%) rename server/src/{service/business/checkService.ts => domain/checks/check.service.ts} (94%) rename server/src/{types/check.ts => domain/checks/check.type.ts} (98%) rename server/src/{service/business/diagnosticService.ts => domain/diagnostics/diagnostic.service.ts} (98%) rename server/src/{db/models/DLQItem.ts => domain/dlq/dlq.model.ts} (93%) rename server/src/{repositories/dlq/IDLQRepository.ts => domain/dlq/dlq.repository.interface.ts} (90%) rename server/src/{repositories/dlq/MongoDLQRepository.ts => domain/dlq/dlq.repository.mongo.ts} (94%) rename server/src/{types/dlqItem.ts => domain/dlq/dlq.type.ts} (100%) rename server/src/{db/models/GeoCheck.ts => domain/geo-checks/geo-check.model.ts} (94%) rename server/src/{repositories/geo-checks/IGeoChecksRepository.ts => domain/geo-checks/geo-check.repository.interface.ts} (84%) rename server/src/{repositories/geo-checks/MongoGeoChecksRepository.ts => domain/geo-checks/geo-check.repository.mongo.ts} (97%) rename server/src/{service/business/geoChecksService.ts => domain/geo-checks/geo-check.service.ts} (92%) rename server/src/{types/geoCheck.ts => domain/geo-checks/geo-check.type.ts} (95%) rename server/src/{db/models/Incident.ts => domain/incidents/incident.model.ts} (95%) rename server/src/{repositories/incidents/IIncidentsRepository.ts => domain/incidents/incident.repository.interface.ts} (88%) rename server/src/{repositories/incidents/MongoIncidentsRepository.ts => domain/incidents/incident.repository.mongo.ts} (96%) rename server/src/{service/business/incidentService.ts => domain/incidents/incident.service.ts} (92%) rename server/src/{types/incident.ts => domain/incidents/incident.type.ts} (100%) rename server/src/{db/models/Invite.ts => domain/invites/invite.model.ts} (93%) rename server/src/{repositories/invites/IInvitesRepository.ts => domain/invites/invite.repository.interface.ts} (79%) rename server/src/{repositories/invites/MongoInviteRepository.ts => domain/invites/invite.repository.mongo.ts} (88%) rename server/src/{service/business/inviteService.ts => domain/invites/invite.service.ts} (88%) rename server/src/{types/invite.ts => domain/invites/invite.type.ts} (73%) rename server/src/{db/models/MaintenanceWindow.ts => domain/maintenance-windows/maintenance-window.model.ts} (91%) rename server/src/{repositories/maintenance-windows/IMaintenanceWindowsRepository.ts => domain/maintenance-windows/maintenance-window.repository.interface.ts} (89%) rename server/src/{repositories/maintenance-windows/MongoMaintenanceWindowsRepository.ts => domain/maintenance-windows/maintenance-window.repository.mongo.ts} (94%) rename server/src/{service/business/maintenanceWindowService.ts => domain/maintenance-windows/maintenance-window.service.ts} (95%) rename server/src/{types/maintenanceWindow.ts => domain/maintenance-windows/maintenance-window.type.ts} (100%) rename server/src/{db/models/Migration.ts => domain/migrations/migration.model.ts} (100%) rename server/src/{db/models/MonitorStats.ts => domain/monitor-stats/monitor-stats.model.ts} (92%) rename server/src/{repositories/monitor-stats/IMonitorStatsRepository.ts => domain/monitor-stats/monitor-stats.repository.interface.ts} (85%) rename server/src/{repositories/monitor-stats/MongoMonitorStatsRepository.ts => domain/monitor-stats/monitor-stats.repository.mongo.ts} (94%) rename server/src/{types/monitorStats.ts => domain/monitor-stats/monitor-stats.type.ts} (100%) rename server/src/{db/models/Monitor.ts => domain/monitors/monitor.model.ts} (98%) rename server/src/{repositories/monitors/IMonitorsRepository.ts => domain/monitors/monitor.repository.interface.ts} (94%) rename server/src/{repositories/monitors/MongoMonitorsRepository.ts => domain/monitors/monitor.repository.mongo.ts} (98%) rename server/src/{service/business/monitorService.ts => domain/monitors/monitor.service.ts} (94%) rename server/src/{types/monitor.ts => domain/monitors/monitor.types.ts} (84%) rename server/src/{service/infrastructure/notificationMessageBuilder.ts => domain/notifications/notification.message-builder.ts} (96%) rename server/src/{db/models/Notification.ts => domain/notifications/notification.model.ts} (92%) rename server/src/{repositories/notifications/INotificationsRepository.ts => domain/notifications/notification.repository.interface.ts} (86%) rename server/src/{repositories/notifications/MongoNotificationsRepository.ts => domain/notifications/notification.repository.mongo.ts} (93%) rename server/src/{service/infrastructure/notificationsService.ts => domain/notifications/notification.service.ts} (91%) rename server/src/{types/notificationMessage.ts => domain/notifications/notification.type.ts} (51%) rename server/src/{service/infrastructure/notificationProviders => domain/notifications/providers}/INotificationProvider.ts (85%) rename server/src/{service/infrastructure/notificationProviders => domain/notifications/providers}/discord.ts (92%) rename server/src/{service/infrastructure/notificationProviders => domain/notifications/providers}/email.ts (89%) rename server/src/{service/infrastructure/notificationProviders => domain/notifications/providers}/matrix.ts (93%) rename server/src/{service/infrastructure/notificationProviders => domain/notifications/providers}/ntfy.ts (90%) rename server/src/{service/infrastructure/notificationProviders => domain/notifications/providers}/pagerduty.ts (89%) rename server/src/{service/infrastructure/notificationProviders => domain/notifications/providers}/pushover.ts (89%) rename server/src/{service/infrastructure/notificationProviders => domain/notifications/providers}/slack.ts (92%) rename server/src/{service/infrastructure/notificationProviders => domain/notifications/providers}/teams.ts (94%) rename server/src/{service/infrastructure/notificationProviders => domain/notifications/providers}/telegram.ts (89%) rename server/src/{service/infrastructure/notificationProviders => domain/notifications/providers}/twilio.ts (88%) rename server/src/{service/infrastructure/notificationProviders => domain/notifications/providers}/utils.ts (80%) rename server/src/{service/infrastructure/notificationProviders => domain/notifications/providers}/webhook.ts (90%) rename server/src/{db/models/QueueWorker.ts => domain/queue-workers/queue-worker.model.ts} (54%) rename server/src/{repositories/queue-workers/IQueueWorkersRepository.ts => domain/queue-workers/queue-worker.repository.interface.ts} (56%) rename server/src/{repositories/queue-workers/MongoQueueWorkersRepository.ts => domain/queue-workers/queue-worker.repository.mongo.ts} (72%) create mode 100644 server/src/domain/queue-workers/queue-worker.type.ts rename server/src/{db/models/RecoveryToken.ts => domain/recovery-tokens/recovery-token.model.ts} (87%) rename server/src/{repositories/recovery-tokens/IRecoveryTokensRepository.ts => domain/recovery-tokens/recovery-token.repository.interface.ts} (74%) rename server/src/{repositories/recovery-tokens/MongoRecoveryTokensRepository.ts => domain/recovery-tokens/recovery-token.repository.mongo.ts} (82%) rename server/src/{types/recoveryToken.ts => domain/recovery-tokens/recovery-token.type.ts} (100%) rename server/src/{repositories/status-pages/IStatusPagesRepository.ts => domain/status-pages/status-page-repository.interface.ts} (88%) rename server/src/{repositories/status-pages/MongoStatusPagesRepository.ts => domain/status-pages/status-page-repository.mongo.ts} (94%) rename server/src/{db/models/StatusPage.ts => domain/status-pages/status-page.model.ts} (94%) rename server/src/{service/business/statusPageService.ts => domain/status-pages/status-page.service.ts} (91%) rename server/src/{types/statusPage.ts => domain/status-pages/status-page.type.ts} (100%) rename server/src/{db/models/Tag.ts => domain/tags/tag.model.ts} (91%) rename server/src/{repositories/tags/ITagsRepository.ts => domain/tags/tag.repository.interface.ts} (88%) rename server/src/{repositories/tags/MongoTagsRepository.ts => domain/tags/tag.repository.mongo.ts} (92%) rename server/src/{service/infrastructure/tagService.ts => domain/tags/tag.service.ts} (85%) rename server/src/{types/tag.ts => domain/tags/tag.type.ts} (100%) rename server/src/{db/models/Team.ts => domain/teams/team.model.ts} (90%) rename server/src/{repositories/teams/ITeamsRepository.ts => domain/teams/team.repository.interface.ts} (74%) rename server/src/{repositories/teams/MongoTeamsRepository.ts => domain/teams/team.repository.model.ts} (84%) rename server/src/{types/team.ts => domain/teams/team.type.ts} (100%) rename server/src/{db/models/User.ts => domain/users/user.model.ts} (88%) rename server/src/{repositories/users/IUsersRepository.ts => domain/users/user.repository.interface.ts} (88%) rename server/src/{repositories/users/MongoUsersRepository.ts => domain/users/user.repository.mongo.ts} (95%) rename server/src/{service/business/userService.ts => domain/users/user.service.ts} (93%) rename server/src/{types/user.ts => domain/users/user.type.ts} (100%) delete mode 100644 server/src/repositories/index.ts rename server/src/service/{infrastructure => }/bufferService.ts (91%) rename server/src/service/{infrastructure => }/emailService.ts (97%) rename server/src/service/{infrastructure => }/globalPingService.ts (95%) delete mode 100644 server/src/service/index.ts rename server/src/service/{infrastructure/JobQueues/QueueHelper.ts => job-queues/job-queue.helper.ts} (90%) rename server/src/service/{infrastructure/JobQueues/IJobQueue.ts => job-queues/job-queue.interface.ts} (92%) rename server/src/service/{infrastructure/JobQueues/LessSimpleQueue.ts => job-queues/job-queue.less-simple.ts} (95%) rename server/src/service/{infrastructure/JobQueues/SuperSimpleQueue.ts => job-queues/job-queue.sumper-simple.ts} (96%) rename server/src/service/{infrastructure => }/network/AdvancedMatcher.ts (96%) rename server/src/service/{infrastructure => }/network/DNSProvider.ts (91%) rename server/src/service/{infrastructure => }/network/DockerProvider.ts (95%) rename server/src/service/{infrastructure => }/network/GameProvider.ts (89%) rename server/src/service/{infrastructure => }/network/GrpcProvider.ts (96%) rename server/src/service/{infrastructure => }/network/HardwareProvider.ts (79%) rename server/src/service/{infrastructure => }/network/HttpProvider.ts (93%) rename server/src/service/{infrastructure => }/network/IStatusProvider.ts (74%) rename server/src/service/{infrastructure => }/network/PageSpeedProvider.ts (87%) rename server/src/service/{infrastructure => }/network/PingProvider.ts (92%) rename server/src/service/{infrastructure => }/network/PortProvider.ts (90%) rename server/src/service/{infrastructure => }/network/WebSocketProvider.ts (91%) rename server/src/service/{infrastructure => }/network/utils.ts (92%) rename server/src/service/{infrastructure => }/networkService.ts (96%) rename server/src/service/{infrastructure => }/protos/health.proto (100%) rename server/src/service/{infrastructure => }/statusService.ts (95%) delete mode 100644 server/src/types/alert.ts delete mode 100644 server/src/types/email.ts delete mode 100644 server/src/types/index.ts delete mode 100644 server/src/types/notification.ts diff --git a/server/src/controllers/authController.ts b/server/src/api/controllers/authController.ts similarity index 97% rename from server/src/controllers/authController.ts rename to server/src/api/controllers/authController.ts index 20303b4eb..45f806a8c 100755 --- a/server/src/controllers/authController.ts +++ b/server/src/api/controllers/authController.ts @@ -1,6 +1,6 @@ import { Request, Response, NextFunction } from "express"; import { AppError } from "@/utils/AppError.js"; -import { requireTeamId, requireUserEmail, requireUserId, requireUserRoles } from "@/controllers/controllerUtils.js"; +import { requireTeamId, requireUserEmail, requireUserId, requireUserRoles } from "@/api/controllers/controllerUtils.js"; import { registrationBodyValidation, @@ -8,7 +8,7 @@ import { recoveryValidation, recoveryTokenBodyValidation, newPasswordValidation, -} from "@/validation/authValidation.js"; +} from "@/api/validation/authValidation.js"; import { editUserBodyValidation, @@ -18,8 +18,8 @@ import { editUserByIdBodyValidation, editSuperadminUserByIdBodyValidation, editUserPasswordByIdBodyValidation, -} from "@/validation/userValidation.js"; -import { IUserService } from "@/service/index.js"; +} from "@/api/validation/userValidation.js"; +import { IUserService } from "@/domain/users/user.service.js"; const SERVICE_NAME = "authController"; diff --git a/server/src/controllers/checkController.ts b/server/src/api/controllers/checkController.ts similarity index 95% rename from server/src/controllers/checkController.ts rename to server/src/api/controllers/checkController.ts index dfe64e80a..23fbe2227 100755 --- a/server/src/controllers/checkController.ts +++ b/server/src/api/controllers/checkController.ts @@ -6,9 +6,9 @@ import { getTeamChecksQueryValidation, getChecksSummaryByTeamIdQueryValidation, deleteChecksParamValidation, -} from "@/validation/checkValidation.js"; -import { ICheckService } from "@/service/index.js"; -import { requireTeamId } from "@/controllers/controllerUtils.js"; +} from "@/api/validation/checkValidation.js"; +import { ICheckService } from "@/domain/checks/check.service.js"; +import { requireTeamId } from "@/api/controllers/controllerUtils.js"; const SERVICE_NAME = "checkController"; diff --git a/server/src/controllers/controllerUtils.ts b/server/src/api/controllers/controllerUtils.ts similarity index 96% rename from server/src/controllers/controllerUtils.ts rename to server/src/api/controllers/controllerUtils.ts index 67dc71a70..45bf3fa9f 100755 --- a/server/src/controllers/controllerUtils.ts +++ b/server/src/api/controllers/controllerUtils.ts @@ -1,5 +1,6 @@ import { AppError } from "@/utils/AppError.js"; -import { Monitor, type MonitorType, MonitorTypes, UserRole } from "@/types/index.js"; +import { Monitor, MonitorTypes, type MonitorType } from "@/domain/monitors/monitor.types.js"; +import { UserRole } from "@/domain/users/user.type.js"; import sslChecker, { SSLDetails } from "ssl-checker"; type SSLCheckerType = typeof sslChecker; diff --git a/server/src/controllers/diagnosticController.ts b/server/src/api/controllers/diagnosticController.ts similarity index 91% rename from server/src/controllers/diagnosticController.ts rename to server/src/api/controllers/diagnosticController.ts index ffe7c6f5f..efc383e1a 100755 --- a/server/src/controllers/diagnosticController.ts +++ b/server/src/api/controllers/diagnosticController.ts @@ -1,4 +1,4 @@ -import { IDiagnosticService } from "@/service/index.js"; +import { IDiagnosticService } from "@/domain/diagnostics/diagnostic.service.js"; import { Request, Response, NextFunction } from "express"; const SERVICE_NAME = "diagnosticController"; diff --git a/server/src/controllers/geoCheckController.ts b/server/src/api/controllers/geoCheckController.ts similarity index 90% rename from server/src/controllers/geoCheckController.ts rename to server/src/api/controllers/geoCheckController.ts index 96f9beeac..a50176188 100644 --- a/server/src/controllers/geoCheckController.ts +++ b/server/src/api/controllers/geoCheckController.ts @@ -1,8 +1,7 @@ import { Request, Response, NextFunction } from "express"; -import { getChecksParamValidation, getChecksQueryValidation } from "@/validation/checkValidation.js"; -import type { IGeoChecksService } from "@/service/business/geoChecksService.js"; +import { getChecksParamValidation, getChecksQueryValidation } from "@/api/validation/checkValidation.js"; +import type { IGeoChecksService } from "@/domain/geo-checks/geo-check.service.js"; import { requireTeamId } from "./controllerUtils.js"; -import { AppError } from "@/utils/AppError.js"; const SERVICE_NAME = "geoCheckController"; diff --git a/server/src/controllers/incidentController.ts b/server/src/api/controllers/incidentController.ts similarity index 96% rename from server/src/controllers/incidentController.ts rename to server/src/api/controllers/incidentController.ts index 03f1c7fe4..6358d2a89 100644 --- a/server/src/controllers/incidentController.ts +++ b/server/src/api/controllers/incidentController.ts @@ -1,8 +1,8 @@ import { AppError } from "@/utils/AppError.js"; import { Request, Response, NextFunction } from "express"; import { requireTeamId, requireUserId, requireUserEmail, extractString } from "./controllerUtils.js"; -import { IIncidentService } from "@/service/index.js"; -import { getIncidentsByTeamQueryValidation, getIncidentSummaryQueryValidation } from "@/validation/incidentValidation.js"; +import { IIncidentService } from "@/domain/incidents/incident.service.js"; +import { getIncidentsByTeamQueryValidation, getIncidentSummaryQueryValidation } from "@/api/validation/incidentValidation.js"; const SERVICE_NAME = "IncidentController"; diff --git a/server/src/controllers/inviteController.ts b/server/src/api/controllers/inviteController.ts similarity index 94% rename from server/src/controllers/inviteController.ts rename to server/src/api/controllers/inviteController.ts index 700a7bc6a..c77385f7b 100755 --- a/server/src/controllers/inviteController.ts +++ b/server/src/api/controllers/inviteController.ts @@ -1,7 +1,7 @@ import { Request, Response, NextFunction } from "express"; -import { inviteBodyValidation, inviteVerificationBodyValidation } from "@/validation/authValidation.js"; -import { requireFirstName, requireTeamId, requireUserRoles } from "@/controllers/controllerUtils.js"; -import { IInviteService } from "@/service/index.js"; +import { inviteBodyValidation, inviteVerificationBodyValidation } from "@/api/validation/authValidation.js"; +import { requireFirstName, requireTeamId, requireUserRoles } from "@/api/controllers/controllerUtils.js"; +import { IInviteService } from "@/domain/invites/invite.service.js"; const SERVICE_NAME = "inviteController"; export interface IInviteController { diff --git a/server/src/controllers/logController.ts b/server/src/api/controllers/logController.ts similarity index 100% rename from server/src/controllers/logController.ts rename to server/src/api/controllers/logController.ts diff --git a/server/src/controllers/maintenanceWindowController.ts b/server/src/api/controllers/maintenanceWindowController.ts similarity index 95% rename from server/src/controllers/maintenanceWindowController.ts rename to server/src/api/controllers/maintenanceWindowController.ts index 441acfa80..ddbf4deca 100644 --- a/server/src/controllers/maintenanceWindowController.ts +++ b/server/src/api/controllers/maintenanceWindowController.ts @@ -7,9 +7,9 @@ import { getMaintenanceWindowsByMonitorIdParamValidation, getMaintenanceWindowsByTeamIdQueryValidation, deleteMaintenanceWindowByIdParamValidation, -} from "@/validation/maintenanceWindowValidation.js"; -import { requireTeamId } from "@/controllers/controllerUtils.js"; -import { IMaintenanceWindowService } from "@/service/index.js"; +} from "@/api/validation/maintenanceWindowValidation.js"; +import { requireTeamId } from "@/api/controllers/controllerUtils.js"; +import { IMaintenanceWindowService } from "@/domain/maintenance-windows/maintenance-window.service.js"; export interface IMaintenanceWindowController { createMaintenanceWindows: (req: Request, res: Response, next: NextFunction) => Promise; diff --git a/server/src/controllers/monitorController.ts b/server/src/api/controllers/monitorController.ts similarity index 97% rename from server/src/controllers/monitorController.ts rename to server/src/api/controllers/monitorController.ts index 25946ccdf..a0cb073d2 100644 --- a/server/src/controllers/monitorController.ts +++ b/server/src/api/controllers/monitorController.ts @@ -1,5 +1,5 @@ import { Request, Response, NextFunction } from "express"; -import { updateNotificationsValidation } from "@/validation/notificationValidation.js"; +import { updateNotificationsValidation } from "@/api/validation/notificationValidation.js"; import { getMonitorByIdParamValidation, getMonitorByIdQueryValidation, @@ -15,11 +15,12 @@ import { getUptimeDetailsByIdQueryValidation, importMonitorsBodyValidation, bulkPauseMonitorBodyValidation, -} from "@/validation/monitorValidation.js"; +} from "@/api/validation/monitorValidation.js"; import sslChecker from "ssl-checker"; -import { fetchMonitorCertificate, requireTeamId, requireUserId } from "@/controllers/controllerUtils.js"; +import { fetchMonitorCertificate, requireTeamId, requireUserId } from "@/api/controllers/controllerUtils.js"; import { AppError } from "@/utils/AppError.js"; -import { IMonitorService, INotificationsService } from "@/service/index.js"; +import { IMonitorService } from "@/domain/monitors/monitor.service.js"; +import { INotificationsService } from "@/domain/notifications/notification.service.js"; const SERVICE_NAME = "monitorController"; diff --git a/server/src/controllers/notificationController.ts b/server/src/api/controllers/notificationController.ts similarity index 95% rename from server/src/controllers/notificationController.ts rename to server/src/api/controllers/notificationController.ts index 301c15446..3aecfcad8 100644 --- a/server/src/controllers/notificationController.ts +++ b/server/src/api/controllers/notificationController.ts @@ -7,11 +7,11 @@ import { testNotificationBodyValidation, editNotificationParamValidation, testAllNotificationsBodyValidation, -} from "@/validation/notificationValidation.js"; +} from "@/api/validation/notificationValidation.js"; import { AppError } from "@/utils/AppError.js"; -import { INotificationsService } from "@/service/index.js"; +import { INotificationsService } from "@/domain/notifications/notification.service.js"; import { requireTeamId, requireUserId } from "./controllerUtils.js"; -import { IMonitorsRepository } from "@/repositories/index.js"; +import { IMonitorsRepository } from "@/domain/monitors/monitor.repository.interface.js"; const SERVICE_NAME = "NotificationController"; diff --git a/server/src/controllers/queueController.ts b/server/src/api/controllers/queueController.ts similarity index 93% rename from server/src/controllers/queueController.ts rename to server/src/api/controllers/queueController.ts index 3b0bb64ce..0561ba6f0 100755 --- a/server/src/controllers/queueController.ts +++ b/server/src/api/controllers/queueController.ts @@ -1,5 +1,5 @@ -import { IJobQueue } from "@/service/index.js"; -import { getQueueJobsQueryValidation } from "@/validation/queueValidation.js"; +import { IJobQueue } from "@/service/job-queues/job-queue.interface.js"; +import { getQueueJobsQueryValidation } from "@/api/validation/queueValidation.js"; import { Request, Response, NextFunction } from "express"; const SERVICE_NAME = "JobQueueController"; diff --git a/server/src/controllers/settingsController.ts b/server/src/api/controllers/settingsController.ts similarity index 91% rename from server/src/controllers/settingsController.ts rename to server/src/api/controllers/settingsController.ts index 485a90d64..4acfdf552 100644 --- a/server/src/controllers/settingsController.ts +++ b/server/src/api/controllers/settingsController.ts @@ -1,9 +1,10 @@ import { Request, Response, NextFunction } from "express"; -import { updateAppSettingsBodyValidation } from "@/validation/settingsValidation.js"; -import { sendTestEmailBodyValidation } from "@/validation/notificationValidation.js"; +import { updateAppSettingsBodyValidation } from "@/api/validation/settingsValidation.js"; +import { sendTestEmailBodyValidation } from "@/api/validation/notificationValidation.js"; import { AppError } from "@/utils/AppError.js"; -import { IEmailService, ISettingsService } from "@/service/index.js"; -import { Settings } from "@/types/settings.js"; +import { ISettingsService } from "@/domain/app-settings/app-settings.service.js"; +import { IEmailService } from "@/service/emailService.js"; +import { Settings } from "@/domain/app-settings/app-settings.type.js"; const SERVICE_NAME = "SettingsController"; diff --git a/server/src/controllers/statusPageController.ts b/server/src/api/controllers/statusPageController.ts similarity index 93% rename from server/src/controllers/statusPageController.ts rename to server/src/api/controllers/statusPageController.ts index 190c3a9fd..5771fa5e4 100644 --- a/server/src/controllers/statusPageController.ts +++ b/server/src/api/controllers/statusPageController.ts @@ -5,12 +5,12 @@ import { getStatusPageParamValidation, getStatusPageQueryValidation, imageValidation, -} from "@/validation/statusPageValidation.js"; +} from "@/api/validation/statusPageValidation.js"; import { AppError } from "@/utils/AppError.js"; -import { requireTeamId, requireUserId } from "@/controllers/controllerUtils.js"; -import { IStatusPageService } from "@/service/business/statusPageService.js"; -import { IMonitorsRepository } from "@/repositories/index.js"; -import { ISettingsService } from "@/service/system/settingsService.js"; +import { requireTeamId, requireUserId } from "@/api/controllers/controllerUtils.js"; +import { IStatusPageService } from "@/domain/status-pages/status-page.service.js"; +import { IMonitorsRepository } from "@/domain/monitors/monitor.repository.interface.js"; +import { ISettingsService } from "@/domain/app-settings/app-settings.service.js"; import { NormalizeData } from "@/utils/dataUtils.js"; const SERVICE_NAME = "statusPageController"; diff --git a/server/src/controllers/statusPageThemeFlag.ts b/server/src/api/controllers/statusPageThemeFlag.ts similarity index 95% rename from server/src/controllers/statusPageThemeFlag.ts rename to server/src/api/controllers/statusPageThemeFlag.ts index bd65d5cb2..0fc2baedc 100644 --- a/server/src/controllers/statusPageThemeFlag.ts +++ b/server/src/api/controllers/statusPageThemeFlag.ts @@ -1,4 +1,4 @@ -import { DEFAULT_STATUS_PAGE_THEME, DEFAULT_STATUS_PAGE_THEME_MODE, type StatusPage } from "@/types/statusPage.js"; +import { DEFAULT_STATUS_PAGE_THEME, DEFAULT_STATUS_PAGE_THEME_MODE, type StatusPage } from "@/domain/status-pages/status-page.type.js"; /** * When STATUS_PAGE_THEMES_ENABLED is false, the controller drops incoming diff --git a/server/src/controllers/tagController.ts b/server/src/api/controllers/tagController.ts similarity index 96% rename from server/src/controllers/tagController.ts rename to server/src/api/controllers/tagController.ts index 66b21dc6b..95dd81296 100644 --- a/server/src/controllers/tagController.ts +++ b/server/src/api/controllers/tagController.ts @@ -1,5 +1,5 @@ import { Request, Response, NextFunction } from "express"; -import { ITagsService } from "@/service/index.js"; +import { ITagsService } from "@/domain/tags/tag.service.js"; import { requireTeamId } from "./controllerUtils.js"; import { createTagBodyValidation, @@ -7,7 +7,7 @@ import { getTagByIdParamValidation, editTagParamValidation, deleteTagParamValidation, -} from "@/validation/index.js"; +} from "@/api/validation/index.js"; export interface ITagsController { createTag: (req: Request, res: Response, next: NextFunction) => Promise; diff --git a/server/src/middleware/handleErrors.ts b/server/src/api/middleware/handleErrors.ts similarity index 100% rename from server/src/middleware/handleErrors.ts rename to server/src/api/middleware/handleErrors.ts diff --git a/server/src/middleware/isAllowed.ts b/server/src/api/middleware/isAllowed.ts similarity index 92% rename from server/src/middleware/isAllowed.ts rename to server/src/api/middleware/isAllowed.ts index 21690ee38..67cc68f46 100755 --- a/server/src/middleware/isAllowed.ts +++ b/server/src/api/middleware/isAllowed.ts @@ -1,7 +1,7 @@ import type { Request, Response, NextFunction } from "express"; const SERVICE_NAME = "allowedRoles"; import { AppError } from "@/utils/AppError.js"; -import type { UserRole } from "@/types/index.js"; +import type { UserRole } from "@/domain/users/user.type.js"; const isAllowed = (allowedRoles: UserRole[]) => { return (req: Request, res: Response, next: NextFunction) => { diff --git a/server/src/middleware/rateLimiter.ts b/server/src/api/middleware/rateLimiter.ts similarity index 100% rename from server/src/middleware/rateLimiter.ts rename to server/src/api/middleware/rateLimiter.ts diff --git a/server/src/middleware/sanitization.ts b/server/src/api/middleware/sanitization.ts similarity index 100% rename from server/src/middleware/sanitization.ts rename to server/src/api/middleware/sanitization.ts diff --git a/server/src/middleware/verifyJWT.ts b/server/src/api/middleware/verifyJWT.ts similarity index 93% rename from server/src/middleware/verifyJWT.ts rename to server/src/api/middleware/verifyJWT.ts index 63218566c..0f0f28021 100644 --- a/server/src/middleware/verifyJWT.ts +++ b/server/src/api/middleware/verifyJWT.ts @@ -2,8 +2,8 @@ import { NextFunction, Request, Response } from "express"; import jwt from "jsonwebtoken"; import { AppError } from "@/utils/AppError.js"; -import type { ISettingsService } from "@/service/system/settingsService.js"; -import type { User } from "@/types/user.js"; +import type { ISettingsService } from "@/domain/app-settings/app-settings.service.js"; +import type { User } from "@/domain/users/user.type.js"; const SERVICE_NAME = "verifyJWT"; const TOKEN_PREFIX = "Bearer "; diff --git a/server/src/middleware/verifyStatusPageAccess.ts b/server/src/api/middleware/verifyStatusPageAccess.ts similarity index 88% rename from server/src/middleware/verifyStatusPageAccess.ts rename to server/src/api/middleware/verifyStatusPageAccess.ts index 25ea29c51..bd2d062a3 100644 --- a/server/src/middleware/verifyStatusPageAccess.ts +++ b/server/src/api/middleware/verifyStatusPageAccess.ts @@ -1,5 +1,5 @@ import { NextFunction, Request, RequestHandler, Response } from "express"; -import { IStatusPagesRepository } from "@/repositories/index.js"; +import { IStatusPagesRepository } from "@/domain/status-pages/status-page-repository.interface.js"; import { AppError } from "@/utils/AppError.js"; export const createVerifyStatusPageAccess = (statusPagesRepository: IStatusPagesRepository, verifyJWT: RequestHandler) => { diff --git a/server/src/routes/authRoute.ts b/server/src/api/routes/authRoute.ts old mode 100755 new mode 100644 similarity index 96% rename from server/src/routes/authRoute.ts rename to server/src/api/routes/authRoute.ts index af6fd4266..22055ae40 --- a/server/src/routes/authRoute.ts +++ b/server/src/api/routes/authRoute.ts @@ -1,7 +1,7 @@ import { Router, RequestHandler } from "express"; import { isAllowed } from "../middleware/isAllowed.js"; import multer from "multer"; -import { IAuthController } from "@/controllers/authController.js"; +import { IAuthController } from "@/api/controllers/authController.js"; const upload = multer(); diff --git a/server/src/routes/checkRoute.ts b/server/src/api/routes/checkRoute.ts old mode 100755 new mode 100644 similarity index 91% rename from server/src/routes/checkRoute.ts rename to server/src/api/routes/checkRoute.ts index 712bae969..171d79ab4 --- a/server/src/routes/checkRoute.ts +++ b/server/src/api/routes/checkRoute.ts @@ -1,7 +1,7 @@ import { Router } from "express"; import { isAllowed } from "../middleware/isAllowed.js"; -import { ICheckController } from "@/controllers/checkController.js"; +import { ICheckController } from "@/api/controllers/checkController.js"; class CheckRoutes { private router: Router; diff --git a/server/src/routes/diagnosticRoute.ts b/server/src/api/routes/diagnosticRoute.ts old mode 100755 new mode 100644 similarity index 88% rename from server/src/routes/diagnosticRoute.ts rename to server/src/api/routes/diagnosticRoute.ts index 32b857e8d..3fe29bc1e --- a/server/src/routes/diagnosticRoute.ts +++ b/server/src/api/routes/diagnosticRoute.ts @@ -1,6 +1,6 @@ import { RequestHandler, Router } from "express"; import { isAllowed } from "../middleware/isAllowed.js"; -import { IDiagnosticController } from "@/controllers/diagnosticController.js"; +import { IDiagnosticController } from "@/api/controllers/diagnosticController.js"; class DiagnosticRoutes { private router: Router; diff --git a/server/src/routes/geoCheckRoutes.ts b/server/src/api/routes/geoCheckRoutes.ts similarity index 85% rename from server/src/routes/geoCheckRoutes.ts rename to server/src/api/routes/geoCheckRoutes.ts index 1fc48d7b3..bf9178afe 100644 --- a/server/src/routes/geoCheckRoutes.ts +++ b/server/src/api/routes/geoCheckRoutes.ts @@ -1,4 +1,4 @@ -import { IGeoCheckController } from "@/controllers/geoCheckController.js"; +import { IGeoCheckController } from "@/api/controllers/geoCheckController.js"; import { Router } from "express"; class GeoCheckRoutes { diff --git a/server/src/routes/incidentRoute.ts b/server/src/api/routes/incidentRoute.ts similarity index 91% rename from server/src/routes/incidentRoute.ts rename to server/src/api/routes/incidentRoute.ts index fdbb6f532..0f2f4485c 100644 --- a/server/src/routes/incidentRoute.ts +++ b/server/src/api/routes/incidentRoute.ts @@ -1,6 +1,6 @@ import { Router } from "express"; import { isAllowed } from "../middleware/isAllowed.js"; -import { IIncidentController } from "@/controllers/incidentController.js"; +import { IIncidentController } from "@/api/controllers/incidentController.js"; class IncidentRoutes { private router: Router; diff --git a/server/src/routes/inviteRoute.ts b/server/src/api/routes/inviteRoute.ts old mode 100755 new mode 100644 similarity index 91% rename from server/src/routes/inviteRoute.ts rename to server/src/api/routes/inviteRoute.ts index 4542bd21e..2e25694d2 --- a/server/src/routes/inviteRoute.ts +++ b/server/src/api/routes/inviteRoute.ts @@ -1,6 +1,6 @@ import { RequestHandler, Router } from "express"; import { isAllowed } from "../middleware/isAllowed.js"; -import { IInviteController } from "@/controllers/inviteController.js"; +import { IInviteController } from "@/api/controllers/inviteController.js"; class InviteRoutes { private router: Router; diff --git a/server/src/routes/logRoutes.ts b/server/src/api/routes/logRoutes.ts old mode 100755 new mode 100644 similarity index 77% rename from server/src/routes/logRoutes.ts rename to server/src/api/routes/logRoutes.ts index ea03d690e..ef98b5189 --- a/server/src/routes/logRoutes.ts +++ b/server/src/api/routes/logRoutes.ts @@ -1,6 +1,6 @@ import { Router } from "express"; -import { isAllowed } from "@/middleware/isAllowed.js"; -import { ILogController } from "@/controllers/logController.js"; +import { isAllowed } from "@/api/middleware/isAllowed.js"; +import { ILogController } from "@/api/controllers/logController.js"; class LogRoutes { private router: Router; private logController: ILogController; diff --git a/server/src/routes/maintenanceWindowRoute.ts b/server/src/api/routes/maintenanceWindowRoute.ts old mode 100755 new mode 100644 similarity index 90% rename from server/src/routes/maintenanceWindowRoute.ts rename to server/src/api/routes/maintenanceWindowRoute.ts index 1c2c139c0..43d03ff34 --- a/server/src/routes/maintenanceWindowRoute.ts +++ b/server/src/api/routes/maintenanceWindowRoute.ts @@ -1,4 +1,4 @@ -import { IMaintenanceWindowController } from "@/controllers/maintenanceWindowController.js"; +import { IMaintenanceWindowController } from "@/api/controllers/maintenanceWindowController.js"; import { Router } from "express"; class MaintenanceWindowRoutes { diff --git a/server/src/routes/monitorRoute.ts b/server/src/api/routes/monitorRoute.ts old mode 100755 new mode 100644 similarity index 95% rename from server/src/routes/monitorRoute.ts rename to server/src/api/routes/monitorRoute.ts index 0b5e24dd0..29834ce70 --- a/server/src/routes/monitorRoute.ts +++ b/server/src/api/routes/monitorRoute.ts @@ -1,6 +1,6 @@ import { Router } from "express"; -import { isAllowed } from "@/middleware/isAllowed.js"; -import { IMonitorController } from "@/controllers/monitorController.js"; +import { isAllowed } from "@/api/middleware/isAllowed.js"; +import { IMonitorController } from "@/api/controllers/monitorController.js"; class MonitorRoutes { private router: Router; diff --git a/server/src/routes/notificationRoute.ts b/server/src/api/routes/notificationRoute.ts old mode 100755 new mode 100644 similarity index 91% rename from server/src/routes/notificationRoute.ts rename to server/src/api/routes/notificationRoute.ts index 4ec6ce3b6..16d9a7086 --- a/server/src/routes/notificationRoute.ts +++ b/server/src/api/routes/notificationRoute.ts @@ -1,4 +1,4 @@ -import { INotificationController } from "@/controllers/notificationController.js"; +import { INotificationController } from "@/api/controllers/notificationController.js"; import { Router } from "express"; class NotificationRoutes { private router: Router; diff --git a/server/src/routes/queueRoute.ts b/server/src/api/routes/queueRoute.ts old mode 100755 new mode 100644 similarity index 84% rename from server/src/routes/queueRoute.ts rename to server/src/api/routes/queueRoute.ts index d5d35147c..0a9d41bb1 --- a/server/src/routes/queueRoute.ts +++ b/server/src/api/routes/queueRoute.ts @@ -1,6 +1,6 @@ import { Router } from "express"; -import { isAllowed } from "@/middleware/isAllowed.js"; -import { IJobQueueController } from "@/controllers/queueController.js"; +import { isAllowed } from "@/api/middleware/isAllowed.js"; +import { IJobQueueController } from "@/api/controllers/queueController.js"; class QueueRoutes { private router: Router; private queueController: IJobQueueController; diff --git a/server/src/routes/settingsRoute.ts b/server/src/api/routes/settingsRoute.ts old mode 100755 new mode 100644 similarity index 90% rename from server/src/routes/settingsRoute.ts rename to server/src/api/routes/settingsRoute.ts index aec2319c2..3bb0e75fd --- a/server/src/routes/settingsRoute.ts +++ b/server/src/api/routes/settingsRoute.ts @@ -1,6 +1,6 @@ import { Router } from "express"; import { isAllowed } from "../middleware/isAllowed.js"; -import { ISettingsController } from "@/controllers/settingsController.js"; +import { ISettingsController } from "@/api/controllers/settingsController.js"; class SettingsRoutes { private router: Router; diff --git a/server/src/routes/statusPageRoute.ts b/server/src/api/routes/statusPageRoute.ts old mode 100755 new mode 100644 similarity index 93% rename from server/src/routes/statusPageRoute.ts rename to server/src/api/routes/statusPageRoute.ts index 871a67300..807970e4b --- a/server/src/routes/statusPageRoute.ts +++ b/server/src/api/routes/statusPageRoute.ts @@ -1,4 +1,4 @@ -import { IStatusPageController } from "@/controllers/statusPageController.js"; +import { IStatusPageController } from "@/api/controllers/statusPageController.js"; import { RequestHandler, Router } from "express"; import multer from "multer"; const upload = multer(); diff --git a/server/src/routes/tagRoutes.ts b/server/src/api/routes/tagRoutes.ts similarity index 90% rename from server/src/routes/tagRoutes.ts rename to server/src/api/routes/tagRoutes.ts index 9b237c976..c1a3f7972 100644 --- a/server/src/routes/tagRoutes.ts +++ b/server/src/api/routes/tagRoutes.ts @@ -1,4 +1,4 @@ -import { ITagsController } from "@/controllers/tagController.js"; +import { ITagsController } from "@/api/controllers/tagController.js"; import { Router } from "express"; class TagRoutes { private router: Router; diff --git a/server/src/validation/authValidation.ts b/server/src/api/validation/authValidation.ts similarity index 96% rename from server/src/validation/authValidation.ts rename to server/src/api/validation/authValidation.ts index d8f592cee..be30272e6 100644 --- a/server/src/validation/authValidation.ts +++ b/server/src/api/validation/authValidation.ts @@ -1,6 +1,6 @@ import { z } from "zod"; import { passwordPattern, nameValidation, lowercaseEmailValidation } from "./shared.js"; -import { UserRoles } from "@/types/user.js"; +import { UserRoles } from "@/domain/users/user.type.js"; //**************************************** // Auth Validations diff --git a/server/src/validation/checkValidation.ts b/server/src/api/validation/checkValidation.ts similarity index 91% rename from server/src/validation/checkValidation.ts rename to server/src/api/validation/checkValidation.ts index 0c58b9df1..db0978357 100644 --- a/server/src/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 "@/types/geoCheck.js"; -import { MonitorTypes } from "@/types/monitor.js"; +import { GeoContinents } from "@/domain/geo-checks/geo-check.type.js"; +import { MonitorTypes } from "@/domain/monitors/monitor.types.js"; //**************************************** // Check Validations diff --git a/server/src/validation/incidentValidation.ts b/server/src/api/validation/incidentValidation.ts similarity index 100% rename from server/src/validation/incidentValidation.ts rename to server/src/api/validation/incidentValidation.ts diff --git a/server/src/validation/index.ts b/server/src/api/validation/index.ts similarity index 94% rename from server/src/validation/index.ts rename to server/src/api/validation/index.ts index 8627d3892..55c586769 100644 --- a/server/src/validation/index.ts +++ b/server/src/api/validation/index.ts @@ -9,7 +9,7 @@ export * from "./shared.js"; // Environment validation -export * from "./envValidation.js"; +export * from "@/config/envValidation.js"; // Domain-specific validations export * from "./authValidation.js"; diff --git a/server/src/validation/maintenanceWindowValidation.ts b/server/src/api/validation/maintenanceWindowValidation.ts similarity index 96% rename from server/src/validation/maintenanceWindowValidation.ts rename to server/src/api/validation/maintenanceWindowValidation.ts index 837db28e8..2ee22bc19 100644 --- a/server/src/validation/maintenanceWindowValidation.ts +++ b/server/src/api/validation/maintenanceWindowValidation.ts @@ -1,6 +1,6 @@ import { z } from "zod"; import { booleanCoercion } from "./shared.js"; -import { DurationUnits } from "@/types/maintenanceWindow.js"; +import { DurationUnits } from "@/domain/maintenance-windows/maintenance-window.type.js"; const dateToString = z.coerce.date().transform((d) => d.toISOString()); diff --git a/server/src/validation/monitorValidation.ts b/server/src/api/validation/monitorValidation.ts similarity index 97% rename from server/src/validation/monitorValidation.ts rename to server/src/api/validation/monitorValidation.ts index 2d70830b7..f44cc88ae 100644 --- a/server/src/validation/monitorValidation.ts +++ b/server/src/api/validation/monitorValidation.ts @@ -1,7 +1,14 @@ import { z } from "zod"; import { booleanCoercion, dnsHostnameRegex, dnsServerValidation } from "./shared.js"; -import { GeoContinents } from "@/types/geoCheck.js"; -import { DnsRecordTypes, HttpStatusCodeSet, MonitorMatchMethods, MonitorStatuses, MonitorTypes, PageSpeedStrategies } from "@/types/monitor.js"; +import { GeoContinents } from "@/domain/geo-checks/geo-check.type.js"; +import { + DnsRecordTypes, + HttpStatusCodeSet, + MonitorMatchMethods, + MonitorStatuses, + MonitorTypes, + PageSpeedStrategies, +} from "@/domain/monitors/monitor.types.js"; const httpStatusCode = z.number().refine((code) => HttpStatusCodeSet.has(code), { message: "Must be a valid HTTP status code" }); diff --git a/server/src/validation/notificationValidation.ts b/server/src/api/validation/notificationValidation.ts similarity index 100% rename from server/src/validation/notificationValidation.ts rename to server/src/api/validation/notificationValidation.ts diff --git a/server/src/validation/queueValidation.ts b/server/src/api/validation/queueValidation.ts similarity index 100% rename from server/src/validation/queueValidation.ts rename to server/src/api/validation/queueValidation.ts diff --git a/server/src/validation/settingsValidation.ts b/server/src/api/validation/settingsValidation.ts similarity index 95% rename from server/src/validation/settingsValidation.ts rename to server/src/api/validation/settingsValidation.ts index db58c50ed..d118cbd4f 100644 --- a/server/src/validation/settingsValidation.ts +++ b/server/src/api/validation/settingsValidation.ts @@ -1,4 +1,4 @@ -import { CHECK_TTL_SENTINEL } from "@/types/check.js"; +import { CHECK_TTL_SENTINEL } from "@/domain/checks/check.type.js"; import { z } from "zod"; //**************************************** diff --git a/server/src/validation/shared.ts b/server/src/api/validation/shared.ts similarity index 97% rename from server/src/validation/shared.ts rename to server/src/api/validation/shared.ts index a3e17866b..18b8ba463 100644 --- a/server/src/validation/shared.ts +++ b/server/src/api/validation/shared.ts @@ -1,5 +1,5 @@ import { z } from "zod"; -import { type UserRole } from "@/types/user.js"; +import { type UserRole } from "@/domain/users/user.type.js"; export const passwordPattern = /^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!?@#$%^&*()\-_=+[\]{};:'",.~`|\\/])[A-Za-z0-9!?@#$%^&*()\-_=+[\]{};:'",.~`|\\/]+$/; diff --git a/server/src/validation/statusPageValidation.ts b/server/src/api/validation/statusPageValidation.ts similarity index 97% rename from server/src/validation/statusPageValidation.ts rename to server/src/api/validation/statusPageValidation.ts index 6a42d340c..58595e24f 100644 --- a/server/src/validation/statusPageValidation.ts +++ b/server/src/api/validation/statusPageValidation.ts @@ -1,6 +1,6 @@ import { z } from "zod"; import { booleanCoercion } from "./shared.js"; -import { StatusPageTypes, StatusPageThemes, StatusPageThemeModes } from "@/types/statusPage.js"; +import { StatusPageTypes, StatusPageThemes, StatusPageThemeModes } from "@/domain/status-pages/status-page.type.js"; //**************************************** // Status Page Validations diff --git a/server/src/validation/tagValidation.ts b/server/src/api/validation/tagValidation.ts similarity index 100% rename from server/src/validation/tagValidation.ts rename to server/src/api/validation/tagValidation.ts diff --git a/server/src/validation/userValidation.ts b/server/src/api/validation/userValidation.ts similarity index 97% rename from server/src/validation/userValidation.ts rename to server/src/api/validation/userValidation.ts index 40e7d8b54..21fb55317 100644 --- a/server/src/validation/userValidation.ts +++ b/server/src/api/validation/userValidation.ts @@ -1,5 +1,5 @@ import { z } from "zod"; -import { UserRoles } from "@/types/user.js"; +import { UserRoles } from "@/domain/users/user.type.js"; import { nameValidation, lowercaseEmailValidation, passwordValidation } from "./shared.js"; //**************************************** diff --git a/server/src/app.ts b/server/src/app.ts index da1cd8ad9..e397b798c 100644 --- a/server/src/app.ts +++ b/server/src/app.ts @@ -5,13 +5,13 @@ import helmet from "helmet"; import compression from "compression"; import cookieParser from "cookie-parser"; import swaggerUi, { type JsonObject } from "swagger-ui-express"; -import { handleErrors } from "@/middleware/handleErrors.js"; -import { generalApiLimiter } from "@/middleware/rateLimiter.js"; -import { sanitizeBody, sanitizeQuery } from "@/middleware/sanitization.js"; +import { handleErrors } from "@/api/middleware/handleErrors.js"; +import { generalApiLimiter } from "@/api/middleware/rateLimiter.js"; +import { sanitizeBody, sanitizeQuery } from "@/api/middleware/sanitization.js"; import { setupRoutes } from "@/config/routes.js"; import { InitializedServices } from "@/config/services.js"; import { InitializedControllers } from "@/config/controllers.js"; -import { EnvConfig } from "@/service/system/settingsService.js"; +import { EnvConfig } from "@/domain/app-settings/app-settings.service.js"; export const createApp = ({ services, diff --git a/server/src/config/controllers.ts b/server/src/config/controllers.ts index e757cfa22..09dc6651b 100644 --- a/server/src/config/controllers.ts +++ b/server/src/config/controllers.ts @@ -1,17 +1,17 @@ -import MonitorController from "../controllers/monitorController.js"; -import AuthController from "../controllers/authController.js"; -import SettingsController from "../controllers/settingsController.js"; -import CheckController from "../controllers/checkController.js"; -import GeoCheckController from "../controllers/geoCheckController.js"; -import InviteController from "../controllers/inviteController.js"; -import MaintenanceWindowController from "../controllers/maintenanceWindowController.js"; -import QueueController from "../controllers/queueController.js"; -import LogController from "../controllers/logController.js"; -import StatusPageController from "../controllers/statusPageController.js"; -import NotificationController from "../controllers/notificationController.js"; -import TagsController from "../controllers/tagController.js"; -import DiagnosticController from "../controllers/diagnosticController.js"; -import IncidentController from "../controllers/incidentController.js"; +import MonitorController from "../api/controllers/monitorController.js"; +import AuthController from "../api/controllers/authController.js"; +import SettingsController from "../api/controllers/settingsController.js"; +import CheckController from "../api/controllers/checkController.js"; +import GeoCheckController from "../api/controllers/geoCheckController.js"; +import InviteController from "../api/controllers/inviteController.js"; +import MaintenanceWindowController from "../api/controllers/maintenanceWindowController.js"; +import QueueController from "../api/controllers/queueController.js"; +import LogController from "../api/controllers/logController.js"; +import StatusPageController from "../api/controllers/statusPageController.js"; +import NotificationController from "../api/controllers/notificationController.js"; +import TagsController from "../api/controllers/tagController.js"; +import DiagnosticController from "../api/controllers/diagnosticController.js"; +import IncidentController from "../api/controllers/incidentController.js"; import type { InitializedServices } from "@/config/services.js"; export interface InitializedControllers { diff --git a/server/src/validation/envValidation.ts b/server/src/config/envValidation.ts similarity index 90% rename from server/src/validation/envValidation.ts rename to server/src/config/envValidation.ts index 5280a8036..9d83336dc 100644 --- a/server/src/validation/envValidation.ts +++ b/server/src/config/envValidation.ts @@ -1,6 +1,6 @@ import { z } from "zod"; -import { DbTypes, QueueTypes, QueueModes } from "@/types/settings.js"; -import { booleanCoercion } from "./shared.js"; +import { DbTypes, QueueTypes, QueueModes } from "@/domain/app-settings/app-settings.type.js"; +import { booleanCoercion } from "@/api/validation/shared.js"; const envSchema = z.object({ // Server Configuration diff --git a/server/src/config/routes.ts b/server/src/config/routes.ts index cff5e6b1d..d3fbab2c7 100644 --- a/server/src/config/routes.ts +++ b/server/src/config/routes.ts @@ -1,25 +1,25 @@ import type { Application } from "express"; -import { createVerifyJWT } from "../middleware/verifyJWT.js"; -import { createVerifyStatusPageAccess } from "../middleware/verifyStatusPageAccess.js"; -import { authApiLimiter } from "../middleware/rateLimiter.js"; +import { createVerifyJWT } from "../api/middleware/verifyJWT.js"; +import { createVerifyStatusPageAccess } from "../api/middleware/verifyStatusPageAccess.js"; +import { authApiLimiter } from "../api/middleware/rateLimiter.js"; import type { InitializedControllers } from "./controllers.js"; import type { InitializedServices } from "./services.js"; -import AuthRoutes from "../routes/authRoute.js"; -import InviteRoutes from "../routes/inviteRoute.js"; -import MonitorRoutes from "../routes/monitorRoute.js"; -import CheckRoutes from "../routes/checkRoute.js"; -import GeoCheckRoutes from "../routes/geoCheckRoutes.js"; -import SettingsRoutes from "../routes/settingsRoute.js"; -import MaintenanceWindowRoutes from "../routes/maintenanceWindowRoute.js"; -import StatusPageRoutes from "../routes/statusPageRoute.js"; -import QueueRoutes from "../routes/queueRoute.js"; -import LogRoutes from "../routes/logRoutes.js"; -import DiagnosticRoutes from "../routes/diagnosticRoute.js"; -import NotificationRoutes from "../routes/notificationRoute.js"; -import TagRoutes from "../routes/tagRoutes.js"; +import AuthRoutes from "../api/routes/authRoute.js"; +import InviteRoutes from "../api/routes/inviteRoute.js"; +import MonitorRoutes from "../api/routes/monitorRoute.js"; +import CheckRoutes from "../api/routes/checkRoute.js"; +import GeoCheckRoutes from "../api/routes/geoCheckRoutes.js"; +import SettingsRoutes from "../api/routes/settingsRoute.js"; +import MaintenanceWindowRoutes from "../api/routes/maintenanceWindowRoute.js"; +import StatusPageRoutes from "../api/routes/statusPageRoute.js"; +import QueueRoutes from "../api/routes/queueRoute.js"; +import LogRoutes from "../api/routes/logRoutes.js"; +import DiagnosticRoutes from "../api/routes/diagnosticRoute.js"; +import NotificationRoutes from "../api/routes/notificationRoute.js"; +import TagRoutes from "../api/routes/tagRoutes.js"; -import IncidentRoutes from "../routes/incidentRoute.js"; +import IncidentRoutes from "../api/routes/incidentRoute.js"; export const setupRoutes = (app: Application, controllers: InitializedControllers, services: InitializedServices) => { const verifyJWT = createVerifyJWT(services.settingsService); diff --git a/server/src/config/services.ts b/server/src/config/services.ts index 818ef1663..9aed9c968 100644 --- a/server/src/config/services.ts +++ b/server/src/config/services.ts @@ -1,75 +1,52 @@ import { Mongoose } from "mongoose"; -import MongoDB from "../db/MongoDB.js"; -import { IDb } from "@/db/IDb.js"; -import { - // Service classes - NetworkService, - EmailService, - BufferService, - GlobalPingService, - LessSimpleQueue, - SuperSimpleQueue, - QueueHelper, - NotificationsService, - TagsService, - StatusService, - NotificationMessageBuilder, - MonitorService, - StatusPageService, - UserService, - CheckService, - GeoChecksService, - DiagnosticService, - InviteService, - MaintenanceWindowService, - IncidentService, - // Notification providers - WebhookProvider, - SlackProvider, - EmailProvider, - DiscordProvider, - PagerDutyProvider, - MatrixProvider, - TeamsProvider, - TelegramProvider, - PushoverProvider, - TwilioProvider, - NtfyProvider, - // Interfaces - INetworkService, - IEmailService, - IBufferService, - IJobQueue, - INotificationsService, - ITagsService, - IStatusService, - IMonitorService, - IUserService, - ICheckService, - IGeoChecksService, - IDiagnosticService, - IInviteService, - IMaintenanceWindowService, - IStatusPageService, - IIncidentService, - INotificationMessageBuilder, - ISettingsService, - SettingsService, - EnvConfig, -} from "@/service/index.js"; +import MongoDB from "../db/db.mongo.js"; +import { IDb } from "@/db/db.interface.js"; +import { EnvConfig, ISettingsService, SettingsService } from "@/domain/app-settings/app-settings.service.js"; +import { CheckService, ICheckService } from "@/domain/checks/check.service.js"; +import { DiagnosticService, IDiagnosticService } from "@/domain/diagnostics/diagnostic.service.js"; +import { GeoChecksService, IGeoChecksService } from "@/domain/geo-checks/geo-check.service.js"; +import { IIncidentService, IncidentService } from "@/domain/incidents/incident.service.js"; +import { IInviteService, InviteService } from "@/domain/invites/invite.service.js"; +import { IMaintenanceWindowService, MaintenanceWindowService } from "@/domain/maintenance-windows/maintenance-window.service.js"; +import { IMonitorService, MonitorService } from "@/domain/monitors/monitor.service.js"; +import { INotificationMessageBuilder, NotificationMessageBuilder } from "@/domain/notifications/notification.message-builder.js"; +import { INotificationsService, NotificationsService } from "@/domain/notifications/notification.service.js"; +import { DiscordProvider } from "@/domain/notifications/providers/discord.js"; +import { EmailProvider } from "@/domain/notifications/providers/email.js"; +import { MatrixProvider } from "@/domain/notifications/providers/matrix.js"; +import { NtfyProvider } from "@/domain/notifications/providers/ntfy.js"; +import { PagerDutyProvider } from "@/domain/notifications/providers/pagerduty.js"; +import { PushoverProvider } from "@/domain/notifications/providers/pushover.js"; +import { SlackProvider } from "@/domain/notifications/providers/slack.js"; +import { TeamsProvider } from "@/domain/notifications/providers/teams.js"; +import { TelegramProvider } from "@/domain/notifications/providers/telegram.js"; +import { TwilioProvider } from "@/domain/notifications/providers/twilio.js"; +import { WebhookProvider } from "@/domain/notifications/providers/webhook.js"; +import { IStatusPageService, StatusPageService } from "@/domain/status-pages/status-page.service.js"; +import { ITagsService, TagsService } from "@/domain/tags/tag.service.js"; +import { IUserService, UserService } from "@/domain/users/user.service.js"; +import { BufferService, IBufferService } from "@/service/bufferService.js"; +import { EmailService, IEmailService } from "@/service/emailService.js"; +import { GlobalPingService } from "@/service/globalPingService.js"; +import { QueueHelper } from "@/service/job-queues/job-queue.helper.js"; +import { IJobQueue } from "@/service/job-queues/job-queue.interface.js"; +import { LessSimpleQueue } from "@/service/job-queues/job-queue.less-simple.js"; +import { SuperSimpleQueue } from "@/service/job-queues/job-queue.sumper-simple.js"; +import { INetworkService, NetworkService } from "@/service/networkService.js"; +import { IStatusService, StatusService } from "@/service/statusService.js"; // Network providers -import { PingProvider } from "@/service/infrastructure/network/PingProvider.js"; -import { HttpProvider } from "@/service/infrastructure/network/HttpProvider.js"; -import { AdvancedMatcher } from "@/service/infrastructure/network/AdvancedMatcher.js"; -import { PageSpeedProvider } from "@/service/infrastructure/network/PageSpeedProvider.js"; -import { HardwareProvider } from "@/service/infrastructure/network/HardwareProvider.js"; -import { DockerProvider } from "@/service/infrastructure/network/DockerProvider.js"; -import { PortProvider } from "@/service/infrastructure/network/PortProvider.js"; -import { GameProvider } from "@/service/infrastructure/network/GameProvider.js"; -import { GrpcProvider } from "@/service/infrastructure/network/GrpcProvider.js"; -import { WebSocketProvider } from "@/service/infrastructure/network/WebSocketProvider.js"; -import { DNSProvider } from "@/service/infrastructure/network/DNSProvider.js"; +import { PingProvider } from "@/service/network/PingProvider.js"; +import { HttpProvider } from "@/service/network/HttpProvider.js"; +import { AdvancedMatcher } from "@/service/network/AdvancedMatcher.js"; +import { PageSpeedProvider } from "@/service/network/PageSpeedProvider.js"; +import { HardwareProvider } from "@/service/network/HardwareProvider.js"; +import { DockerProvider } from "@/service/network/DockerProvider.js"; +import { PortProvider } from "@/service/network/PortProvider.js"; +import { GameProvider } from "@/service/network/GameProvider.js"; +import { GrpcProvider } from "@/service/network/GrpcProvider.js"; +import { WebSocketProvider } from "@/service/network/WebSocketProvider.js"; +import { DNSProvider } from "@/service/network/DNSProvider.js"; // Third-party import { Resolver } from "dns/promises"; @@ -93,40 +70,38 @@ import * as protoLoader from "@grpc/proto-loader"; import WebSocket from "ws"; // Repositories -import { - MongoMonitorsRepository, - MongoChecksRepository, - MongoGeoChecksRepository, - MongoMonitorStatsRepository, - MongoStatusPagesRepository, - MongoUsersRepository, - MongoInvitesRepository, - MongoRecoveryTokensRepository, - MongoNotificationsRepository, - MongoTagsRepository, - MongoIncidentsRepository, - MongoTeamsRepository, - MongoMaintenanceWindowsRepository, - MongoSettingsRepository, - MongoQueueWorkersRepository, - IMonitorsRepository, - IChecksRepository, - IGeoChecksRepository, - IMonitorStatsRepository, - IStatusPagesRepository, - IUsersRepository, - IInvitesRepository, - IRecoveryTokensRepository, - ISettingsRepository, - INotificationsRepository, - ITagsRepository, - IIncidentsRepository, - ITeamsRepository, - IMaintenanceWindowsRepository, -} from "@/repositories/index.js"; +import { ISettingsRepository } from "@/domain/app-settings/app-settings-repository.interface.js"; +import MongoSettingsRepository from "@/domain/app-settings/app-settings.repository.mongo.js"; +import { IChecksRepository } from "@/domain/checks/check.repository.interface.js"; +import MongoChecksRepository from "@/domain/checks/check.repository.mongo.js"; +import { IGeoChecksRepository } from "@/domain/geo-checks/geo-check.repository.interface.js"; +import MongoGeoChecksRepository from "@/domain/geo-checks/geo-check.repository.mongo.js"; +import { IIncidentsRepository } from "@/domain/incidents/incident.repository.interface.js"; +import MongoIncidentsRepository from "@/domain/incidents/incident.repository.mongo.js"; +import { IInvitesRepository } from "@/domain/invites/invite.repository.interface.js"; +import MongoInvitesRepository from "@/domain/invites/invite.repository.mongo.js"; +import { IMaintenanceWindowsRepository } from "@/domain/maintenance-windows/maintenance-window.repository.interface.js"; +import MongoMaintenanceWindowsRepository from "@/domain/maintenance-windows/maintenance-window.repository.mongo.js"; +import { IMonitorStatsRepository } from "@/domain/monitor-stats/monitor-stats.repository.interface.js"; +import MongoMonitorStatsRepository from "@/domain/monitor-stats/monitor-stats.repository.mongo.js"; +import { IMonitorsRepository } from "@/domain/monitors/monitor.repository.interface.js"; +import MongoMonitorsRepository from "@/domain/monitors/monitor.repository.mongo.js"; +import { INotificationsRepository } from "@/domain/notifications/notification.repository.interface.js"; +import MongoNotificationsRepository from "@/domain/notifications/notification.repository.mongo.js"; +import MongoQueueWorkersRepository from "@/domain/queue-workers/queue-worker.repository.mongo.js"; +import { IRecoveryTokensRepository } from "@/domain/recovery-tokens/recovery-token.repository.interface.js"; +import MongoRecoveryTokensRepository from "@/domain/recovery-tokens/recovery-token.repository.mongo.js"; +import { IStatusPagesRepository } from "@/domain/status-pages/status-page-repository.interface.js"; +import MongoStatusPagesRepository from "@/domain/status-pages/status-page-repository.mongo.js"; +import { ITagsRepository } from "@/domain/tags/tag.repository.interface.js"; +import MongoTagsRepository from "@/domain/tags/tag.repository.mongo.js"; +import { ITeamsRepository } from "@/domain/teams/team.repository.interface.js"; +import MongoTeamsRepository from "@/domain/teams/team.repository.model.js"; +import { IUsersRepository } from "@/domain/users/user.repository.interface.js"; +import MongoUsersRepository from "@/domain/users/user.repository.mongo.js"; import { ILogger } from "@/utils/logger.js"; import { AppError } from "@/utils/AppError.js"; -import { type QueueMode } from "@/types/settings.js"; +import { type QueueMode } from "@/domain/app-settings/app-settings.type.js"; export type InitializedServices = { settingsService: ISettingsService; diff --git a/server/src/db/IDb.ts b/server/src/db/db.interface.ts similarity index 100% rename from server/src/db/IDb.ts rename to server/src/db/db.interface.ts diff --git a/server/src/db/MongoDB.ts b/server/src/db/db.mongo.ts similarity index 93% rename from server/src/db/MongoDB.ts rename to server/src/db/db.mongo.ts index 4531ce5a9..2585eb58b 100755 --- a/server/src/db/MongoDB.ts +++ b/server/src/db/db.mongo.ts @@ -1,11 +1,11 @@ import { Mongoose } from "mongoose"; import mongoose from "mongoose"; -import AppSettings from "@/db/models/AppSettings.js"; +import AppSettings from "@/domain/app-settings/app-settings.model.js"; import { runMigrations } from "@/db/migration/index.js"; import { ILogger } from "@/utils/logger.js"; -import { EnvConfig } from "@/service/system/settingsService.js"; +import { EnvConfig } from "@/domain/app-settings/app-settings.service.js"; const SERVICE_NAME = "MongoDB"; -import { IDb } from "@/db/IDb.js"; +import { IDb } from "@/db/db.interface.js"; import { AppError } from "@/utils/AppError.js"; class MongoDB implements IDb { diff --git a/server/src/db/migration/0001_migrateStatusWindowThreshold.ts b/server/src/db/migration/0001_migrateStatusWindowThreshold.ts index d9dd12aa1..c620ffc5f 100644 --- a/server/src/db/migration/0001_migrateStatusWindowThreshold.ts +++ b/server/src/db/migration/0001_migrateStatusWindowThreshold.ts @@ -1,4 +1,4 @@ -import Monitor from "@/db/models/Monitor.js"; +import Monitor from "@/domain/monitors/monitor.model.js"; async function migrateStatusWindowThreshold() { const monitors = await Monitor.find({ statusWindowThreshold: { $lt: 1 } }); for (const monitor of monitors) { diff --git a/server/src/db/migration/0003_cleanupDuplicateMonitorStats.ts b/server/src/db/migration/0003_cleanupDuplicateMonitorStats.ts index c4dff2fc0..f772b5229 100644 --- a/server/src/db/migration/0003_cleanupDuplicateMonitorStats.ts +++ b/server/src/db/migration/0003_cleanupDuplicateMonitorStats.ts @@ -1,4 +1,4 @@ -import { MonitorStatsModel } from "../models/MonitorStats.js"; +import { MonitorStatsModel } from "../../domain/monitor-stats/monitor-stats.model.js"; import { logger } from "@/utils/logger.js"; /** diff --git a/server/src/db/migration/0004_fixInfrastructureThresholds.ts b/server/src/db/migration/0004_fixInfrastructureThresholds.ts index bf6458565..dfc45c4fe 100644 --- a/server/src/db/migration/0004_fixInfrastructureThresholds.ts +++ b/server/src/db/migration/0004_fixInfrastructureThresholds.ts @@ -1,4 +1,4 @@ -import { MonitorModel } from "../models/Monitor.js"; +import { MonitorModel } from "../../domain/monitors/monitor.model.js"; import { logger } from "@/utils/logger.js"; /** diff --git a/server/src/db/migration/0005_migrateStatusPageTypeToArray.ts b/server/src/db/migration/0005_migrateStatusPageTypeToArray.ts index 0b13d1cb6..d5dcafbd1 100644 --- a/server/src/db/migration/0005_migrateStatusPageTypeToArray.ts +++ b/server/src/db/migration/0005_migrateStatusPageTypeToArray.ts @@ -1,6 +1,6 @@ import mongoose from "mongoose"; import { logger } from "@/utils/logger.js"; -import StatusPageModel from "../models/StatusPage.js"; +import StatusPageModel from "../../domain/status-pages/status-page.model.js"; export async function migrateStatusPageTypeToArray(): Promise { const SERVICE_NAME = "Migration:MigrateStatusPageTypeToArray"; diff --git a/server/src/db/migration/0006_cleanupDuplicateMonitorStatsForUniqueIndex.ts b/server/src/db/migration/0006_cleanupDuplicateMonitorStatsForUniqueIndex.ts index 814b19776..4a34e9926 100644 --- a/server/src/db/migration/0006_cleanupDuplicateMonitorStatsForUniqueIndex.ts +++ b/server/src/db/migration/0006_cleanupDuplicateMonitorStatsForUniqueIndex.ts @@ -1,4 +1,4 @@ -import { MonitorStatsModel } from "../models/MonitorStats.js"; +import { MonitorStatsModel } from "../../domain/monitor-stats/monitor-stats.model.js"; import { logger } from "@/utils/logger.js"; /** diff --git a/server/src/db/migration/0007_migrateMaintenanceWindowMonitorIdToArray.ts b/server/src/db/migration/0007_migrateMaintenanceWindowMonitorIdToArray.ts index a60b8786a..bf5766000 100644 --- a/server/src/db/migration/0007_migrateMaintenanceWindowMonitorIdToArray.ts +++ b/server/src/db/migration/0007_migrateMaintenanceWindowMonitorIdToArray.ts @@ -1,7 +1,7 @@ import mongoose from "mongoose"; import type { AnyBulkWriteOperation, Document } from "mongodb"; import { logger } from "@/utils/logger.js"; -import MaintenanceWindowModel from "../models/MaintenanceWindow.js"; +import MaintenanceWindowModel from "../../domain/maintenance-windows/maintenance-window.model.js"; type GroupResult = { _id: { diff --git a/server/src/db/migration/index.ts b/server/src/db/migration/index.ts index 61785118e..ac78cc813 100644 --- a/server/src/db/migration/index.ts +++ b/server/src/db/migration/index.ts @@ -2,7 +2,7 @@ import { migrateStatusWindowThreshold } from "./0001_migrateStatusWindowThreshol import { convertChecksToTimeSeries } from "./0002_convertChecksToTimeSeries.js"; import { cleanupDuplicateMonitorStats } from "./0003_cleanupDuplicateMonitorStats.js"; import { fixInfrastructureThresholds } from "./0004_fixInfrastructureThresholds.js"; -import MigrationModel from "../models/Migration.js"; +import MigrationModel from "../../domain/migrations/migration.model.js"; import { migrateStatusPageTypeToArray } from "./0005_migrateStatusPageTypeToArray.js"; import { cleanupDuplicateMonitorStatsForUniqueIndex } from "./0006_cleanupDuplicateMonitorStatsForUniqueIndex.js"; import { migrateMaintenanceWindowMonitorIdToArray } from "./0007_migrateMaintenanceWindowMonitorIdToArray.js"; diff --git a/server/src/db/models/index.ts b/server/src/db/models/index.ts deleted file mode 100644 index b825ca503..000000000 --- a/server/src/db/models/index.ts +++ /dev/null @@ -1,46 +0,0 @@ -export * from "@/db/models/Monitor.js"; -export { default as MonitorModel } from "@/db/models/Monitor.js"; - -export * from "@/db/models/Check.js"; -export { default as CheckModel } from "@/db/models/Check.js"; - -export * from "@/db/models/MonitorStats.js"; -export { default as MonitorStatsModel } from "@/db/models/MonitorStats.js"; - -export * from "@/db/models/StatusPage.js"; -export { default as StatusPageModel } from "@/db/models/StatusPage.js"; - -export * from "@/db/models/User.js"; -export { default as UserModel } from "@/db/models/User.js"; - -export * from "@/db/models/Invite.js"; -export { default as InviteModel } from "@/db/models/Invite.js"; - -export * from "@/db/models/AppSettings.js"; -export { default as AppSettingsModel } from "@/db/models/AppSettings.js"; - -export * from "@/db/models/RecoveryToken.js"; -export { default as RecoveryTokenModel } from "@/db/models/RecoveryToken.js"; - -export * from "@/db/models/Notification.js"; -export { default as NotificationModel } from "@/db/models/Notification.js"; - -export * from "@/db/models/Incident.js"; -export { default as IncidentModel } from "@/db/models/Incident.js"; - -export * from "@/db/models/Team.js"; -export { default as TeamModel } from "@/db/models/Team.js"; - -export * from "@/db/models/MaintenanceWindow.js"; -export { default as MaintenanceWindowModel } from "@/db/models/MaintenanceWindow.js"; - -export * from "@/db/models/GeoCheck.js"; -export { default as GeoCheckModel } from "@/db/models/GeoCheck.js"; - -export * from "@/db/models/DLQItem.js"; -export { default as DLQItemModel } from "@/db/models/DLQItem.js"; -export * from "@/db/models/Tag.js"; -export { default as TagModel } from "@/db/models/Tag.js"; - -export * from "@/db/models/QueueWorker.js"; -export { default as QueueWorkerModel } from "@/db/models/QueueWorker.js"; diff --git a/server/src/repositories/settings/ISettingsRepository.ts b/server/src/domain/app-settings/app-settings-repository.interface.ts similarity index 75% rename from server/src/repositories/settings/ISettingsRepository.ts rename to server/src/domain/app-settings/app-settings-repository.interface.ts index 0485a5aea..401d867f7 100644 --- a/server/src/repositories/settings/ISettingsRepository.ts +++ b/server/src/domain/app-settings/app-settings-repository.interface.ts @@ -1,4 +1,4 @@ -import type { Settings, SettingsUpdate } from "@/types/index.js"; +import type { Settings, SettingsUpdate } from "@/domain/app-settings/app-settings.type.js"; export interface ISettingsRepository { // create create(settings: Partial): Promise; diff --git a/server/src/db/models/AppSettings.ts b/server/src/domain/app-settings/app-settings.model.ts similarity index 94% rename from server/src/db/models/AppSettings.ts rename to server/src/domain/app-settings/app-settings.model.ts index 195f43044..da766fa83 100644 --- a/server/src/db/models/AppSettings.ts +++ b/server/src/domain/app-settings/app-settings.model.ts @@ -1,5 +1,5 @@ import { Schema, model, type Types } from "mongoose"; -import type { Settings, SettingsThresholds } from "@/types/settings.js"; +import type { Settings, SettingsThresholds } from "@/domain/app-settings/app-settings.type.js"; interface AppSettingsDocument extends Omit { _id: Types.ObjectId; diff --git a/server/src/repositories/settings/MongoSettingsRepository.ts b/server/src/domain/app-settings/app-settings.repository.mongo.ts similarity index 91% rename from server/src/repositories/settings/MongoSettingsRepository.ts rename to server/src/domain/app-settings/app-settings.repository.mongo.ts index 3117a94ea..ab242e4b7 100644 --- a/server/src/repositories/settings/MongoSettingsRepository.ts +++ b/server/src/domain/app-settings/app-settings.repository.mongo.ts @@ -1,7 +1,7 @@ import mongoose, { type UpdateQuery } from "mongoose"; -import { ISettingsRepository } from "@/repositories/settings/ISettingsRepository.js"; -import type { Settings, SettingsUpdate } from "@/types/index.js"; -import { AppSettingsModel, type AppSettingsDocument } from "@/db/models/index.js"; +import { ISettingsRepository } from "@/domain/app-settings/app-settings-repository.interface.js"; +import type { Settings, SettingsUpdate } from "@/domain/app-settings/app-settings.type.js"; +import { AppSettingsModel, type AppSettingsDocument } from "@/domain/app-settings/app-settings.model.js"; class MongoSettingsRepository implements ISettingsRepository { private toStringId = (value?: mongoose.Types.ObjectId | string | null): string => { diff --git a/server/src/service/system/settingsService.ts b/server/src/domain/app-settings/app-settings.service.ts similarity index 89% rename from server/src/service/system/settingsService.ts rename to server/src/domain/app-settings/app-settings.service.ts index dfbf6cfdc..ef14a932b 100755 --- a/server/src/service/system/settingsService.ts +++ b/server/src/domain/app-settings/app-settings.service.ts @@ -1,7 +1,7 @@ -import { ISettingsRepository } from "@/repositories/index.js"; -import { type DbType, type QueueType, type QueueMode, Settings, SettingsUpdate } from "@/types/index.js"; +import { ISettingsRepository } from "@/domain/app-settings/app-settings-repository.interface.js"; +import { Settings, SettingsUpdate, type DbType, type QueueMode, type QueueType } from "@/domain/app-settings/app-settings.type.js"; import { AppError } from "@/utils/AppError.js"; -import { ValidatedEnv } from "@/validation/envValidation.js"; +import { ValidatedEnv } from "@/config/envValidation.js"; import type { StringValue } from "ms"; const SERVICE_NAME = "SettingsService"; diff --git a/server/src/types/settings.ts b/server/src/domain/app-settings/app-settings.type.ts similarity index 75% rename from server/src/types/settings.ts rename to server/src/domain/app-settings/app-settings.type.ts index 4a4ff02a2..d1b4c254b 100644 --- a/server/src/types/settings.ts +++ b/server/src/domain/app-settings/app-settings.type.ts @@ -7,12 +7,6 @@ export type QueueType = (typeof QueueTypes)[number]; export const QueueModes = ["primary", "worker"] as const; export type QueueMode = (typeof QueueModes)[number]; -export type QueueWorker = { - workerId: string; // hostname:pid:uuid - mode: QueueMode; - lastSeenAt: number; // epoch ms of the last heartbeat -}; - export interface SettingsThresholds { cpu?: number; memory?: number; @@ -50,3 +44,20 @@ export interface Settings { createdAt: string; updatedAt: string; } + +export type EmailTransportConfig = Pick< + Settings, + | "systemEmailHost" + | "systemEmailPort" + | "systemEmailAddress" + | "systemEmailDisplayName" + | "systemEmailPassword" + | "systemEmailUser" + | "systemEmailConnectionHost" + | "systemEmailTLSServername" + | "systemEmailSecure" + | "systemEmailPool" + | "systemEmailIgnoreTLS" + | "systemEmailRequireTLS" + | "systemEmailRejectUnauthorized" +>; diff --git a/server/src/db/models/Check.ts b/server/src/domain/checks/check.model.ts similarity index 98% rename from server/src/db/models/Check.ts rename to server/src/domain/checks/check.model.ts index 964936af9..82be6937c 100644 --- a/server/src/db/models/Check.ts +++ b/server/src/domain/checks/check.model.ts @@ -1,5 +1,5 @@ import { Schema, model, Types } from "mongoose"; -import { MonitorTypes, type MonitorType } from "@/types/monitor.js"; +import { MonitorTypes, type MonitorType } from "@/domain/monitors/monitor.types.js"; import type { Check, CheckAudits, @@ -13,7 +13,7 @@ import type { CheckNetworkInterfaceInfo, GotTimings, ILighthouseAudit, -} from "@/types/check.js"; +} from "@/domain/checks/check.type.js"; type CheckMetadataDocument = Omit & { monitorId: Types.ObjectId; diff --git a/server/src/repositories/checks/IChecksRepository.ts b/server/src/domain/checks/check.repository.interface.ts similarity index 87% rename from server/src/repositories/checks/IChecksRepository.ts rename to server/src/domain/checks/check.repository.interface.ts index b96d14933..46c2a12c6 100644 --- a/server/src/repositories/checks/IChecksRepository.ts +++ b/server/src/domain/checks/check.repository.interface.ts @@ -2,12 +2,12 @@ import type { Check, ChecksQueryResult, ChecksSummary, - MonitorType, - PageSpeedChecksResult, HardwareChecksResult, + PageSpeedChecksResult, UptimeChecksResult, -} from "@/types/index.js"; -import type { LatestChecksMap } from "@/repositories/checks/MongoChecksRepistory.js"; +} 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"; export interface IChecksRepository { // create diff --git a/server/src/repositories/checks/MongoChecksRepistory.ts b/server/src/domain/checks/check.repository.mongo.ts similarity index 98% rename from server/src/repositories/checks/MongoChecksRepistory.ts rename to server/src/domain/checks/check.repository.mongo.ts index 4055ddfc3..35d3440c8 100644 --- a/server/src/repositories/checks/MongoChecksRepistory.ts +++ b/server/src/domain/checks/check.repository.mongo.ts @@ -1,4 +1,4 @@ -import { IChecksRepository } from "@/repositories/index.js"; +import { IChecksRepository } from "@/domain/checks/check.repository.interface.js"; import type { Check, CheckAudits, @@ -11,9 +11,9 @@ import type { CheckMetadata, CheckNetworkInterfaceInfo, GotTimings, - MonitorType, -} from "@/types/index.js"; -import { CheckModel, type CheckDocument } from "@/db/models/index.js"; +} from "@/domain/checks/check.type.js"; +import type { MonitorType } from "@/domain/monitors/monitor.types.js"; +import { CheckModel, type CheckDocument } from "@/domain/checks/check.model.js"; import mongoose from "mongoose"; import { getDateForRange } from "@/utils/dataUtils.js"; import { ILogger } from "@/utils/logger.js"; diff --git a/server/src/service/business/checkService.ts b/server/src/domain/checks/check.service.ts similarity index 94% rename from server/src/service/business/checkService.ts rename to server/src/domain/checks/check.service.ts index dd2a66202..58990eaaf 100644 --- a/server/src/service/business/checkService.ts +++ b/server/src/domain/checks/check.service.ts @@ -1,14 +1,8 @@ import { Types } from "mongoose"; -import { IChecksRepository, IMonitorsRepository } from "@/repositories/index.js"; -import type { - MonitorStatusResponse, - CheckErrorInfo, - Check, - ILighthouseAudit, - ChecksQueryResult, - ChecksSummary, - MonitorPayloadMap, -} from "@/types/index.js"; +import { IChecksRepository } from "@/domain/checks/check.repository.interface.js"; +import { IMonitorsRepository } from "@/domain/monitors/monitor.repository.interface.js"; +import type { Check, CheckErrorInfo, ChecksQueryResult, ChecksSummary, ILighthouseAudit } from "@/domain/checks/check.type.js"; +import type { MonitorPayloadMap, MonitorStatusResponse } from "@/types/network.js"; import type { HardwareStatusPayload, PageSpeedStatusPayload } from "@/types/network.js"; import { AppError } from "@/utils/AppError.js"; import { ILogger } from "@/utils/logger.js"; diff --git a/server/src/types/check.ts b/server/src/domain/checks/check.type.ts similarity index 98% rename from server/src/types/check.ts rename to server/src/domain/checks/check.type.ts index f4c64f926..fe733e4e9 100644 --- a/server/src/types/check.ts +++ b/server/src/domain/checks/check.type.ts @@ -1,4 +1,4 @@ -import type { MonitorType } from "@/types/index.js"; +import type { MonitorType } from "@/domain/monitors/monitor.types.js"; import type { Response } from "got"; export const CHECK_TTL_SENTINEL = 366; diff --git a/server/src/service/business/diagnosticService.ts b/server/src/domain/diagnostics/diagnostic.service.ts similarity index 98% rename from server/src/service/business/diagnosticService.ts rename to server/src/domain/diagnostics/diagnostic.service.ts index c5debf0e1..408b19cb5 100644 --- a/server/src/service/business/diagnosticService.ts +++ b/server/src/domain/diagnostics/diagnostic.service.ts @@ -1,6 +1,6 @@ import v8 from "v8"; import os from "os"; -import { IDb } from "@/db/IDb.js"; +import { IDb } from "@/db/db.interface.js"; import { Mongoose } from "mongoose"; import { AppError } from "@/utils/AppError.js"; diff --git a/server/src/db/models/DLQItem.ts b/server/src/domain/dlq/dlq.model.ts similarity index 93% rename from server/src/db/models/DLQItem.ts rename to server/src/domain/dlq/dlq.model.ts index 707846adb..1ece5a028 100644 --- a/server/src/db/models/DLQItem.ts +++ b/server/src/domain/dlq/dlq.model.ts @@ -1,5 +1,5 @@ import { Schema, model, type Types } from "mongoose"; -import { DLQItemTypes, DLQItemStatuses, type DLQItem } from "@/types/dlqItem.js"; +import { DLQItemTypes, DLQItemStatuses, type DLQItem } from "@/domain/dlq/dlq.type.js"; export interface DLQItemDocument extends Omit { _id: Types.ObjectId; diff --git a/server/src/repositories/dlq/IDLQRepository.ts b/server/src/domain/dlq/dlq.repository.interface.ts similarity index 90% rename from server/src/repositories/dlq/IDLQRepository.ts rename to server/src/domain/dlq/dlq.repository.interface.ts index 5e26e6096..43d4f75d5 100644 --- a/server/src/repositories/dlq/IDLQRepository.ts +++ b/server/src/domain/dlq/dlq.repository.interface.ts @@ -1,4 +1,4 @@ -import type { DLQItem, DLQItemType, DLQItemStatus } from "@/types/index.js"; +import type { DLQItem, DLQItemStatus, DLQItemType } from "@/domain/dlq/dlq.type.js"; export interface DLQQueryFilters { type?: DLQItemType; diff --git a/server/src/repositories/dlq/MongoDLQRepository.ts b/server/src/domain/dlq/dlq.repository.mongo.ts similarity index 94% rename from server/src/repositories/dlq/MongoDLQRepository.ts rename to server/src/domain/dlq/dlq.repository.mongo.ts index 8c9da76ad..4cf7bad85 100644 --- a/server/src/repositories/dlq/MongoDLQRepository.ts +++ b/server/src/domain/dlq/dlq.repository.mongo.ts @@ -1,7 +1,7 @@ -import { DLQItemModel } from "@/db/models/index.js"; -import type { DLQItemDocument } from "@/db/models/DLQItem.js"; -import type { DLQItem } from "@/types/index.js"; -import type { IDLQRepository, DLQQueryFilters, DLQStatusCount } from "@/repositories/dlq/IDLQRepository.js"; +import { DLQItemModel } from "@/domain/dlq/dlq.model.js"; +import type { DLQItemDocument } from "@/domain/dlq/dlq.model.js"; +import type { DLQItem } from "@/domain/dlq/dlq.type.js"; +import type { IDLQRepository, DLQQueryFilters, DLQStatusCount } from "@/domain/dlq/dlq.repository.interface.js"; import mongoose from "mongoose"; import { AppError } from "@/utils/AppError.js"; diff --git a/server/src/types/dlqItem.ts b/server/src/domain/dlq/dlq.type.ts similarity index 100% rename from server/src/types/dlqItem.ts rename to server/src/domain/dlq/dlq.type.ts diff --git a/server/src/db/models/GeoCheck.ts b/server/src/domain/geo-checks/geo-check.model.ts similarity index 94% rename from server/src/db/models/GeoCheck.ts rename to server/src/domain/geo-checks/geo-check.model.ts index 8c0749f00..0db895d0a 100644 --- a/server/src/db/models/GeoCheck.ts +++ b/server/src/domain/geo-checks/geo-check.model.ts @@ -1,6 +1,6 @@ import { Schema, model, Types } from "mongoose"; -import { MonitorTypes, type MonitorType } from "@/types/monitor.js"; -import type { GeoCheck, GeoCheckLocation, GeoCheckMetadata, GeoCheckResult, GeoCheckTimings } from "@/types/geoCheck.js"; +import { MonitorTypes, type MonitorType } from "@/domain/monitors/monitor.types.js"; +import type { GeoCheck, GeoCheckLocation, GeoCheckMetadata, GeoCheckResult, GeoCheckTimings } from "@/domain/geo-checks/geo-check.type.js"; type GeoCheckMetadataDocument = Omit & { monitorId: Types.ObjectId; diff --git a/server/src/repositories/geo-checks/IGeoChecksRepository.ts b/server/src/domain/geo-checks/geo-check.repository.interface.ts similarity index 84% rename from server/src/repositories/geo-checks/IGeoChecksRepository.ts rename to server/src/domain/geo-checks/geo-check.repository.interface.ts index fe4beb796..2e6f33e33 100644 --- a/server/src/repositories/geo-checks/IGeoChecksRepository.ts +++ b/server/src/domain/geo-checks/geo-check.repository.interface.ts @@ -1,5 +1,5 @@ -import type { GeoCheck, GroupedGeoCheck } from "@/types/geoCheck.js"; -import type { GeoContinent, FlatGeoCheck } from "@/types/geoCheck.js"; +import type { GeoCheck, GroupedGeoCheck } from "@/domain/geo-checks/geo-check.type.js"; +import type { GeoContinent, FlatGeoCheck } from "@/domain/geo-checks/geo-check.type.js"; export interface GeoChecksQueryResult { geoChecksCount: number; diff --git a/server/src/repositories/geo-checks/MongoGeoChecksRepository.ts b/server/src/domain/geo-checks/geo-check.repository.mongo.ts similarity index 97% rename from server/src/repositories/geo-checks/MongoGeoChecksRepository.ts rename to server/src/domain/geo-checks/geo-check.repository.mongo.ts index 0adcf7c9f..426fb533d 100644 --- a/server/src/repositories/geo-checks/MongoGeoChecksRepository.ts +++ b/server/src/domain/geo-checks/geo-check.repository.mongo.ts @@ -1,7 +1,7 @@ -import { IGeoChecksRepository } from "./IGeoChecksRepository.js"; -import type { GeoCheck, GeoCheckMetadata, GeoCheckResult, GroupedGeoCheck, GeoContinent, FlatGeoCheck } from "@/types/geoCheck.js"; -import type { FlatGeoChecksQueryResult } from "./IGeoChecksRepository.js"; -import { GeoCheckMetadataDocument, GeoCheckModel, type GeoCheckDocument } from "@/db/models/index.js"; +import { IGeoChecksRepository } from "./geo-check.repository.interface.js"; +import type { GeoCheck, GeoCheckMetadata, GeoCheckResult, GroupedGeoCheck, GeoContinent, FlatGeoCheck } from "@/domain/geo-checks/geo-check.type.js"; +import type { FlatGeoChecksQueryResult } from "./geo-check.repository.interface.js"; +import { GeoCheckMetadataDocument, GeoCheckModel, type GeoCheckDocument } from "@/domain/geo-checks/geo-check.model.js"; import mongoose, { PipelineStage } from "mongoose"; import { getDateForRange } from "@/utils/dataUtils.js"; import { ILogger } from "@/utils/logger.js"; diff --git a/server/src/service/business/geoChecksService.ts b/server/src/domain/geo-checks/geo-check.service.ts similarity index 92% rename from server/src/service/business/geoChecksService.ts rename to server/src/domain/geo-checks/geo-check.service.ts index 5f557506f..0ace565fc 100644 --- a/server/src/service/business/geoChecksService.ts +++ b/server/src/domain/geo-checks/geo-check.service.ts @@ -1,9 +1,10 @@ -import type { Monitor, GeoCheck } from "@/types/index.js"; -import type { GeoCheckResult, GeoContinent } from "@/types/geoCheck.js"; +import type { GeoCheck } from "@/domain/geo-checks/geo-check.type.js"; +import type { Monitor } from "@/domain/monitors/monitor.types.js"; +import type { GeoCheckResult, GeoContinent } from "@/domain/geo-checks/geo-check.type.js"; import { Types } from "mongoose"; -import type { FlatGeoChecksQueryResult, IGeoChecksRepository } from "@/repositories/index.js"; -import type { IMonitorsRepository } from "@/repositories/index.js"; -import type { IGlobalPingService } from "@/service/infrastructure/globalPingService.js"; +import type { FlatGeoChecksQueryResult, IGeoChecksRepository } from "@/domain/geo-checks/geo-check.repository.interface.js"; +import type { IMonitorsRepository } from "@/domain/monitors/monitor.repository.interface.js"; +import type { IGlobalPingService } from "@/service/globalPingService.js"; import type { ILogger } from "@/utils/logger.js"; import { AppError } from "@/utils/AppError.js"; diff --git a/server/src/types/geoCheck.ts b/server/src/domain/geo-checks/geo-check.type.ts similarity index 95% rename from server/src/types/geoCheck.ts rename to server/src/domain/geo-checks/geo-check.type.ts index 548c4c65f..044bec3b0 100644 --- a/server/src/types/geoCheck.ts +++ b/server/src/domain/geo-checks/geo-check.type.ts @@ -1,4 +1,4 @@ -import type { MonitorType } from "@/types/index.js"; +import type { MonitorType } from "@/domain/monitors/monitor.types.js"; export const GeoContinents = ["EU", "NA", "AS", "SA", "AF", "OC"] as const; export type GeoContinent = (typeof GeoContinents)[number]; diff --git a/server/src/db/models/Incident.ts b/server/src/domain/incidents/incident.model.ts similarity index 95% rename from server/src/db/models/Incident.ts rename to server/src/domain/incidents/incident.model.ts index 82e2b5eb2..9e252bb1d 100644 --- a/server/src/db/models/Incident.ts +++ b/server/src/domain/incidents/incident.model.ts @@ -1,5 +1,5 @@ import { Schema, model, type Types } from "mongoose"; -import { IncidentResolutionTypes, type Incident } from "@/types/incident.js"; +import { IncidentResolutionTypes, type Incident } from "@/domain/incidents/incident.type.js"; type IncidentDocumentBase = Omit & { monitorId: Types.ObjectId; diff --git a/server/src/repositories/incidents/IIncidentsRepository.ts b/server/src/domain/incidents/incident.repository.interface.ts similarity index 88% rename from server/src/repositories/incidents/IIncidentsRepository.ts rename to server/src/domain/incidents/incident.repository.interface.ts index c4fcef2ae..549a33b85 100644 --- a/server/src/repositories/incidents/IIncidentsRepository.ts +++ b/server/src/domain/incidents/incident.repository.interface.ts @@ -1,5 +1,5 @@ -import type { Incident } from "@/types/index.js"; -import type { IncidentSummary } from "@/types/index.js"; +import type { Incident } from "@/domain/incidents/incident.type.js"; +import type { IncidentSummary } from "@/domain/incidents/incident.type.js"; export interface IIncidentsRepository { // create create(incident: Partial): Promise; diff --git a/server/src/repositories/incidents/MongoIncidentsRepository.ts b/server/src/domain/incidents/incident.repository.mongo.ts similarity index 96% rename from server/src/repositories/incidents/MongoIncidentsRepository.ts rename to server/src/domain/incidents/incident.repository.mongo.ts index e24551462..4cf410e88 100644 --- a/server/src/repositories/incidents/MongoIncidentsRepository.ts +++ b/server/src/domain/incidents/incident.repository.mongo.ts @@ -1,7 +1,7 @@ -import { IncidentModel } from "@/db/models/index.js"; -import type { IncidentDocument } from "@/db/models/Incident.js"; -import type { Incident, IncidentSummary } from "@/types/index.js"; -import type { IIncidentsRepository } from "@/repositories/index.js"; +import { IncidentModel } from "@/domain/incidents/incident.model.js"; +import type { IncidentDocument } from "@/domain/incidents/incident.model.js"; +import type { Incident, IncidentSummary } from "@/domain/incidents/incident.type.js"; +import type { IIncidentsRepository } from "@/domain/incidents/incident.repository.interface.js"; import mongoose from "mongoose"; import { AppError } from "@/utils/AppError.js"; diff --git a/server/src/service/business/incidentService.ts b/server/src/domain/incidents/incident.service.ts similarity index 92% rename from server/src/service/business/incidentService.ts rename to server/src/domain/incidents/incident.service.ts index 1606cc95d..d588086b2 100644 --- a/server/src/service/business/incidentService.ts +++ b/server/src/domain/incidents/incident.service.ts @@ -1,12 +1,15 @@ const SERVICE_NAME = "incidentService"; -import type { Monitor } from "@/types/monitor.js"; +import type { Monitor } from "@/domain/monitors/monitor.types.js"; import type { MonitorStatusResponse } from "@/types/network.js"; import { AppError } from "@/utils/AppError.js"; import { getDateForRange } from "@/utils/dataUtils.js"; -import type { IIncidentsRepository, IMonitorsRepository, IUsersRepository } from "@/repositories/index.js"; -import type { Incident, IncidentSummary, User } from "@/types/index.js"; -import type { MonitorActionDecision } from "@/service/infrastructure/JobQueues/QueueHelper.js"; -import type { INotificationMessageBuilder } from "@/service/infrastructure/notificationMessageBuilder.js"; +import type { IIncidentsRepository } from "@/domain/incidents/incident.repository.interface.js"; +import type { IMonitorsRepository } from "@/domain/monitors/monitor.repository.interface.js"; +import type { IUsersRepository } from "@/domain/users/user.repository.interface.js"; +import type { Incident, IncidentSummary } from "@/domain/incidents/incident.type.js"; +import type { User } from "@/domain/users/user.type.js"; +import type { MonitorActionDecision } from "@/service/job-queues/job-queue.helper.js"; +import type { INotificationMessageBuilder } from "@/domain/notifications/notification.message-builder.js"; import type { ILogger } from "@/utils/logger.js"; export interface IIncidentService { diff --git a/server/src/types/incident.ts b/server/src/domain/incidents/incident.type.ts similarity index 100% rename from server/src/types/incident.ts rename to server/src/domain/incidents/incident.type.ts diff --git a/server/src/db/models/Invite.ts b/server/src/domain/invites/invite.model.ts similarity index 93% rename from server/src/db/models/Invite.ts rename to server/src/domain/invites/invite.model.ts index 25ddd9a72..a2bd6ae74 100755 --- a/server/src/db/models/Invite.ts +++ b/server/src/domain/invites/invite.model.ts @@ -1,5 +1,5 @@ import { Schema, model, type Types } from "mongoose"; -import type { Invite } from "@/types/invite.js"; +import type { Invite } from "@/domain/invites/invite.type.js"; type InviteDocumentBase = Omit & { teamId: Types.ObjectId; diff --git a/server/src/repositories/invites/IInvitesRepository.ts b/server/src/domain/invites/invite.repository.interface.ts similarity index 79% rename from server/src/repositories/invites/IInvitesRepository.ts rename to server/src/domain/invites/invite.repository.interface.ts index 74a7ad68c..348731e9c 100644 --- a/server/src/repositories/invites/IInvitesRepository.ts +++ b/server/src/domain/invites/invite.repository.interface.ts @@ -1,4 +1,4 @@ -import type { Invite } from "@/types/index.js"; +import type { Invite } from "@/domain/invites/invite.type.js"; export interface IInvitesRepository { // create diff --git a/server/src/repositories/invites/MongoInviteRepository.ts b/server/src/domain/invites/invite.repository.mongo.ts similarity index 88% rename from server/src/repositories/invites/MongoInviteRepository.ts rename to server/src/domain/invites/invite.repository.mongo.ts index a8187d09a..8956a08b3 100644 --- a/server/src/repositories/invites/MongoInviteRepository.ts +++ b/server/src/domain/invites/invite.repository.mongo.ts @@ -1,6 +1,6 @@ -import { IInvitesRepository } from "@/repositories/index.js"; -import type { Invite } from "@/types/index.js"; -import { type InviteDocument, InviteModel } from "@/db/models/index.js"; +import { IInvitesRepository } from "@/domain/invites/invite.repository.interface.js"; +import type { Invite } from "@/domain/invites/invite.type.js"; +import { type InviteDocument, InviteModel } from "@/domain/invites/invite.model.js"; import { AppError } from "@/utils/AppError.js"; import mongoose from "mongoose"; import crypto from "crypto"; diff --git a/server/src/service/business/inviteService.ts b/server/src/domain/invites/invite.service.ts similarity index 88% rename from server/src/service/business/inviteService.ts rename to server/src/domain/invites/invite.service.ts index 7e2b7de52..76c5c6289 100644 --- a/server/src/service/business/inviteService.ts +++ b/server/src/domain/invites/invite.service.ts @@ -1,9 +1,10 @@ -import type { Invite, UserRole } from "@/types/index.js"; -import { canManageRole } from "@/types/user.js"; -import type { IInvitesRepository } from "@/repositories/index.js"; +import type { Invite } from "@/domain/invites/invite.type.js"; +import type { UserRole } from "@/domain/users/user.type.js"; +import { canManageRole } from "@/domain/users/user.type.js"; +import type { IInvitesRepository } from "@/domain/invites/invite.repository.interface.js"; import { AppError } from "@/utils/AppError.js"; -import { ISettingsService } from "../system/settingsService.js"; -import { IEmailService } from "../infrastructure/emailService.js"; +import { ISettingsService } from "../app-settings/app-settings.service.js"; +import { IEmailService } from "@/service/emailService.js"; const SERVICE_NAME = "inviteService"; diff --git a/server/src/types/invite.ts b/server/src/domain/invites/invite.type.ts similarity index 73% rename from server/src/types/invite.ts rename to server/src/domain/invites/invite.type.ts index cdbdb37e5..e00c75d6b 100644 --- a/server/src/types/invite.ts +++ b/server/src/domain/invites/invite.type.ts @@ -1,4 +1,4 @@ -import type { UserRole } from "@/types/user.js"; +import type { UserRole } from "@/domain/users/user.type.js"; export interface Invite { id: string; diff --git a/server/src/db/models/MaintenanceWindow.ts b/server/src/domain/maintenance-windows/maintenance-window.model.ts similarity index 91% rename from server/src/db/models/MaintenanceWindow.ts rename to server/src/domain/maintenance-windows/maintenance-window.model.ts index 654ae50dd..c42ef3fdc 100644 --- a/server/src/db/models/MaintenanceWindow.ts +++ b/server/src/domain/maintenance-windows/maintenance-window.model.ts @@ -1,5 +1,5 @@ import { Schema, model, type Types } from "mongoose"; -import { DurationUnits, type MaintenanceWindow } from "@/types/maintenanceWindow.js"; +import { DurationUnits, type MaintenanceWindow } from "@/domain/maintenance-windows/maintenance-window.type.js"; type MaintenanceWindowDocumentBase = Omit & { monitorIds: Types.ObjectId[]; diff --git a/server/src/repositories/maintenance-windows/IMaintenanceWindowsRepository.ts b/server/src/domain/maintenance-windows/maintenance-window.repository.interface.ts similarity index 89% rename from server/src/repositories/maintenance-windows/IMaintenanceWindowsRepository.ts rename to server/src/domain/maintenance-windows/maintenance-window.repository.interface.ts index 0f4ad66a2..06384aed5 100644 --- a/server/src/repositories/maintenance-windows/IMaintenanceWindowsRepository.ts +++ b/server/src/domain/maintenance-windows/maintenance-window.repository.interface.ts @@ -1,4 +1,4 @@ -import type { MaintenanceWindow } from "@/types/index.js"; +import type { MaintenanceWindow } from "@/domain/maintenance-windows/maintenance-window.type.js"; export interface IMaintenanceWindowsRepository { // create create(data: Partial): Promise; diff --git a/server/src/repositories/maintenance-windows/MongoMaintenanceWindowsRepository.ts b/server/src/domain/maintenance-windows/maintenance-window.repository.mongo.ts similarity index 94% rename from server/src/repositories/maintenance-windows/MongoMaintenanceWindowsRepository.ts rename to server/src/domain/maintenance-windows/maintenance-window.repository.mongo.ts index c3f94f55d..ce32a22d1 100644 --- a/server/src/repositories/maintenance-windows/MongoMaintenanceWindowsRepository.ts +++ b/server/src/domain/maintenance-windows/maintenance-window.repository.mongo.ts @@ -1,6 +1,6 @@ -import type { MaintenanceWindow } from "@/types/index.js"; -import { type MaintenanceWindowDocument, MaintenanceWindowModel } from "@/db/models/index.js"; -import { IMaintenanceWindowsRepository } from "./IMaintenanceWindowsRepository.js"; +import type { MaintenanceWindow } from "@/domain/maintenance-windows/maintenance-window.type.js"; +import { type MaintenanceWindowDocument, MaintenanceWindowModel } from "@/domain/maintenance-windows/maintenance-window.model.js"; +import { IMaintenanceWindowsRepository } from "./maintenance-window.repository.interface.js"; import mongoose, { SortOrder } from "mongoose"; import { AppError } from "@/utils/AppError.js"; diff --git a/server/src/service/business/maintenanceWindowService.ts b/server/src/domain/maintenance-windows/maintenance-window.service.ts similarity index 95% rename from server/src/service/business/maintenanceWindowService.ts rename to server/src/domain/maintenance-windows/maintenance-window.service.ts index 2ea4c4eae..e1158dec9 100644 --- a/server/src/service/business/maintenanceWindowService.ts +++ b/server/src/domain/maintenance-windows/maintenance-window.service.ts @@ -1,5 +1,6 @@ -import { IMaintenanceWindowsRepository, IMonitorsRepository } from "@/repositories/index.js"; -import type { DurationUnit, MaintenanceWindow } from "@/types/index.js"; +import { IMaintenanceWindowsRepository } from "@/domain/maintenance-windows/maintenance-window.repository.interface.js"; +import { IMonitorsRepository } from "@/domain/monitors/monitor.repository.interface.js"; +import type { DurationUnit, MaintenanceWindow } from "@/domain/maintenance-windows/maintenance-window.type.js"; import { AppError } from "@/utils/AppError.js"; import { isWindowActive } from "@/utils/maintenanceWindow.js"; diff --git a/server/src/types/maintenanceWindow.ts b/server/src/domain/maintenance-windows/maintenance-window.type.ts similarity index 100% rename from server/src/types/maintenanceWindow.ts rename to server/src/domain/maintenance-windows/maintenance-window.type.ts diff --git a/server/src/db/models/Migration.ts b/server/src/domain/migrations/migration.model.ts similarity index 100% rename from server/src/db/models/Migration.ts rename to server/src/domain/migrations/migration.model.ts diff --git a/server/src/db/models/MonitorStats.ts b/server/src/domain/monitor-stats/monitor-stats.model.ts similarity index 92% rename from server/src/db/models/MonitorStats.ts rename to server/src/domain/monitor-stats/monitor-stats.model.ts index 4ef2dab61..889b5ec60 100755 --- a/server/src/db/models/MonitorStats.ts +++ b/server/src/domain/monitor-stats/monitor-stats.model.ts @@ -1,5 +1,5 @@ import { Schema, model, type Types } from "mongoose"; -import type { MonitorStats as MonitorStatsEntity } from "@/types/monitorStats.js"; +import type { MonitorStats as MonitorStatsEntity } from "@/domain/monitor-stats/monitor-stats.type.js"; type MonitorStatsDocumentBase = Omit & { monitorId: Types.ObjectId; diff --git a/server/src/repositories/monitor-stats/IMonitorStatsRepository.ts b/server/src/domain/monitor-stats/monitor-stats.repository.interface.ts similarity index 85% rename from server/src/repositories/monitor-stats/IMonitorStatsRepository.ts rename to server/src/domain/monitor-stats/monitor-stats.repository.interface.ts index 101283e32..286ef3608 100644 --- a/server/src/repositories/monitor-stats/IMonitorStatsRepository.ts +++ b/server/src/domain/monitor-stats/monitor-stats.repository.interface.ts @@ -1,4 +1,4 @@ -import type { MonitorStats, CheckResultInput } from "@/types/index.js"; +import type { CheckResultInput, MonitorStats } from "@/domain/monitor-stats/monitor-stats.type.js"; export interface IMonitorStatsRepository { // create diff --git a/server/src/repositories/monitor-stats/MongoMonitorStatsRepository.ts b/server/src/domain/monitor-stats/monitor-stats.repository.mongo.ts similarity index 94% rename from server/src/repositories/monitor-stats/MongoMonitorStatsRepository.ts rename to server/src/domain/monitor-stats/monitor-stats.repository.mongo.ts index ea255f7ad..7027197da 100644 --- a/server/src/repositories/monitor-stats/MongoMonitorStatsRepository.ts +++ b/server/src/domain/monitor-stats/monitor-stats.repository.mongo.ts @@ -1,6 +1,6 @@ -import { type MonitorStatsDocument, MonitorStatsModel } from "@/db/models/index.js"; -import type { MonitorStats, CheckResultInput } from "@/types/index.js"; -import { IMonitorStatsRepository } from "@/repositories/index.js"; +import { type MonitorStatsDocument, MonitorStatsModel } from "@/domain/monitor-stats/monitor-stats.model.js"; +import type { CheckResultInput, MonitorStats } from "@/domain/monitor-stats/monitor-stats.type.js"; +import { IMonitorStatsRepository } from "@/domain/monitor-stats/monitor-stats.repository.interface.js"; import mongoose from "mongoose"; import { AppError } from "@/utils/AppError.js"; class MongoMonitorStatsRepository implements IMonitorStatsRepository { diff --git a/server/src/types/monitorStats.ts b/server/src/domain/monitor-stats/monitor-stats.type.ts similarity index 100% rename from server/src/types/monitorStats.ts rename to server/src/domain/monitor-stats/monitor-stats.type.ts diff --git a/server/src/db/models/Monitor.ts b/server/src/domain/monitors/monitor.model.ts similarity index 98% rename from server/src/db/models/Monitor.ts rename to server/src/domain/monitors/monitor.model.ts index 5b982c004..e45e975e8 100644 --- a/server/src/db/models/Monitor.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 "@/types/monitor.js"; -import { DnsRecordTypes, MonitorTypes, MonitorStatuses, PageSpeedStrategies } from "@/types/monitor.js"; +import type { Monitor, MonitorMatchMethod, CheckSnapshot } from "@/domain/monitors/monitor.types.js"; +import { DnsRecordTypes, MonitorTypes, MonitorStatuses, PageSpeedStrategies } from "@/domain/monitors/monitor.types.js"; import type { CheckAudits, CheckCaptureInfo, @@ -12,7 +12,7 @@ import type { CheckNetworkInterfaceInfo, GotTimings, ILighthouseAudit, -} from "@/types/check.js"; +} from "@/domain/checks/check.type.js"; type CheckSnapshotDocument = Omit & { createdAt: Date }; diff --git a/server/src/repositories/monitors/IMonitorsRepository.ts b/server/src/domain/monitors/monitor.repository.interface.ts similarity index 94% rename from server/src/repositories/monitors/IMonitorsRepository.ts rename to server/src/domain/monitors/monitor.repository.interface.ts index dcd01f3c9..e5a0fa585 100644 --- a/server/src/repositories/monitors/IMonitorsRepository.ts +++ b/server/src/domain/monitors/monitor.repository.interface.ts @@ -1,4 +1,4 @@ -import { type MonitorType, type Monitor, type MonitorStatus, type MonitorsSummary, CheckSnapshot } from "@/types/index.js"; +import type { MonitorType, Monitor, MonitorStatus, MonitorsSummary, CheckSnapshot } from "@/domain/monitors/monitor.types.js"; export interface TeamQueryConfig { limit?: number; diff --git a/server/src/repositories/monitors/MongoMonitorsRepository.ts b/server/src/domain/monitors/monitor.repository.mongo.ts similarity index 98% rename from server/src/repositories/monitors/MongoMonitorsRepository.ts rename to server/src/domain/monitors/monitor.repository.mongo.ts index a7e327842..165db24e3 100644 --- a/server/src/repositories/monitors/MongoMonitorsRepository.ts +++ b/server/src/domain/monitors/monitor.repository.mongo.ts @@ -1,11 +1,11 @@ -import { MonitorModel } from "@/db/models/index.js"; -import type { MonitorDocument, CheckSnapshotDocument } from "@/db/models/index.js"; -import type { Monitor, MonitorStatus, MonitorsSummary, CheckSnapshot } from "@/types/index.js"; +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 mongoose, { type FilterQuery, type PipelineStage } from "mongoose"; -import type { IMonitorsRepository, TeamQueryConfig, SummaryConfig } from "./IMonitorsRepository.js"; import { MongoBulkWriteError } from "mongodb"; import { AppError } from "@/utils/AppError.js"; - +import { IMonitorsRepository, TeamQueryConfig, SummaryConfig } from "@/domain/monitors/monitor.repository.interface.js"; class MongoMonitorsRepository implements IMonitorsRepository { create = async (monitor: Monitor, teamId: string, userId: string) => { const monitorModel = new MonitorModel({ ...monitor, teamId, userId }); diff --git a/server/src/service/business/monitorService.ts b/server/src/domain/monitors/monitor.service.ts similarity index 94% rename from server/src/service/business/monitorService.ts rename to server/src/domain/monitors/monitor.service.ts index d172107c9..eaa40dcfe 100644 --- a/server/src/service/business/monitorService.ts +++ b/server/src/domain/monitors/monitor.service.ts @@ -1,5 +1,5 @@ import { NormalizeData, NormalizeDataUptimeDetails } from "@/utils/dataUtils.js"; -import { type Monitor } from "@/types/index.js"; +import { type Monitor } from "@/domain/monitors/monitor.types.js"; import type { MonitorType, MonitorsWithChecksByTeamIdResult, @@ -8,22 +8,20 @@ import type { PageSpeedDetailsResult, GamesMap, GroupedGeoCheckResult, -} from "@/types/monitor.js"; -import { supportsGeoCheck, supportsUptimeDetails } from "@/types/monitor.js"; -import type { UptimeChecksResult, HardwareChecksResult, PageSpeedChecksResult } from "@/types/check.js"; -import type { GeoContinent } from "@/types/geoCheck.js"; -import type { - IChecksRepository, - IGeoChecksRepository, - IIncidentsRepository, - IMonitorsRepository, - IMonitorStatsRepository, - IStatusPagesRepository, -} from "@/repositories/index.js"; +} from "@/domain/monitors/monitor.types.js"; +import { supportsGeoCheck, supportsUptimeDetails } from "@/domain/monitors/monitor.types.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"; +import type { IGeoChecksRepository } from "@/domain/geo-checks/geo-check.repository.interface.js"; +import type { IIncidentsRepository } from "@/domain/incidents/incident.repository.interface.js"; +import type { IMonitorStatsRepository } from "@/domain/monitor-stats/monitor-stats.repository.interface.js"; +import type { IMonitorsRepository } from "@/domain/monitors/monitor.repository.interface.js"; +import type { IStatusPagesRepository } from "@/domain/status-pages/status-page-repository.interface.js"; import demoMonitorsData from "@/utils/demoMonitors.json" with { type: "json" }; import { AppError } from "@/utils/AppError.js"; -import type { ImportedMonitor } from "@/validation/monitorValidation.js"; -import { IJobQueue } from "@/service/infrastructure/JobQueues/IJobQueue.js"; +import type { ImportedMonitor } from "@/api/validation/monitorValidation.js"; +import { IJobQueue } from "@/service/job-queues/job-queue.interface.js"; import { ILogger } from "@/utils/logger.js"; const SERVICE_NAME = "MonitorService"; diff --git a/server/src/types/monitor.ts b/server/src/domain/monitors/monitor.types.ts similarity index 84% rename from server/src/types/monitor.ts rename to server/src/domain/monitors/monitor.types.ts index 3c543616c..273d8de66 100644 --- a/server/src/types/monitor.ts +++ b/server/src/domain/monitors/monitor.types.ts @@ -1,7 +1,7 @@ -import type { CheckSnapshot } from "@/types/check.js"; -export type { CheckSnapshot } from "@/types/check.js"; -import type { GeoContinent, GroupedGeoCheck } from "@/types/geoCheck.js"; -export type { GeoContinent } from "@/types/geoCheck.js"; +import type { CheckSnapshot } from "@/domain/checks/check.type.js"; +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"; export const HttpStatusCodes = Object.keys(http.STATUS_CODES).map(Number); @@ -113,13 +113,13 @@ export interface GroupedGeoCheckResult { export interface UptimeDetailsResult { monitorData: { monitor: Monitor; - groupedChecks: import("./check.js").GroupedCheck[]; - groupedUpChecks: import("./check.js").GroupedCheck[]; - groupedDownChecks: import("./check.js").GroupedCheck[]; + groupedChecks: import("../checks/check.type.js").GroupedCheck[]; + groupedUpChecks: import("../checks/check.type.js").GroupedCheck[]; + groupedDownChecks: import("../checks/check.type.js").GroupedCheck[]; groupedAvgResponseTime: number; groupedUptimePercentage: number; }; - monitorStats: import("./monitorStats.js").MonitorStats | null; + monitorStats: import("../monitor-stats/monitor-stats.type.js").MonitorStats | null; } export interface HardwareDiskStats { @@ -167,15 +167,15 @@ export interface HardwareStats { export interface HardwareDetailsResult { monitor: Monitor; stats: HardwareStats; - monitorStats: import("./monitorStats.js").MonitorStats | null; + monitorStats: import("../monitor-stats/monitor-stats.type.js").MonitorStats | null; } export interface PageSpeedDetailsResult { monitorData: { monitor: Monitor; - groupedChecks: import("./check.js").PageSpeedGroupedCheck[]; + groupedChecks: import("../checks/check.type.js").PageSpeedGroupedCheck[]; }; - monitorStats: import("./monitorStats.js").MonitorStats | null; + monitorStats: import("../monitor-stats/monitor-stats.type.js").MonitorStats | null; } export interface Game { diff --git a/server/src/service/infrastructure/notificationMessageBuilder.ts b/server/src/domain/notifications/notification.message-builder.ts similarity index 96% rename from server/src/service/infrastructure/notificationMessageBuilder.ts rename to server/src/domain/notifications/notification.message-builder.ts index 2035439c2..9d3714ae7 100644 --- a/server/src/service/infrastructure/notificationMessageBuilder.ts +++ b/server/src/domain/notifications/notification.message-builder.ts @@ -1,12 +1,13 @@ -import type { HardwareStatusPayload, Monitor, MonitorStatusResponse } from "@/types/index.js"; -import type { MonitorActionDecision } from "@/service/infrastructure/JobQueues/QueueHelper.js"; +import type { Monitor } from "@/domain/monitors/monitor.types.js"; +import type { HardwareStatusPayload, MonitorStatusResponse } from "@/types/network.js"; +import type { MonitorActionDecision } from "@/service/job-queues/job-queue.helper.js"; import type { NotificationMessage, NotificationType, NotificationSeverity, ThresholdBreach, NotificationContent, -} from "@/types/notificationMessage.js"; +} from "@/domain/notifications/notification.type.js"; export interface INotificationMessageBuilder { buildMessage( diff --git a/server/src/db/models/Notification.ts b/server/src/domain/notifications/notification.model.ts similarity index 92% rename from server/src/db/models/Notification.ts rename to server/src/domain/notifications/notification.model.ts index 93202bb8f..797b3e768 100755 --- a/server/src/db/models/Notification.ts +++ b/server/src/domain/notifications/notification.model.ts @@ -1,5 +1,5 @@ import { Schema, model, type Types } from "mongoose"; -import type { Notification, NotificationChannel } from "@/types/notification.js"; +import type { Notification, NotificationChannel } from "@/domain/notifications/notification.type.js"; interface NotificationDocument extends Omit { _id: Types.ObjectId; diff --git a/server/src/repositories/notifications/INotificationsRepository.ts b/server/src/domain/notifications/notification.repository.interface.ts similarity index 86% rename from server/src/repositories/notifications/INotificationsRepository.ts rename to server/src/domain/notifications/notification.repository.interface.ts index 0236c3a89..9de6e1e06 100644 --- a/server/src/repositories/notifications/INotificationsRepository.ts +++ b/server/src/domain/notifications/notification.repository.interface.ts @@ -1,4 +1,4 @@ -import type { Notification } from "@/types/index.js"; +import type { Notification } from "@/domain/notifications/notification.type.js"; export interface INotificationsRepository { // create create(notificationData: Partial): Promise; diff --git a/server/src/repositories/notifications/MongoNotificationsRepository.ts b/server/src/domain/notifications/notification.repository.mongo.ts similarity index 93% rename from server/src/repositories/notifications/MongoNotificationsRepository.ts rename to server/src/domain/notifications/notification.repository.mongo.ts index e556fa206..cc2729cf7 100644 --- a/server/src/repositories/notifications/MongoNotificationsRepository.ts +++ b/server/src/domain/notifications/notification.repository.mongo.ts @@ -1,7 +1,7 @@ import mongoose from "mongoose"; -import { NotificationModel, type NotificationDocument } from "@/db/models/index.js"; -import { INotificationsRepository } from "@/repositories/index.js"; -import type { Notification } from "@/types/index.js"; +import { NotificationModel, type NotificationDocument } from "@/domain/notifications/notification.model.js"; +import { INotificationsRepository } from "@/domain/notifications/notification.repository.interface.js"; +import type { Notification } from "@/domain/notifications/notification.type.js"; import { AppError } from "@/utils/AppError.js"; class MongoNotificationsRepository implements INotificationsRepository { diff --git a/server/src/service/infrastructure/notificationsService.ts b/server/src/domain/notifications/notification.service.ts similarity index 91% rename from server/src/service/infrastructure/notificationsService.ts rename to server/src/domain/notifications/notification.service.ts index 09129a8af..ea6a9265c 100644 --- a/server/src/service/infrastructure/notificationsService.ts +++ b/server/src/domain/notifications/notification.service.ts @@ -1,11 +1,14 @@ -import type { Monitor, MonitorStatusResponse, Notification } from "@/types/index.js"; -import type { NotificationMessage } from "@/types/notificationMessage.js"; -import { IMonitorsRepository, INotificationsRepository } from "@/repositories/index.js"; -import { INotificationProvider } from "./notificationProviders/INotificationProvider.js"; -import type { MonitorActionDecision } from "@/service/infrastructure/JobQueues/QueueHelper.js"; -import type { ISettingsService } from "@/service/system/settingsService.js"; +import type { Monitor } from "@/domain/monitors/monitor.types.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"; +import { IMonitorsRepository } from "@/domain/monitors/monitor.repository.interface.js"; +import { INotificationsRepository } from "@/domain/notifications/notification.repository.interface.js"; +import { INotificationProvider } from "@/domain/notifications/providers/INotificationProvider.js"; +import type { MonitorActionDecision } from "@/service/job-queues/job-queue.helper.js"; +import type { ISettingsService } from "@/domain/app-settings/app-settings.service.js"; import { ILogger } from "@/utils/logger.js"; -import type { INotificationMessageBuilder } from "@/service/infrastructure/notificationMessageBuilder.js"; +import type { INotificationMessageBuilder } from "@/domain/notifications/notification.message-builder.js"; export interface INotificationsService { createNotification: (notificationData: Partial, userId: string, teamId: string) => Promise; diff --git a/server/src/types/notificationMessage.ts b/server/src/domain/notifications/notification.type.ts similarity index 51% rename from server/src/types/notificationMessage.ts rename to server/src/domain/notifications/notification.type.ts index f06ff1bd9..8ae617a88 100644 --- a/server/src/types/notificationMessage.ts +++ b/server/src/domain/notifications/notification.type.ts @@ -1,3 +1,62 @@ +export const NotificationChannels = [ + "email", + "slack", + "discord", + "webhook", + "pager_duty", + "matrix", + "teams", + "telegram", + "pushover", + "twilio", + "ntfy", +] as const; +export type NotificationChannel = (typeof NotificationChannels)[number]; + +export interface Notification { + id: string; + userId: string; + teamId: string; + type: NotificationChannel; + notificationName: string; + address?: string; + phone?: string; + homeserverUrl?: string; + roomId?: string; + accessToken?: string; + accountSid?: string; + twilioPhoneNumber?: string; + topic?: string; + createdAt: string; + updatedAt: string; +} + +export interface AlertPagerDutyPayload { + routing_key?: string; + dedup_key?: string; + event_action?: "trigger" | "resolve"; + payload: Record; +} + +export interface AlertMatrixPayload { + plainText: string; + htmlText: string; +} + +export interface DiscordEmbedField { + name: string; + value: string; + inline?: boolean; +} + +export interface AlertDiscordPayload { + title: string; + description: string; + color: number; + fields: DiscordEmbedField[]; + timestamp: string; +} + /** * Unified notification message types for cross-provider consistency * Part of notification system unification effort diff --git a/server/src/service/infrastructure/notificationProviders/INotificationProvider.ts b/server/src/domain/notifications/providers/INotificationProvider.ts similarity index 85% rename from server/src/service/infrastructure/notificationProviders/INotificationProvider.ts rename to server/src/domain/notifications/providers/INotificationProvider.ts index b5c886408..6e1840669 100644 --- a/server/src/service/infrastructure/notificationProviders/INotificationProvider.ts +++ b/server/src/domain/notifications/providers/INotificationProvider.ts @@ -1,5 +1,5 @@ -import type { Notification } from "@/types/index.js"; -import type { NotificationMessage } from "@/types/notificationMessage.js"; +import type { Notification } from "@/domain/notifications/notification.type.js"; +import type { NotificationMessage } from "@/domain/notifications/notification.type.js"; import { ILogger } from "@/utils/logger.js"; import type { OptionsOfJSONResponseBody } from "got"; diff --git a/server/src/service/infrastructure/notificationProviders/discord.ts b/server/src/domain/notifications/providers/discord.ts similarity index 92% rename from server/src/service/infrastructure/notificationProviders/discord.ts rename to server/src/domain/notifications/providers/discord.ts index 942e0b578..cada9fcf2 100644 --- a/server/src/service/infrastructure/notificationProviders/discord.ts +++ b/server/src/domain/notifications/providers/discord.ts @@ -1,8 +1,8 @@ const SERVICE_NAME = "DiscordProvider"; -import type { AlertDiscordPayload, DiscordEmbedField, Notification } from "@/types/index.js"; -import { NotificationProvider } from "@/service/infrastructure/notificationProviders/INotificationProvider.js"; -import { getTestMessage } from "@/service/infrastructure/notificationProviders/utils.js"; -import type { NotificationMessage, NotificationSeverity } from "@/types/notificationMessage.js"; +import type { AlertDiscordPayload, DiscordEmbedField, Notification } from "@/domain/notifications/notification.type.js"; +import { NotificationProvider } from "@/domain/notifications/providers/INotificationProvider.js"; +import { getTestMessage } from "@/domain/notifications/providers/utils.js"; +import type { NotificationMessage, NotificationSeverity } from "@/domain/notifications/notification.type.js"; import got from "got"; export class DiscordProvider extends NotificationProvider { diff --git a/server/src/service/infrastructure/notificationProviders/email.ts b/server/src/domain/notifications/providers/email.ts similarity index 89% rename from server/src/service/infrastructure/notificationProviders/email.ts rename to server/src/domain/notifications/providers/email.ts index 0890eac7f..fa84be66d 100644 --- a/server/src/service/infrastructure/notificationProviders/email.ts +++ b/server/src/domain/notifications/providers/email.ts @@ -1,10 +1,10 @@ const SERVICE_NAME = "EmailProvider"; -import type { Notification } from "@/types/index.js"; -import { NotificationProvider } from "@/service/infrastructure/notificationProviders/INotificationProvider.js"; -import { buildTestEmail } from "@/service/infrastructure/notificationProviders/utils.js"; -import type { NotificationMessage } from "@/types/notificationMessage.js"; +import type { Notification } from "@/domain/notifications/notification.type.js"; +import { NotificationProvider } from "@/domain/notifications/providers/INotificationProvider.js"; +import { buildTestEmail } from "@/domain/notifications/providers/utils.js"; +import type { NotificationMessage } from "@/domain/notifications/notification.type.js"; import type { ILogger } from "@/utils/logger.js"; -import { IEmailService } from "@/service/infrastructure/emailService.js"; +import { IEmailService } from "@/service/emailService.js"; export class EmailProvider extends NotificationProvider { private emailService: IEmailService; diff --git a/server/src/service/infrastructure/notificationProviders/matrix.ts b/server/src/domain/notifications/providers/matrix.ts similarity index 93% rename from server/src/service/infrastructure/notificationProviders/matrix.ts rename to server/src/domain/notifications/providers/matrix.ts index f8a093ab7..a1f35b0ca 100644 --- a/server/src/service/infrastructure/notificationProviders/matrix.ts +++ b/server/src/domain/notifications/providers/matrix.ts @@ -1,9 +1,9 @@ const SERVICE_NAME = "MatrixProvider"; import got from "got"; -import { NotificationProvider } from "@/service/infrastructure/notificationProviders/INotificationProvider.js"; -import type { AlertMatrixPayload, Notification } from "@/types/index.js"; -import type { NotificationMessage } from "@/types/notificationMessage.js"; -import { getTestMessage } from "@/service/infrastructure/notificationProviders/utils.js"; +import { NotificationProvider } from "@/domain/notifications/providers/INotificationProvider.js"; +import type { AlertMatrixPayload, Notification } from "@/domain/notifications/notification.type.js"; +import type { NotificationMessage } from "@/domain/notifications/notification.type.js"; +import { getTestMessage } from "@/domain/notifications/providers/utils.js"; import { randomUUID } from "crypto"; export class MatrixProvider extends NotificationProvider { diff --git a/server/src/service/infrastructure/notificationProviders/ntfy.ts b/server/src/domain/notifications/providers/ntfy.ts similarity index 90% rename from server/src/service/infrastructure/notificationProviders/ntfy.ts rename to server/src/domain/notifications/providers/ntfy.ts index 8811cce47..7ca351d87 100644 --- a/server/src/service/infrastructure/notificationProviders/ntfy.ts +++ b/server/src/domain/notifications/providers/ntfy.ts @@ -1,8 +1,8 @@ const SERVICE_NAME = "NtfyProvider"; -import type { Notification } from "@/types/index.js"; -import { NotificationProvider } from "@/service/infrastructure/notificationProviders/INotificationProvider.js"; -import type { NotificationMessage } from "@/types/notificationMessage.js"; -import { getTestMessage } from "@/service/infrastructure/notificationProviders/utils.js"; +import type { Notification } from "@/domain/notifications/notification.type.js"; +import { NotificationProvider } from "@/domain/notifications/providers/INotificationProvider.js"; +import type { NotificationMessage } from "@/domain/notifications/notification.type.js"; +import { getTestMessage } from "@/domain/notifications/providers/utils.js"; import got from "got"; export class NtfyProvider extends NotificationProvider { diff --git a/server/src/service/infrastructure/notificationProviders/pagerduty.ts b/server/src/domain/notifications/providers/pagerduty.ts similarity index 89% rename from server/src/service/infrastructure/notificationProviders/pagerduty.ts rename to server/src/domain/notifications/providers/pagerduty.ts index 0d2fa75be..6cb264c1d 100644 --- a/server/src/service/infrastructure/notificationProviders/pagerduty.ts +++ b/server/src/domain/notifications/providers/pagerduty.ts @@ -1,10 +1,10 @@ const SERVICE_NAME = "PagerDutyProvider"; import got from "got"; -import type { Notification } from "@/types/index.js"; -import { NotificationProvider } from "@/service/infrastructure/notificationProviders/INotificationProvider.js"; -import type { NotificationMessage } from "@/types/notificationMessage.js"; -import { getTestMessage } from "@/service/infrastructure/notificationProviders/utils.js"; -import { AlertPagerDutyPayload } from "@/types/index.js"; +import type { Notification } from "@/domain/notifications/notification.type.js"; +import { NotificationProvider } from "@/domain/notifications/providers/INotificationProvider.js"; +import type { NotificationMessage } from "@/domain/notifications/notification.type.js"; +import { getTestMessage } from "@/domain/notifications/providers/utils.js"; +import { AlertPagerDutyPayload } from "@/domain/notifications/notification.type.js"; export class PagerDutyProvider extends NotificationProvider { async sendTestAlert(notification: Partial): Promise { diff --git a/server/src/service/infrastructure/notificationProviders/pushover.ts b/server/src/domain/notifications/providers/pushover.ts similarity index 89% rename from server/src/service/infrastructure/notificationProviders/pushover.ts rename to server/src/domain/notifications/providers/pushover.ts index 5d001892d..b1831e405 100644 --- a/server/src/service/infrastructure/notificationProviders/pushover.ts +++ b/server/src/domain/notifications/providers/pushover.ts @@ -1,8 +1,8 @@ const SERVICE_NAME = "PushoverProvider"; -import type { Notification } from "@/types/index.js"; -import { NotificationProvider } from "@/service/infrastructure/notificationProviders/INotificationProvider.js"; -import type { NotificationMessage } from "@/types/notificationMessage.js"; -import { getTestMessage } from "@/service/infrastructure/notificationProviders/utils.js"; +import type { Notification } from "@/domain/notifications/notification.type.js"; +import { NotificationProvider } from "@/domain/notifications/providers/INotificationProvider.js"; +import type { NotificationMessage } from "@/domain/notifications/notification.type.js"; +import { getTestMessage } from "@/domain/notifications/providers/utils.js"; import got from "got"; export class PushoverProvider extends NotificationProvider { diff --git a/server/src/service/infrastructure/notificationProviders/slack.ts b/server/src/domain/notifications/providers/slack.ts similarity index 92% rename from server/src/service/infrastructure/notificationProviders/slack.ts rename to server/src/domain/notifications/providers/slack.ts index 1ab046f7f..23f9b2f61 100644 --- a/server/src/service/infrastructure/notificationProviders/slack.ts +++ b/server/src/domain/notifications/providers/slack.ts @@ -1,8 +1,8 @@ const SERVICE_NAME = "SlackProvider"; -import type { Notification } from "@/types/index.js"; -import { NotificationProvider } from "@/service/infrastructure/notificationProviders/INotificationProvider.js"; -import type { NotificationMessage } from "@/types/notificationMessage.js"; -import { getTestMessage } from "@/service/infrastructure/notificationProviders/utils.js"; +import type { Notification } from "@/domain/notifications/notification.type.js"; +import { NotificationProvider } from "@/domain/notifications/providers/INotificationProvider.js"; +import type { NotificationMessage } from "@/domain/notifications/notification.type.js"; +import { getTestMessage } from "@/domain/notifications/providers/utils.js"; import got, { HTTPError } from "got"; export class SlackProvider extends NotificationProvider { diff --git a/server/src/service/infrastructure/notificationProviders/teams.ts b/server/src/domain/notifications/providers/teams.ts similarity index 94% rename from server/src/service/infrastructure/notificationProviders/teams.ts rename to server/src/domain/notifications/providers/teams.ts index f98724295..36d37a210 100644 --- a/server/src/service/infrastructure/notificationProviders/teams.ts +++ b/server/src/domain/notifications/providers/teams.ts @@ -1,8 +1,8 @@ const SERVICE_NAME = "TeamsProvider"; -import type { Notification } from "@/types/index.js"; -import { NotificationProvider } from "@/service/infrastructure/notificationProviders/INotificationProvider.js"; -import type { NotificationMessage } from "@/types/notificationMessage.js"; -import { getTestMessage } from "@/service/infrastructure/notificationProviders/utils.js"; +import type { Notification } from "@/domain/notifications/notification.type.js"; +import { NotificationProvider } from "@/domain/notifications/providers/INotificationProvider.js"; +import type { NotificationMessage } from "@/domain/notifications/notification.type.js"; +import { getTestMessage } from "@/domain/notifications/providers/utils.js"; import got, { HTTPError } from "got"; // Types for Adaptive Card elements diff --git a/server/src/service/infrastructure/notificationProviders/telegram.ts b/server/src/domain/notifications/providers/telegram.ts similarity index 89% rename from server/src/service/infrastructure/notificationProviders/telegram.ts rename to server/src/domain/notifications/providers/telegram.ts index 9d6968fdd..72e31b5bf 100644 --- a/server/src/service/infrastructure/notificationProviders/telegram.ts +++ b/server/src/domain/notifications/providers/telegram.ts @@ -1,8 +1,8 @@ const SERVICE_NAME = "TelegramProvider"; -import type { Notification } from "@/types/index.js"; -import { NotificationProvider } from "@/service/infrastructure/notificationProviders/INotificationProvider.js"; -import type { NotificationMessage } from "@/types/notificationMessage.js"; -import { getTestMessage } from "@/service/infrastructure/notificationProviders/utils.js"; +import type { Notification } from "@/domain/notifications/notification.type.js"; +import { NotificationProvider } from "@/domain/notifications/providers/INotificationProvider.js"; +import type { NotificationMessage } from "@/domain/notifications/notification.type.js"; +import { getTestMessage } from "@/domain/notifications/providers/utils.js"; import got from "got"; export class TelegramProvider extends NotificationProvider { diff --git a/server/src/service/infrastructure/notificationProviders/twilio.ts b/server/src/domain/notifications/providers/twilio.ts similarity index 88% rename from server/src/service/infrastructure/notificationProviders/twilio.ts rename to server/src/domain/notifications/providers/twilio.ts index a871fe5cb..2f7937b7f 100644 --- a/server/src/service/infrastructure/notificationProviders/twilio.ts +++ b/server/src/domain/notifications/providers/twilio.ts @@ -1,8 +1,8 @@ const SERVICE_NAME = "TwilioProvider"; -import type { Notification } from "@/types/index.js"; -import { NotificationProvider } from "@/service/infrastructure/notificationProviders/INotificationProvider.js"; -import type { NotificationMessage } from "@/types/notificationMessage.js"; -import { getTestMessage } from "@/service/infrastructure/notificationProviders/utils.js"; +import type { Notification } from "@/domain/notifications/notification.type.js"; +import { NotificationProvider } from "@/domain/notifications/providers/INotificationProvider.js"; +import type { NotificationMessage } from "@/domain/notifications/notification.type.js"; +import { getTestMessage } from "@/domain/notifications/providers/utils.js"; import got from "got"; export class TwilioProvider extends NotificationProvider { diff --git a/server/src/service/infrastructure/notificationProviders/utils.ts b/server/src/domain/notifications/providers/utils.ts similarity index 80% rename from server/src/service/infrastructure/notificationProviders/utils.ts rename to server/src/domain/notifications/providers/utils.ts index 454df1963..3eaf428fe 100644 --- a/server/src/service/infrastructure/notificationProviders/utils.ts +++ b/server/src/domain/notifications/providers/utils.ts @@ -1,4 +1,4 @@ -import { IEmailService } from "@/service/infrastructure/emailService.js"; +import { IEmailService } from "@/service/emailService.js"; export const buildTestEmail = async (emailService: IEmailService) => { const context = { testName: "Monitoring System" }; const html = await emailService.buildEmail("testEmailTemplate", context); diff --git a/server/src/service/infrastructure/notificationProviders/webhook.ts b/server/src/domain/notifications/providers/webhook.ts similarity index 90% rename from server/src/service/infrastructure/notificationProviders/webhook.ts rename to server/src/domain/notifications/providers/webhook.ts index 292650f91..fc5a80fde 100644 --- a/server/src/service/infrastructure/notificationProviders/webhook.ts +++ b/server/src/domain/notifications/providers/webhook.ts @@ -1,8 +1,8 @@ const SERVICE_NAME = "WebhookProvider"; -import type { Notification } from "@/types/index.js"; -import { NotificationProvider } from "@/service/infrastructure/notificationProviders/INotificationProvider.js"; -import type { NotificationMessage } from "@/types/notificationMessage.js"; -import { getTestMessage } from "@/service/infrastructure/notificationProviders/utils.js"; +import type { Notification } from "@/domain/notifications/notification.type.js"; +import { NotificationProvider } from "@/domain/notifications/providers/INotificationProvider.js"; +import type { NotificationMessage } from "@/domain/notifications/notification.type.js"; +import { getTestMessage } from "@/domain/notifications/providers/utils.js"; import got from "got"; export class WebhookProvider extends NotificationProvider { diff --git a/server/src/db/models/QueueWorker.ts b/server/src/domain/queue-workers/queue-worker.model.ts similarity index 54% rename from server/src/db/models/QueueWorker.ts rename to server/src/domain/queue-workers/queue-worker.model.ts index 76485f56c..06299d339 100644 --- a/server/src/db/models/QueueWorker.ts +++ b/server/src/domain/queue-workers/queue-worker.model.ts @@ -1,16 +1,6 @@ import { Schema, model } from "mongoose"; -import { QueueModes, type QueueMode } from "@/types/settings.js"; - -// Heartbeat presence record for a scheduler instance. _id is the scheduler's -// workerId (hostname:pid:uuid). The TTL index on lastSeenAt garbage-collects -// records for instances that have stopped heartbeating. -interface QueueWorkerDocument { - _id: string; - mode: QueueMode; - lastSeenAt: Date; - createdAt: Date; - updatedAt: Date; -} +import { QueueModes } from "@/domain/app-settings/app-settings.type.js"; +import { QueueWorkerDocument } from "@/domain/queue-workers/queue-worker.type.js"; const QueueWorkerSchema = new Schema( { diff --git a/server/src/repositories/queue-workers/IQueueWorkersRepository.ts b/server/src/domain/queue-workers/queue-worker.repository.interface.ts similarity index 56% rename from server/src/repositories/queue-workers/IQueueWorkersRepository.ts rename to server/src/domain/queue-workers/queue-worker.repository.interface.ts index b1f7e76b1..e4522c916 100644 --- a/server/src/repositories/queue-workers/IQueueWorkersRepository.ts +++ b/server/src/domain/queue-workers/queue-worker.repository.interface.ts @@ -1,4 +1,5 @@ -import type { QueueMode, QueueWorker } from "@/types/settings.js"; +import type { QueueMode } from "@/domain/app-settings/app-settings.type.js"; +import type { QueueWorker } from "@/domain/queue-workers/queue-worker.type.js"; export interface IQueueWorkersRepository { upsert(workerId: string, mode: QueueMode): Promise; diff --git a/server/src/repositories/queue-workers/MongoQueueWorkersRepository.ts b/server/src/domain/queue-workers/queue-worker.repository.mongo.ts similarity index 72% rename from server/src/repositories/queue-workers/MongoQueueWorkersRepository.ts rename to server/src/domain/queue-workers/queue-worker.repository.mongo.ts index b8155ea1d..35565bd03 100644 --- a/server/src/repositories/queue-workers/MongoQueueWorkersRepository.ts +++ b/server/src/domain/queue-workers/queue-worker.repository.mongo.ts @@ -1,7 +1,7 @@ -import type { QueueMode, QueueWorker } from "@/types/settings.js"; -import type { IQueueWorkersRepository } from "./IQueueWorkersRepository.js"; -import type { QueueWorkerDocument } from "@/db/models/QueueWorker.js"; -import { QueueWorkerModel } from "@/db/models/QueueWorker.js"; +import type { QueueMode } from "@/domain/app-settings/app-settings.type.js"; +import type { IQueueWorkersRepository } from "./queue-worker.repository.interface.js"; +import type { QueueWorker } from "@/domain/queue-workers/queue-worker.type.js"; +import { QueueWorkerModel, type QueueWorkerDocument } from "@/domain/queue-workers/queue-worker.model.js"; const SERVICE_NAME = "MongoQueueWorkersRepository"; class MongoQueueWorkersRepository implements IQueueWorkersRepository { diff --git a/server/src/domain/queue-workers/queue-worker.type.ts b/server/src/domain/queue-workers/queue-worker.type.ts new file mode 100644 index 000000000..a83c831ad --- /dev/null +++ b/server/src/domain/queue-workers/queue-worker.type.ts @@ -0,0 +1,18 @@ +import { type QueueMode } from "@/domain/app-settings/app-settings.type.js"; + +// Heartbeat presence record for a scheduler instance. _id is the scheduler's +// workerId (hostname:pid:uuid). The TTL index on lastSeenAt garbage-collects +// records for instances that have stopped heartbeating. +export interface QueueWorkerDocument { + _id: string; + mode: QueueMode; + lastSeenAt: Date; + createdAt: Date; + updatedAt: Date; +} + +export type QueueWorker = { + workerId: string; // hostname:pid:uuid + mode: QueueMode; + lastSeenAt: number; // epoch ms of the last heartbeat +}; diff --git a/server/src/db/models/RecoveryToken.ts b/server/src/domain/recovery-tokens/recovery-token.model.ts similarity index 87% rename from server/src/db/models/RecoveryToken.ts rename to server/src/domain/recovery-tokens/recovery-token.model.ts index 07b697d9e..54d77a4f2 100644 --- a/server/src/db/models/RecoveryToken.ts +++ b/server/src/domain/recovery-tokens/recovery-token.model.ts @@ -1,5 +1,5 @@ import { Schema, model, type Types } from "mongoose"; -import type { RecoveryToken as RecoveryTokenEntity } from "@/types/recoveryToken.js"; +import type { RecoveryToken as RecoveryTokenEntity } from "@/domain/recovery-tokens/recovery-token.type.js"; type RecoveryTokenDocumentBase = Omit & { expiry: Date; diff --git a/server/src/repositories/recovery-tokens/IRecoveryTokensRepository.ts b/server/src/domain/recovery-tokens/recovery-token.repository.interface.ts similarity index 74% rename from server/src/repositories/recovery-tokens/IRecoveryTokensRepository.ts rename to server/src/domain/recovery-tokens/recovery-token.repository.interface.ts index 9df1fa793..d5f3a30b7 100644 --- a/server/src/repositories/recovery-tokens/IRecoveryTokensRepository.ts +++ b/server/src/domain/recovery-tokens/recovery-token.repository.interface.ts @@ -1,4 +1,4 @@ -import type { RecoveryToken } from "@/types/recoveryToken.js"; +import type { RecoveryToken } from "@/domain/recovery-tokens/recovery-token.type.js"; export interface IRecoveryTokensRepository { // create diff --git a/server/src/repositories/recovery-tokens/MongoRecoveryTokensRepository.ts b/server/src/domain/recovery-tokens/recovery-token.repository.mongo.ts similarity index 82% rename from server/src/repositories/recovery-tokens/MongoRecoveryTokensRepository.ts rename to server/src/domain/recovery-tokens/recovery-token.repository.mongo.ts index 4c9f9ebb6..1e6140a88 100644 --- a/server/src/repositories/recovery-tokens/MongoRecoveryTokensRepository.ts +++ b/server/src/domain/recovery-tokens/recovery-token.repository.mongo.ts @@ -1,7 +1,7 @@ -import type { RecoveryToken } from "@/types/index.js"; -import type { IRecoveryTokensRepository } from "./IRecoveryTokensRepository.js"; -import type { RecoveryTokenDocument } from "@/db/models/RecoveryToken.js"; -import { RecoveryTokenModel } from "@/db/models/RecoveryToken.js"; +import type { RecoveryToken } from "@/domain/recovery-tokens/recovery-token.type.js"; +import type { IRecoveryTokensRepository } from "./recovery-token.repository.interface.js"; +import type { RecoveryTokenDocument } from "@/domain/recovery-tokens/recovery-token.model.js"; +import { RecoveryTokenModel } from "@/domain/recovery-tokens/recovery-token.model.js"; import mongoose from "mongoose"; import crypto from "crypto"; import { AppError } from "@/utils/AppError.js"; diff --git a/server/src/types/recoveryToken.ts b/server/src/domain/recovery-tokens/recovery-token.type.ts similarity index 100% rename from server/src/types/recoveryToken.ts rename to server/src/domain/recovery-tokens/recovery-token.type.ts diff --git a/server/src/repositories/status-pages/IStatusPagesRepository.ts b/server/src/domain/status-pages/status-page-repository.interface.ts similarity index 88% rename from server/src/repositories/status-pages/IStatusPagesRepository.ts rename to server/src/domain/status-pages/status-page-repository.interface.ts index c901b3c6d..da80e3e3b 100644 --- a/server/src/repositories/status-pages/IStatusPagesRepository.ts +++ b/server/src/domain/status-pages/status-page-repository.interface.ts @@ -1,4 +1,4 @@ -import type { StatusPage } from "@/types/statusPage.js"; +import type { StatusPage } from "@/domain/status-pages/status-page.type.js"; export interface IStatusPagesRepository { // create diff --git a/server/src/repositories/status-pages/MongoStatusPagesRepository.ts b/server/src/domain/status-pages/status-page-repository.mongo.ts similarity index 94% rename from server/src/repositories/status-pages/MongoStatusPagesRepository.ts rename to server/src/domain/status-pages/status-page-repository.mongo.ts index 3f4630eb1..b7f5f984b 100644 --- a/server/src/repositories/status-pages/MongoStatusPagesRepository.ts +++ b/server/src/domain/status-pages/status-page-repository.mongo.ts @@ -1,6 +1,6 @@ -import { IStatusPagesRepository } from "@/repositories/index.js"; -import { type StatusPageDocument, StatusPageModel } from "@/db/models/StatusPage.js"; -import type { StatusPage, StatusPageLogo, StatusPageLogoDocument } from "@/types/statusPage.js"; +import { IStatusPagesRepository } from "@/domain/status-pages/status-page-repository.interface.js"; +import { type StatusPageDocument, StatusPageModel } from "@/domain/status-pages/status-page.model.js"; +import type { StatusPage, StatusPageLogo, StatusPageLogoDocument } from "@/domain/status-pages/status-page.type.js"; import mongoose from "mongoose"; import { AppError } from "@/utils/AppError.js"; diff --git a/server/src/db/models/StatusPage.ts b/server/src/domain/status-pages/status-page.model.ts similarity index 94% rename from server/src/db/models/StatusPage.ts rename to server/src/domain/status-pages/status-page.model.ts index 0b6451492..421d5df17 100644 --- a/server/src/db/models/StatusPage.ts +++ b/server/src/domain/status-pages/status-page.model.ts @@ -1,12 +1,12 @@ import { Schema, model, type Types } from "mongoose"; -import type { StatusPage, StatusPageLogoDocument } from "@/types/statusPage.js"; +import type { StatusPage, StatusPageLogoDocument } from "@/domain/status-pages/status-page.type.js"; import { DEFAULT_STATUS_PAGE_THEME, DEFAULT_STATUS_PAGE_THEME_MODE, StatusPageThemeModes, StatusPageThemes, StatusPageTypes, -} from "@/types/statusPage.js"; +} from "@/domain/status-pages/status-page.type.js"; type StatusPageDocumentBase = Omit< StatusPage, diff --git a/server/src/service/business/statusPageService.ts b/server/src/domain/status-pages/status-page.service.ts similarity index 91% rename from server/src/service/business/statusPageService.ts rename to server/src/domain/status-pages/status-page.service.ts index 179461f25..4cfdc2dfa 100644 --- a/server/src/service/business/statusPageService.ts +++ b/server/src/domain/status-pages/status-page.service.ts @@ -1,6 +1,6 @@ -import { type IStatusPagesRepository } from "@/repositories/index.js"; -import { ISettingsService } from "@/service/system/settingsService.js"; -import { DEFAULT_STATUS_PAGE_THEME, DEFAULT_STATUS_PAGE_THEME_MODE, StatusPage } from "@/types/index.js"; +import { type IStatusPagesRepository } from "@/domain/status-pages/status-page-repository.interface.js"; +import { ISettingsService } from "@/domain/app-settings/app-settings.service.js"; +import { DEFAULT_STATUS_PAGE_THEME, DEFAULT_STATUS_PAGE_THEME_MODE, StatusPage } from "@/domain/status-pages/status-page.type.js"; export interface IStatusPageService { createStatusPage(userId: string, teamId: string, image: Express.Multer.File | undefined, data: Partial): Promise; diff --git a/server/src/types/statusPage.ts b/server/src/domain/status-pages/status-page.type.ts similarity index 100% rename from server/src/types/statusPage.ts rename to server/src/domain/status-pages/status-page.type.ts diff --git a/server/src/db/models/Tag.ts b/server/src/domain/tags/tag.model.ts similarity index 91% rename from server/src/db/models/Tag.ts rename to server/src/domain/tags/tag.model.ts index df77aa7ab..2fbfbf2c6 100644 --- a/server/src/db/models/Tag.ts +++ b/server/src/domain/tags/tag.model.ts @@ -1,5 +1,5 @@ import { Schema, model, type Types } from "mongoose"; -import type { Tag as TagEntity } from "@/types/index.js"; +import type { Tag as TagEntity } from "@/domain/tags/tag.type.js"; type TagDocumentBase = Omit; diff --git a/server/src/repositories/tags/ITagsRepository.ts b/server/src/domain/tags/tag.repository.interface.ts similarity index 88% rename from server/src/repositories/tags/ITagsRepository.ts rename to server/src/domain/tags/tag.repository.interface.ts index 42cec2a5a..ba6fe8eb3 100644 --- a/server/src/repositories/tags/ITagsRepository.ts +++ b/server/src/domain/tags/tag.repository.interface.ts @@ -1,4 +1,4 @@ -import { Tag } from "@/types/index.js"; +import { Tag } from "@/domain/tags/tag.type.js"; export interface ITagsRepository { // create diff --git a/server/src/repositories/tags/MongoTagsRepository.ts b/server/src/domain/tags/tag.repository.mongo.ts similarity index 92% rename from server/src/repositories/tags/MongoTagsRepository.ts rename to server/src/domain/tags/tag.repository.mongo.ts index 72355c7df..5d7d8d0a2 100644 --- a/server/src/repositories/tags/MongoTagsRepository.ts +++ b/server/src/domain/tags/tag.repository.mongo.ts @@ -1,6 +1,6 @@ -import { ITagsRepository } from "@/repositories/tags/ITagsRepository.js"; -import { Tag } from "@/types/tag.js"; -import { TagDocument, TagModel } from "@/db/models/index.js"; +import { ITagsRepository } from "@/domain/tags/tag.repository.interface.js"; +import { Tag } from "@/domain/tags/tag.type.js"; +import { TagDocument, TagModel } from "@/domain/tags/tag.model.js"; import mongoose from "mongoose"; import { AppError } from "@/utils/AppError.js"; diff --git a/server/src/service/infrastructure/tagService.ts b/server/src/domain/tags/tag.service.ts similarity index 85% rename from server/src/service/infrastructure/tagService.ts rename to server/src/domain/tags/tag.service.ts index 5dc6f7cef..8c1806525 100644 --- a/server/src/service/infrastructure/tagService.ts +++ b/server/src/domain/tags/tag.service.ts @@ -1,5 +1,6 @@ -import { Tag } from "@/types/index.js"; -import { ITagsRepository, IMonitorsRepository } from "@/repositories/index.js"; +import { Tag } from "@/domain/tags/tag.type.js"; +import { IMonitorsRepository } from "@/domain/monitors/monitor.repository.interface.js"; +import { ITagsRepository } from "@/domain/tags/tag.repository.interface.js"; export interface ITagsService { createTag(tag: Partial, teamId: string): Promise; getTag(tagId: string, teamId: string): Promise; diff --git a/server/src/types/tag.ts b/server/src/domain/tags/tag.type.ts similarity index 100% rename from server/src/types/tag.ts rename to server/src/domain/tags/tag.type.ts diff --git a/server/src/db/models/Team.ts b/server/src/domain/teams/team.model.ts similarity index 90% rename from server/src/db/models/Team.ts rename to server/src/domain/teams/team.model.ts index 608f90ad8..5fb98b5ce 100755 --- a/server/src/db/models/Team.ts +++ b/server/src/domain/teams/team.model.ts @@ -1,6 +1,6 @@ import { Schema, model, type Types } from "mongoose"; -import type { Team } from "@/types/index.js"; +import type { Team } from "@/domain/teams/team.type.js"; type TeamDocumentBase = Omit & {}; interface TeamDocument extends TeamDocumentBase { diff --git a/server/src/repositories/teams/ITeamsRepository.ts b/server/src/domain/teams/team.repository.interface.ts similarity index 74% rename from server/src/repositories/teams/ITeamsRepository.ts rename to server/src/domain/teams/team.repository.interface.ts index ba1b353cf..83854123c 100644 --- a/server/src/repositories/teams/ITeamsRepository.ts +++ b/server/src/domain/teams/team.repository.interface.ts @@ -1,4 +1,4 @@ -import type { Team } from "@/types/index.js"; +import type { Team } from "@/domain/teams/team.type.js"; export interface ITeamsRepository { // create create(email: string): Promise; diff --git a/server/src/repositories/teams/MongoTeamsRepository.ts b/server/src/domain/teams/team.repository.model.ts similarity index 84% rename from server/src/repositories/teams/MongoTeamsRepository.ts rename to server/src/domain/teams/team.repository.model.ts index 04e2be6f4..d050d6f59 100644 --- a/server/src/repositories/teams/MongoTeamsRepository.ts +++ b/server/src/domain/teams/team.repository.model.ts @@ -1,6 +1,6 @@ -import { Team } from "@/types/index.js"; -import { TeamDocument, TeamModel } from "@/db/models/index.js"; -import { ITeamsRepository } from "@/repositories/index.js"; +import { Team } from "@/domain/teams/team.type.js"; +import { TeamDocument, TeamModel } from "@/domain/teams/team.model.js"; +import { ITeamsRepository } from "@/domain/teams/team.repository.interface.js"; import mongoose from "mongoose"; class MongoTeamsRepository implements ITeamsRepository { diff --git a/server/src/types/team.ts b/server/src/domain/teams/team.type.ts similarity index 100% rename from server/src/types/team.ts rename to server/src/domain/teams/team.type.ts diff --git a/server/src/db/models/User.ts b/server/src/domain/users/user.model.ts similarity index 88% rename from server/src/db/models/User.ts rename to server/src/domain/users/user.model.ts index ac3895301..960702d89 100644 --- a/server/src/db/models/User.ts +++ b/server/src/domain/users/user.model.ts @@ -1,9 +1,9 @@ import { Schema, model, type Types } from "mongoose"; import bcrypt from "bcryptjs"; -import type { User, UserProfileImage, UserRole } from "@/types/index.js"; -import { MonitorModel } from "@/db/models/index.js"; -import Team from "./Team.js"; -import NotificationModel from "./Notification.js"; +import type { User, UserProfileImage, UserRole } from "@/domain/users/user.type.js"; +import { MonitorModel } from "@/domain/monitors/monitor.model.js"; +import Team from "../teams/team.model.js"; +import NotificationModel from "../notifications/notification.model.js"; type UserDocumentBase = Omit & { teamId?: Types.ObjectId; diff --git a/server/src/repositories/users/IUsersRepository.ts b/server/src/domain/users/user.repository.interface.ts similarity index 88% rename from server/src/repositories/users/IUsersRepository.ts rename to server/src/domain/users/user.repository.interface.ts index 3fa094c54..be6212993 100644 --- a/server/src/repositories/users/IUsersRepository.ts +++ b/server/src/domain/users/user.repository.interface.ts @@ -1,4 +1,4 @@ -import type { User } from "@/types/index.js"; +import type { User } from "@/domain/users/user.type.js"; export interface IUsersRepository { // create create(user: Partial, imageFile?: Express.Multer.File | null): Promise; diff --git a/server/src/repositories/users/MongoUsersRepository.ts b/server/src/domain/users/user.repository.mongo.ts similarity index 95% rename from server/src/repositories/users/MongoUsersRepository.ts rename to server/src/domain/users/user.repository.mongo.ts index a8525f2c8..1dc729b81 100644 --- a/server/src/repositories/users/MongoUsersRepository.ts +++ b/server/src/domain/users/user.repository.mongo.ts @@ -1,7 +1,7 @@ import mongoose from "mongoose"; -import { IUsersRepository } from "@/repositories/index.js"; -import { UserModel, type UserDocument } from "@/db/models/index.js"; -import type { User, UserProfileImage } from "@/types/index.js"; +import { IUsersRepository } from "@/domain/users/user.repository.interface.js"; +import { UserModel, type UserDocument } from "@/domain/users/user.model.js"; +import type { User, UserProfileImage } from "@/domain/users/user.type.js"; import { GenerateAvatarImage } from "@/utils/imageProcessing.js"; import { ParseBoolean } from "@/utils/utils.js"; import { AppError } from "@/utils/AppError.js"; diff --git a/server/src/service/business/userService.ts b/server/src/domain/users/user.service.ts similarity index 93% rename from server/src/service/business/userService.ts rename to server/src/domain/users/user.service.ts index 8b2c52159..4edacfbc5 100644 --- a/server/src/service/business/userService.ts +++ b/server/src/domain/users/user.service.ts @@ -1,18 +1,16 @@ -import { - IInvitesRepository, - IMonitorsRepository, - IRecoveryTokensRepository, - IUsersRepository, - ISettingsRepository, - ITeamsRepository, -} from "@/repositories/index.js"; -import type { User } from "@/types/index.js"; -import { canManageRole, type UserRole } from "@/types/user.js"; +import { ISettingsRepository } from "@/domain/app-settings/app-settings-repository.interface.js"; +import { IInvitesRepository } from "@/domain/invites/invite.repository.interface.js"; +import { IRecoveryTokensRepository } from "@/domain/recovery-tokens/recovery-token.repository.interface.js"; +import { ITeamsRepository } from "@/domain/teams/team.repository.interface.js"; +import { IUsersRepository } from "@/domain/users/user.repository.interface.js"; +import { IMonitorsRepository } from "@/domain/monitors/monitor.repository.interface.js"; +import type { User } from "@/domain/users/user.type.js"; +import { canManageRole, type UserRole } from "@/domain/users/user.type.js"; import bcrypt from "bcryptjs"; import { AppError } from "@/utils/AppError.js"; -import { IJobQueue } from "@/service/infrastructure/JobQueues/IJobQueue.js"; -import { IEmailService } from "@/service/infrastructure/emailService.js"; -import { EnvConfig, ISettingsService } from "@/service/system/settingsService.js"; +import { IJobQueue } from "@/service/job-queues/job-queue.interface.js"; +import { IEmailService } from "@/service/emailService.js"; +import { EnvConfig, ISettingsService } from "@/domain/app-settings/app-settings.service.js"; import { ILogger } from "@/utils/logger.js"; import jwt from "jsonwebtoken"; import crypto from "crypto"; diff --git a/server/src/types/user.ts b/server/src/domain/users/user.type.ts similarity index 100% rename from server/src/types/user.ts rename to server/src/domain/users/user.type.ts diff --git a/server/src/index.ts b/server/src/index.ts index 45c75ac8b..cd3a39cdd 100755 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -2,13 +2,13 @@ import { initializeServices } from "./config/services.js"; import { initializeControllers } from "./config/controllers.js"; import { createApp } from "./app.js"; import { initShutdownListener } from "@/shutdown.js"; -import { validateEnv } from "@/validation/envValidation.js"; +import { validateEnv } from "@/config/envValidation.js"; import { fileURLToPath } from "url"; import path from "path"; import fs from "fs"; import Logger, { ILogger } from "@/utils/logger.js"; -import { SettingsService } from "@/service/index.js"; +import { SettingsService } from "@/domain/app-settings/app-settings.service.js"; const SERVICE_NAME = "Server"; let logger: ILogger; @@ -52,7 +52,6 @@ const startApp = async () => { frontendPath, openApiSpec, }); - const server = app.listen(env.PORT, () => { logger.info({ message: `Server started on port:${env.PORT}` }); }); diff --git a/server/src/repositories/index.ts b/server/src/repositories/index.ts deleted file mode 100644 index d36d9d189..000000000 --- a/server/src/repositories/index.ts +++ /dev/null @@ -1,47 +0,0 @@ -export * from "@/repositories/monitors/IMonitorsRepository.js"; -export { default as MongoMonitorsRepository } from "@/repositories/monitors/MongoMonitorsRepository.js"; - -export * from "@/repositories/checks/IChecksRepository.js"; -export { default as MongoChecksRepository } from "@/repositories/checks/MongoChecksRepistory.js"; - -export * from "@/repositories/monitor-stats/IMonitorStatsRepository.js"; -export { default as MongoMonitorStatsRepository } from "@/repositories/monitor-stats/MongoMonitorStatsRepository.js"; - -export * from "@/repositories/status-pages/IStatusPagesRepository.js"; -export { default as MongoStatusPagesRepository } from "@/repositories/status-pages/MongoStatusPagesRepository.js"; - -export * from "@/repositories/users/IUsersRepository.js"; -export { default as MongoUsersRepository } from "@/repositories/users/MongoUsersRepository.js"; - -export * from "@/repositories/invites/IInvitesRepository.js"; -export { default as MongoInvitesRepository } from "@/repositories/invites/MongoInviteRepository.js"; - -export * from "@/repositories/recovery-tokens/IRecoveryTokensRepository.js"; -export { default as MongoRecoveryTokensRepository } from "@/repositories/recovery-tokens/MongoRecoveryTokensRepository.js"; - -export * from "@/repositories/settings/ISettingsRepository.js"; -export { default as MongoSettingsRepository } from "@/repositories/settings/MongoSettingsRepository.js"; - -export * from "@/repositories/notifications/INotificationsRepository.js"; -export { default as MongoNotificationsRepository } from "@/repositories/notifications/MongoNotificationsRepository.js"; - -export * from "@/repositories/tags/ITagsRepository.js"; -export { default as MongoTagsRepository } from "@/repositories/tags/MongoTagsRepository.js"; - -export * from "@/repositories/incidents/IIncidentsRepository.js"; -export { default as MongoIncidentsRepository } from "@/repositories/incidents/MongoIncidentsRepository.js"; - -export * from "@/repositories/teams/ITeamsRepository.js"; -export { default as MongoTeamsRepository } from "@/repositories/teams/MongoTeamsRepository.js"; - -export * from "@/repositories/maintenance-windows/IMaintenanceWindowsRepository.js"; -export { default as MongoMaintenanceWindowsRepository } from "@/repositories/maintenance-windows/MongoMaintenanceWindowsRepository.js"; - -export * from "@/repositories/geo-checks/IGeoChecksRepository.js"; -export { default as MongoGeoChecksRepository } from "@/repositories/geo-checks/MongoGeoChecksRepository.js"; - -export * from "@/repositories/dlq/IDLQRepository.js"; -export { default as MongoDLQRepository } from "@/repositories/dlq/MongoDLQRepository.js"; - -export * from "@/repositories/queue-workers/IQueueWorkersRepository.js"; -export { default as MongoQueueWorkersRepository } from "@/repositories/queue-workers/MongoQueueWorkersRepository.js"; diff --git a/server/src/service/infrastructure/bufferService.ts b/server/src/service/bufferService.ts similarity index 91% rename from server/src/service/infrastructure/bufferService.ts rename to server/src/service/bufferService.ts index 5a1fb3d12..38dfb3545 100755 --- a/server/src/service/infrastructure/bufferService.ts +++ b/server/src/service/bufferService.ts @@ -1,9 +1,9 @@ -import type { Check } from "@/types/index.js"; -import type { GeoCheck } from "@/types/index.js"; -import type { IGeoChecksService } from "../business/geoChecksService.js"; +import type { Check } from "@/domain/checks/check.type.js"; +import type { GeoCheck } from "@/domain/geo-checks/geo-check.type.js"; +import type { IGeoChecksService } from "../domain/geo-checks/geo-check.service.js"; import type { ILogger } from "@/utils/logger.js"; -import type { ISettingsService } from "@/service/system/settingsService.js"; -import { ICheckService } from "../business/checkService.js"; +import type { ISettingsService } from "@/domain/app-settings/app-settings.service.js"; +import { ICheckService } from "../domain/checks/check.service.js"; const SERVICE_NAME = "BufferService"; export interface IBufferService { diff --git a/server/src/service/infrastructure/emailService.ts b/server/src/service/emailService.ts similarity index 97% rename from server/src/service/infrastructure/emailService.ts rename to server/src/service/emailService.ts index 4428b0477..ca153392d 100755 --- a/server/src/service/infrastructure/emailService.ts +++ b/server/src/service/emailService.ts @@ -1,6 +1,6 @@ import { fileURLToPath } from "url"; -import { EmailTransportConfig } from "@/types/index.js"; -import { ISettingsService } from "@/service/system/settingsService.js"; +import { EmailTransportConfig } from "@/domain/app-settings/app-settings.type.js"; +import { ISettingsService } from "@/domain/app-settings/app-settings.service.js"; import { ILogger } from "@/utils/logger.js"; import fs from "node:fs"; import path from "node:path"; diff --git a/server/src/service/infrastructure/globalPingService.ts b/server/src/service/globalPingService.ts similarity index 95% rename from server/src/service/infrastructure/globalPingService.ts rename to server/src/service/globalPingService.ts index 4d7a67113..cebd95408 100644 --- a/server/src/service/infrastructure/globalPingService.ts +++ b/server/src/service/globalPingService.ts @@ -1,9 +1,9 @@ -import type { GeoContinent, GeoCheckResult, GeoCheckTimings, GeoCheckLocation } from "@/types/geoCheck.js"; -import { supportsGeoCheck, type HttpStatusCode } from "@/types/monitor.js"; -import { MonitorType } from "@/types/index.js"; +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 type { ILogger } from "@/utils/logger.js"; import got from "got"; -import { isStatusUp } from "@/service/infrastructure/network/utils.js"; +import { isStatusUp } from "@/service/network/utils.js"; const SERVICE_NAME = "GlobalPingService"; const GLOBAL_PING_API_BASE = "https://api.globalping.io/v1"; diff --git a/server/src/service/index.ts b/server/src/service/index.ts deleted file mode 100644 index 2a0974e27..000000000 --- a/server/src/service/index.ts +++ /dev/null @@ -1,41 +0,0 @@ -// Business services -export * from "@/service/business/checkService.js"; -export * from "@/service/business/diagnosticService.js"; -export * from "@/service/business/geoChecksService.js"; -export * from "@/service/business/incidentService.js"; -export * from "@/service/business/inviteService.js"; -export * from "@/service/business/maintenanceWindowService.js"; -export * from "@/service/business/monitorService.js"; -export * from "@/service/business/statusPageService.js"; -export * from "@/service/business/userService.js"; - -// Infrastructure services -export * from "@/service/infrastructure/JobQueues/IJobQueue.js"; -export * from "@/service/infrastructure/JobQueues/SuperSimpleQueue.js"; -export * from "@/service/infrastructure/JobQueues/LessSimpleQueue.js"; -export * from "@/service/infrastructure/JobQueues/QueueHelper.js"; -export * from "@/service/infrastructure/notificationMessageBuilder.js"; -export * from "@/service/infrastructure/bufferService.js"; -export * from "@/service/infrastructure/emailService.js"; -export * from "@/service/infrastructure/globalPingService.js"; -export * from "@/service/infrastructure/networkService.js"; -export * from "@/service/infrastructure/notificationsService.js"; -export * from "@/service/infrastructure/tagService.js"; -export * from "@/service/infrastructure/statusService.js"; - -// Notification providers -export * from "@/service/infrastructure/notificationProviders/discord.js"; -export * from "@/service/infrastructure/notificationProviders/email.js"; -export * from "@/service/infrastructure/notificationProviders/INotificationProvider.js"; -export * from "@/service/infrastructure/notificationProviders/matrix.js"; -export * from "@/service/infrastructure/notificationProviders/pagerduty.js"; -export * from "@/service/infrastructure/notificationProviders/slack.js"; -export * from "@/service/infrastructure/notificationProviders/teams.js"; -export * from "@/service/infrastructure/notificationProviders/webhook.js"; -export * from "@/service/infrastructure/notificationProviders/telegram.js"; -export * from "@/service/infrastructure/notificationProviders/pushover.js"; -export * from "@/service/infrastructure/notificationProviders/twilio.js"; -export * from "@/service/infrastructure/notificationProviders/ntfy.js"; - -// System services -export * from "@/service/system/settingsService.js"; diff --git a/server/src/service/infrastructure/JobQueues/QueueHelper.ts b/server/src/service/job-queues/job-queue.helper.ts similarity index 90% rename from server/src/service/infrastructure/JobQueues/QueueHelper.ts rename to server/src/service/job-queues/job-queue.helper.ts index ea86feae0..69ecb86c6 100644 --- a/server/src/service/infrastructure/JobQueues/QueueHelper.ts +++ b/server/src/service/job-queues/job-queue.helper.ts @@ -1,29 +1,26 @@ const SERVICE_NAME = "JobQueueHelper"; -import type { Monitor } from "@/types/monitor.js"; -import { supportsGeoCheck } from "@/types/monitor.js"; +import type { Monitor } from "@/domain/monitors/monitor.types.js"; +import { supportsGeoCheck } from "@/domain/monitors/monitor.types.js"; import { AppError } from "@/utils/AppError.js"; -import { - ICheckService, - INetworkService, - INotificationsService, - ISettingsService, - IStatusService, - IncidentService, - type IGeoChecksService, -} from "@/service/index.js"; -import { CHECK_TTL_SENTINEL, type StatusChangeResult } from "@/types/index.js"; +import { ISettingsService } from "@/domain/app-settings/app-settings.service.js"; +import { ICheckService } from "@/domain/checks/check.service.js"; +import { type IGeoChecksService } from "@/domain/geo-checks/geo-check.service.js"; +import { IncidentService } from "@/domain/incidents/incident.service.js"; +import { INotificationsService } from "@/domain/notifications/notification.service.js"; +import { INetworkService } from "@/service/networkService.js"; +import { IStatusService } from "@/service/statusService.js"; +import { CHECK_TTL_SENTINEL } from "@/domain/checks/check.type.js"; +import { type StatusChangeResult } from "@/types/network.js"; import { isWindowActive } from "@/utils/maintenanceWindow.js"; -import { - IMaintenanceWindowsRepository, - IMonitorsRepository, - ITeamsRepository, - IMonitorStatsRepository, - IChecksRepository, - IIncidentsRepository, - IGeoChecksRepository, -} from "@/repositories/index.js"; +import { IChecksRepository } from "@/domain/checks/check.repository.interface.js"; +import { IGeoChecksRepository } from "@/domain/geo-checks/geo-check.repository.interface.js"; +import { IIncidentsRepository } from "@/domain/incidents/incident.repository.interface.js"; +import { IMaintenanceWindowsRepository } from "@/domain/maintenance-windows/maintenance-window.repository.interface.js"; +import { IMonitorStatsRepository } from "@/domain/monitor-stats/monitor-stats.repository.interface.js"; +import { IMonitorsRepository } from "@/domain/monitors/monitor.repository.interface.js"; +import { ITeamsRepository } from "@/domain/teams/team.repository.interface.js"; import { ILogger } from "@/utils/logger.js"; -import { IBufferService } from "@/service/index.js"; +import { IBufferService } from "@/service/bufferService.js"; export interface IQueueHelper { readonly serviceName: string; diff --git a/server/src/service/infrastructure/JobQueues/IJobQueue.ts b/server/src/service/job-queues/job-queue.interface.ts similarity index 92% rename from server/src/service/infrastructure/JobQueues/IJobQueue.ts rename to server/src/service/job-queues/job-queue.interface.ts index ccbca625a..3e8267738 100644 --- a/server/src/service/infrastructure/JobQueues/IJobQueue.ts +++ b/server/src/service/job-queues/job-queue.interface.ts @@ -1,5 +1,5 @@ -import { Monitor } from "@/types/monitor.js"; -import { QueueWorker } from "@/types/settings.js"; +import { Monitor } from "@/domain/monitors/monitor.types.js"; +import { QueueWorker } from "@/domain/queue-workers/queue-worker.type.js"; export type QueueJobFailure = { monitorId: string | number; diff --git a/server/src/service/infrastructure/JobQueues/LessSimpleQueue.ts b/server/src/service/job-queues/job-queue.less-simple.ts similarity index 95% rename from server/src/service/infrastructure/JobQueues/LessSimpleQueue.ts rename to server/src/service/job-queues/job-queue.less-simple.ts index 963b41267..ad12341c1 100644 --- a/server/src/service/infrastructure/JobQueues/LessSimpleQueue.ts +++ b/server/src/service/job-queues/job-queue.less-simple.ts @@ -1,11 +1,12 @@ -import { IMonitorsRepository, IQueueWorkersRepository } from "@/repositories/index.js"; +import { IMonitorsRepository } from "@/domain/monitors/monitor.repository.interface.js"; +import { IQueueWorkersRepository } from "@/domain/queue-workers/queue-worker.repository.interface.js"; import { ILogger } from "@/utils/logger.js"; import { MongoStore, Scheduler, IJob, AddJobInput } from "less-simple-scheduler"; -import { IQueueHelper } from "@/service/infrastructure/JobQueues/QueueHelper.js"; -import { Monitor, supportsGeoCheck } from "@/types/monitor.js"; -import { type QueueMetrics, type QueueJobsPagination, type QueueJobsPage, IJobQueue } from "@/service/infrastructure/JobQueues/IJobQueue.js"; -import { type QueueMode } from "@/types/settings.js"; -import { EnvConfig } from "@/service/system/settingsService.js"; +import { IQueueHelper } from "@/service/job-queues/job-queue.helper.js"; +import { Monitor, supportsGeoCheck } from "@/domain/monitors/monitor.types.js"; +import { type QueueMetrics, type QueueJobsPagination, type QueueJobsPage, IJobQueue } from "@/service/job-queues/job-queue.interface.js"; +import { type QueueMode } from "@/domain/app-settings/app-settings.type.js"; +import { EnvConfig } from "@/domain/app-settings/app-settings.service.js"; const SERVICE_NAME = "JobQueue"; // How long after its last heartbeat a worker is still considered alive. Must be longer than the scheduler's heartbeat diff --git a/server/src/service/infrastructure/JobQueues/SuperSimpleQueue.ts b/server/src/service/job-queues/job-queue.sumper-simple.ts similarity index 96% rename from server/src/service/infrastructure/JobQueues/SuperSimpleQueue.ts rename to server/src/service/job-queues/job-queue.sumper-simple.ts index 42409696b..c53ca5860 100644 --- a/server/src/service/infrastructure/JobQueues/SuperSimpleQueue.ts +++ b/server/src/service/job-queues/job-queue.sumper-simple.ts @@ -1,12 +1,12 @@ -import { IMonitorsRepository } from "@/repositories/index.js"; +import { IMonitorsRepository } from "@/domain/monitors/monitor.repository.interface.js"; import { ILogger } from "@/utils/logger.js"; import Scheduler from "super-simple-scheduler"; -import { IQueueHelper } from "@/service/infrastructure/JobQueues/QueueHelper.js"; -import { Monitor, MonitorType, supportsGeoCheck } from "@/types/monitor.js"; +import { IQueueHelper } from "@/service/job-queues/job-queue.helper.js"; +import { Monitor, MonitorType, supportsGeoCheck } from "@/domain/monitors/monitor.types.js"; import { hostname } from "node:os"; import { randomUUID } from "node:crypto"; -import { QueueMode } from "@/types/settings.js"; -import { IJobQueue, type QueueJobSummary } from "@/service/infrastructure/JobQueues/IJobQueue.js"; +import { QueueMode } from "@/domain/app-settings/app-settings.type.js"; +import { IJobQueue, type QueueJobSummary } from "@/service/job-queues/job-queue.interface.js"; const SERVICE_NAME = "JobQueue"; diff --git a/server/src/service/infrastructure/network/AdvancedMatcher.ts b/server/src/service/network/AdvancedMatcher.ts similarity index 96% rename from server/src/service/infrastructure/network/AdvancedMatcher.ts rename to server/src/service/network/AdvancedMatcher.ts index d6350ef63..8b25c53e8 100644 --- a/server/src/service/infrastructure/network/AdvancedMatcher.ts +++ b/server/src/service/network/AdvancedMatcher.ts @@ -1,4 +1,4 @@ -import { Monitor } from "@/types/monitor.js"; +import { Monitor } from "@/domain/monitors/monitor.types.js"; import jmespath from "jmespath"; type JmesPath = typeof jmespath; diff --git a/server/src/service/infrastructure/network/DNSProvider.ts b/server/src/service/network/DNSProvider.ts similarity index 91% rename from server/src/service/infrastructure/network/DNSProvider.ts rename to server/src/service/network/DNSProvider.ts index 92b4eb333..1aeff7e14 100644 --- a/server/src/service/infrastructure/network/DNSProvider.ts +++ b/server/src/service/network/DNSProvider.ts @@ -1,9 +1,9 @@ import { DNSStatusPayload, MonitorStatusResponse } from "@/types/network.js"; -import { IStatusProvider } from "@/service/infrastructure/network/IStatusProvider.js"; +import { IStatusProvider } from "@/service/network/IStatusProvider.js"; import type { Resolver } from "dns/promises"; -import { Monitor, MonitorType } from "@/types/monitor.js"; +import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js"; import { AppError } from "@/utils/AppError.js"; -import { NETWORK_ERROR, timeRequest } from "@/service/infrastructure/network/utils.js"; +import { NETWORK_ERROR, timeRequest } from "@/service/network/utils.js"; const SERVICE_NAME = "DNSProvider"; diff --git a/server/src/service/infrastructure/network/DockerProvider.ts b/server/src/service/network/DockerProvider.ts similarity index 95% rename from server/src/service/infrastructure/network/DockerProvider.ts rename to server/src/service/network/DockerProvider.ts index 1d4b98818..0cfb133af 100644 --- a/server/src/service/infrastructure/network/DockerProvider.ts +++ b/server/src/service/network/DockerProvider.ts @@ -1,10 +1,10 @@ -import { IStatusProvider } from "@/service/infrastructure/network/IStatusProvider.js"; +import { IStatusProvider } from "@/service/network/IStatusProvider.js"; import { DockerStatusPayload, MonitorStatusResponse } from "@/types/network.js"; -import { Monitor, MonitorType } from "@/types/monitor.js"; +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/infrastructure/network/utils.js"; +import { NETWORK_ERROR, timeRequest } from "@/service/network/utils.js"; type DockerodeType = typeof Dockerode; diff --git a/server/src/service/infrastructure/network/GameProvider.ts b/server/src/service/network/GameProvider.ts similarity index 89% rename from server/src/service/infrastructure/network/GameProvider.ts rename to server/src/service/network/GameProvider.ts index e2ace7433..4e063396d 100644 --- a/server/src/service/infrastructure/network/GameProvider.ts +++ b/server/src/service/network/GameProvider.ts @@ -1,9 +1,9 @@ -import { IStatusProvider } from "@/service/infrastructure/network/IStatusProvider.js"; +import { IStatusProvider } from "@/service/network/IStatusProvider.js"; import { GameStatusPayload, MonitorStatusResponse } from "@/types/network.js"; -import { Monitor, MonitorType } from "@/types/monitor.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/infrastructure/network/utils.js"; +import { NETWORK_ERROR } from "@/service/network/utils.js"; import { ILogger } from "@/utils/logger.js"; type GameDigType = typeof GameDig; diff --git a/server/src/service/infrastructure/network/GrpcProvider.ts b/server/src/service/network/GrpcProvider.ts similarity index 96% rename from server/src/service/infrastructure/network/GrpcProvider.ts rename to server/src/service/network/GrpcProvider.ts index 14a063bca..4e79cef7f 100644 --- a/server/src/service/infrastructure/network/GrpcProvider.ts +++ b/server/src/service/network/GrpcProvider.ts @@ -1,8 +1,8 @@ -import { IStatusProvider } from "@/service/infrastructure/network/IStatusProvider.js"; +import { IStatusProvider } from "@/service/network/IStatusProvider.js"; import { GrpcStatusPayload, MonitorStatusResponse } from "@/types/network.js"; -import { Monitor, MonitorType } from "@/types/monitor.js"; +import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js"; import { AppError } from "@/utils/AppError.js"; -import { timeRequest } from "@/service/infrastructure/network/utils.js"; +import { timeRequest } from "@/service/network/utils.js"; import * as grpc from "@grpc/grpc-js"; import * as protoLoader from "@grpc/proto-loader"; diff --git a/server/src/service/infrastructure/network/HardwareProvider.ts b/server/src/service/network/HardwareProvider.ts similarity index 79% rename from server/src/service/infrastructure/network/HardwareProvider.ts rename to server/src/service/network/HardwareProvider.ts index a9180381e..c612bdbad 100644 --- a/server/src/service/infrastructure/network/HardwareProvider.ts +++ b/server/src/service/network/HardwareProvider.ts @@ -1,7 +1,7 @@ -import { IStatusProvider } from "@/service/infrastructure/network/IStatusProvider.js"; +import { IStatusProvider } from "@/service/network/IStatusProvider.js"; import { HardwareStatusPayload, MonitorStatusResponse } from "@/types/network.js"; -import { Monitor, MonitorType } from "@/types/monitor.js"; -import { HttpProvider } from "@/service/infrastructure/network/HttpProvider.js"; +import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js"; +import { HttpProvider } from "@/service/network/HttpProvider.js"; import { AppError } from "@/utils/AppError.js"; export class HardwareProvider implements IStatusProvider { diff --git a/server/src/service/infrastructure/network/HttpProvider.ts b/server/src/service/network/HttpProvider.ts similarity index 93% rename from server/src/service/infrastructure/network/HttpProvider.ts rename to server/src/service/network/HttpProvider.ts index a31bdf770..9f638dbd6 100644 --- a/server/src/service/infrastructure/network/HttpProvider.ts +++ b/server/src/service/network/HttpProvider.ts @@ -1,12 +1,12 @@ import { type Got, HTTPError, RequestError } from "got"; -import { IAdvancedMatcher } from "@/service/infrastructure/network/AdvancedMatcher.js"; -import { IStatusProvider } from "@/service/infrastructure/network/IStatusProvider.js"; +import { IAdvancedMatcher } from "@/service/network/AdvancedMatcher.js"; +import { IStatusProvider } from "@/service/network/IStatusProvider.js"; 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 "@/types/monitor.js"; -import { NETWORK_ERROR, isStatusUp } from "@/service/infrastructure/network/utils.js"; +import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js"; +import { NETWORK_ERROR, isStatusUp } from "@/service/network/utils.js"; import CacheableLookup from "cacheable-lookup"; export class HttpProvider implements IStatusProvider { diff --git a/server/src/service/infrastructure/network/IStatusProvider.ts b/server/src/service/network/IStatusProvider.ts similarity index 74% rename from server/src/service/infrastructure/network/IStatusProvider.ts rename to server/src/service/network/IStatusProvider.ts index bde6a2db0..f077ff9b5 100644 --- a/server/src/service/infrastructure/network/IStatusProvider.ts +++ b/server/src/service/network/IStatusProvider.ts @@ -1,4 +1,4 @@ -import { Monitor, MonitorType } from "@/types/monitor.js"; +import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js"; import { MonitorStatusResponse } from "@/types/network.js"; export interface IStatusProvider { diff --git a/server/src/service/infrastructure/network/PageSpeedProvider.ts b/server/src/service/network/PageSpeedProvider.ts similarity index 87% rename from server/src/service/infrastructure/network/PageSpeedProvider.ts rename to server/src/service/network/PageSpeedProvider.ts index 0d8560868..a609ca80b 100644 --- a/server/src/service/infrastructure/network/PageSpeedProvider.ts +++ b/server/src/service/network/PageSpeedProvider.ts @@ -1,8 +1,8 @@ -import { IStatusProvider } from "@/service/infrastructure/network/IStatusProvider.js"; +import { IStatusProvider } from "@/service/network/IStatusProvider.js"; import { MonitorStatusResponse, PageSpeedStatusPayload } from "@/types/network.js"; -import { Monitor, MonitorType, DefaultPageSpeedStrategy } from "@/types/monitor.js"; -import { HttpProvider } from "@/service/infrastructure/network/HttpProvider.js"; -import { ISettingsService } from "@/service/system/settingsService.js"; +import { Monitor, MonitorType, DefaultPageSpeedStrategy } from "@/domain/monitors/monitor.types.js"; +import { HttpProvider } from "@/service/network/HttpProvider.js"; +import { ISettingsService } from "@/domain/app-settings/app-settings.service.js"; import { ILogger } from "@/utils/logger.js"; import { AppError } from "@/utils/AppError.js"; diff --git a/server/src/service/infrastructure/network/PingProvider.ts b/server/src/service/network/PingProvider.ts similarity index 92% rename from server/src/service/infrastructure/network/PingProvider.ts rename to server/src/service/network/PingProvider.ts index 0b9691da9..ee66046f9 100644 --- a/server/src/service/infrastructure/network/PingProvider.ts +++ b/server/src/service/network/PingProvider.ts @@ -1,10 +1,10 @@ import { PingStatusPayload } from "@/types/network.js"; import { IStatusProvider } from "./IStatusProvider.js"; -import { MonitorType, Monitor } from "@/types/monitor.js"; +import { MonitorType, Monitor } from "@/domain/monitors/monitor.types.js"; import { MonitorStatusResponse } from "@/types/network.js"; import { AppError } from "@/utils/AppError.js"; import ping from "ping"; -import { timeRequest } from "@/service/infrastructure/network/utils.js"; +import { timeRequest } from "@/service/network/utils.js"; const SERVICE_NAME = "PingProvider"; type Ping = typeof ping; diff --git a/server/src/service/infrastructure/network/PortProvider.ts b/server/src/service/network/PortProvider.ts similarity index 90% rename from server/src/service/infrastructure/network/PortProvider.ts rename to server/src/service/network/PortProvider.ts index 7c1c96ce4..debcd8509 100644 --- a/server/src/service/infrastructure/network/PortProvider.ts +++ b/server/src/service/network/PortProvider.ts @@ -1,8 +1,8 @@ -import { IStatusProvider } from "@/service/infrastructure/network/IStatusProvider.js"; +import { IStatusProvider } from "@/service/network/IStatusProvider.js"; import { PortStatusPayload, MonitorStatusResponse } from "@/types/network.js"; -import { Monitor, MonitorType } from "@/types/monitor.js"; +import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js"; import { AppError } from "@/utils/AppError.js"; -import { NETWORK_ERROR, timeRequest } from "@/service/infrastructure/network/utils.js"; +import { NETWORK_ERROR, timeRequest } from "@/service/network/utils.js"; import * as net from "net"; type NetType = typeof net; diff --git a/server/src/service/infrastructure/network/WebSocketProvider.ts b/server/src/service/network/WebSocketProvider.ts similarity index 91% rename from server/src/service/infrastructure/network/WebSocketProvider.ts rename to server/src/service/network/WebSocketProvider.ts index 0af436067..fef5f76b1 100644 --- a/server/src/service/infrastructure/network/WebSocketProvider.ts +++ b/server/src/service/network/WebSocketProvider.ts @@ -1,8 +1,8 @@ -import { IStatusProvider } from "@/service/infrastructure/network/IStatusProvider.js"; +import { IStatusProvider } from "@/service/network/IStatusProvider.js"; import { WebSocketStatusPayload, MonitorStatusResponse } from "@/types/network.js"; -import { Monitor, MonitorType } from "@/types/monitor.js"; +import { Monitor, MonitorType } from "@/domain/monitors/monitor.types.js"; import { AppError } from "@/utils/AppError.js"; -import { NETWORK_ERROR, timeRequest } from "@/service/infrastructure/network/utils.js"; +import { NETWORK_ERROR, timeRequest } from "@/service/network/utils.js"; import type WebSocket from "ws"; type WebSocketConstructor = typeof WebSocket; diff --git a/server/src/service/infrastructure/network/utils.ts b/server/src/service/network/utils.ts similarity index 92% rename from server/src/service/infrastructure/network/utils.ts rename to server/src/service/network/utils.ts index 994e19d9d..8bcbc4335 100644 --- a/server/src/service/infrastructure/network/utils.ts +++ b/server/src/service/network/utils.ts @@ -1,4 +1,4 @@ -import type { HttpStatusCode } from "@/types/monitor.js"; +import type { HttpStatusCode } from "@/domain/monitors/monitor.types.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/infrastructure/networkService.ts b/server/src/service/networkService.ts similarity index 96% rename from server/src/service/infrastructure/networkService.ts rename to server/src/service/networkService.ts index ca85d12ac..3470c6086 100644 --- a/server/src/service/infrastructure/networkService.ts +++ b/server/src/service/networkService.ts @@ -1,7 +1,8 @@ -import type { Monitor, MonitorStatusResponse, MonitorPayloadMap, MonitorType } from "@/types/index.js"; +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/infrastructure/network/utils.js"; +import { NETWORK_ERROR } from "@/service/network/utils.js"; import { ILogger } from "@/utils/logger.js"; import { IStatusProvider } from "./network/IStatusProvider.js"; const SERVICE_NAME = "NetworkService"; diff --git a/server/src/service/infrastructure/protos/health.proto b/server/src/service/protos/health.proto similarity index 100% rename from server/src/service/infrastructure/protos/health.proto rename to server/src/service/protos/health.proto diff --git a/server/src/service/infrastructure/statusService.ts b/server/src/service/statusService.ts similarity index 95% rename from server/src/service/infrastructure/statusService.ts rename to server/src/service/statusService.ts index 617f15944..47aa8d89a 100755 --- a/server/src/service/infrastructure/statusService.ts +++ b/server/src/service/statusService.ts @@ -1,26 +1,25 @@ -import { IChecksRepository, IMonitorsRepository, IMonitorStatsRepository } from "@/repositories/index.js"; +import { IChecksRepository } from "@/domain/checks/check.repository.interface.js"; +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, - MonitorStatusResponse, - StatusChangeResult, - Check, - HardwareStatusPayload, - PageSpeedStatusPayload, - PingStatusPayload, - HttpStatusPayload, DockerStatusPayload, - PortStatusPayload, GameStatusPayload, GrpcStatusPayload, - CheckSnapshot, - CheckDiskInfo, -} from "@/types/index.js"; + HardwareStatusPayload, + HttpStatusPayload, + MonitorStatusResponse, + PageSpeedStatusPayload, + PingStatusPayload, + PortStatusPayload, + StatusChangeResult, +} from "@/types/network.js"; import { AppError } from "@/utils/AppError.js"; import { ILogger } from "@/utils/logger.js"; import { IBufferService } from "./bufferService.js"; import type { HardwareStatusMetrics } from "@/types/network.js"; -import { MAX_RECENT_CHECKS } from "@/types/index.js"; +import { MAX_RECENT_CHECKS } from "@/domain/monitors/monitor.types.js"; const SERVICE_NAME = "StatusService"; const HARDWARE_ALERT_COUNTER_START = 5; diff --git a/server/src/types/alert.ts b/server/src/types/alert.ts deleted file mode 100644 index 3cb9d7734..000000000 --- a/server/src/types/alert.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { NotificationChannel } from "@/types/index.js"; -export interface AlertWebhookPayload { - body: Record; -} - -export interface AlertPagerDutyPayload { - routing_key?: string; - dedup_key?: string; - event_action?: "trigger" | "resolve"; - payload: Record; -} - -export interface AlertMatrixPayload { - plainText: string; - htmlText: string; -} - -export interface DiscordEmbedField { - name: string; - value: string; - inline?: boolean; -} - -export interface AlertDiscordPayload { - title: string; - description: string; - color: number; - fields: DiscordEmbedField[]; - timestamp: string; -} - -export interface Alert { - channel: NotificationChannel; - address?: string; - subject: string; - message: string; - html?: string; - discordContent?: Record | null; - webhook?: AlertWebhookPayload | null; - pagerDuty?: AlertPagerDutyPayload | null; - matrix?: AlertMatrixPayload | null; -} diff --git a/server/src/types/email.ts b/server/src/types/email.ts deleted file mode 100644 index 6e884319f..000000000 --- a/server/src/types/email.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Settings } from "./settings.js"; - -export type EmailTransportConfig = Pick< - Settings, - | "systemEmailHost" - | "systemEmailPort" - | "systemEmailAddress" - | "systemEmailDisplayName" - | "systemEmailPassword" - | "systemEmailUser" - | "systemEmailConnectionHost" - | "systemEmailTLSServername" - | "systemEmailSecure" - | "systemEmailPool" - | "systemEmailIgnoreTLS" - | "systemEmailRequireTLS" - | "systemEmailRejectUnauthorized" ->; diff --git a/server/src/types/express.d.ts b/server/src/types/express.d.ts index 973d2d5b9..92a4a86c6 100644 --- a/server/src/types/express.d.ts +++ b/server/src/types/express.d.ts @@ -1,4 +1,4 @@ -import type { User } from "@/types/index.js"; +import type { User } from "@/domain/users/user.type.js"; declare global { namespace Express { diff --git a/server/src/types/index.ts b/server/src/types/index.ts deleted file mode 100644 index ca055ba70..000000000 --- a/server/src/types/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -export * from "@/types/check.js"; -export * from "@/types/geoCheck.js"; -export * from "@/types/monitor.js"; -export * from "@/types/monitorStats.js"; -export * from "@/types/statusPage.js"; -export * from "@/types/network.js"; -export * from "@/types/user.js"; -export * from "@/types/invite.js"; -export * from "@/types/recoveryToken.js"; -export * from "@/types/settings.js"; -export * from "@/types/notification.js"; -export * from "@/types/alert.js"; -export * from "@/types/incident.js"; -export * from "@/types/email.js"; -export * from "@/types/team.js"; -export * from "@/types/maintenanceWindow.js"; -export * from "@/types/dlqItem.js"; -export * from "@/types/tag.js"; diff --git a/server/src/types/network.ts b/server/src/types/network.ts index 246422bf2..fe85221f2 100644 --- a/server/src/types/network.ts +++ b/server/src/types/network.ts @@ -8,12 +8,8 @@ import type { CheckNetworkInterfaceInfo, GotTimings, ILighthouseAudit, - DnsRecordType, - Monitor, - MonitorMatchMethod, - MonitorType, - MonitorStatus, -} from "@/types/index.js"; +} from "@/domain/checks/check.type.js"; +import type { DnsRecordType, Monitor, MonitorMatchMethod, MonitorStatus, MonitorType } from "@/domain/monitors/monitor.types.js"; import type { QueryResult } from "gamedig"; diff --git a/server/src/types/notification.ts b/server/src/types/notification.ts deleted file mode 100644 index 0e389f9e2..000000000 --- a/server/src/types/notification.ts +++ /dev/null @@ -1,32 +0,0 @@ -export const NotificationChannels = [ - "email", - "slack", - "discord", - "webhook", - "pager_duty", - "matrix", - "teams", - "telegram", - "pushover", - "twilio", - "ntfy", -] as const; -export type NotificationChannel = (typeof NotificationChannels)[number]; - -export interface Notification { - id: string; - userId: string; - teamId: string; - type: NotificationChannel; - notificationName: string; - address?: string; - phone?: string; - homeserverUrl?: string; - roomId?: string; - accessToken?: string; - accountSid?: string; - twilioPhoneNumber?: string; - topic?: string; - createdAt: string; - updatedAt: string; -} diff --git a/server/src/utils/dataUtils.ts b/server/src/utils/dataUtils.ts index f6d877a35..7b46619e8 100755 --- a/server/src/utils/dataUtils.ts +++ b/server/src/utils/dataUtils.ts @@ -1,4 +1,4 @@ -import type { GroupedCheck, NormalizedCheck, NormalizedUptimeCheck, HasResponseTime } from "@/types/index.js"; +import type { GroupedCheck, HasResponseTime, NormalizedCheck, NormalizedUptimeCheck } from "@/domain/checks/check.type.js"; export const getDateForRange = (dateRange: string): Date | undefined => { const now = Date.now(); diff --git a/server/src/utils/logger.ts b/server/src/utils/logger.ts index e3c0db169..c53e7112c 100755 --- a/server/src/utils/logger.ts +++ b/server/src/utils/logger.ts @@ -1,7 +1,7 @@ import { createLogger, format, transports, Logger as WinstonLogger } from "winston"; import type { Logform } from "winston"; import dotenv from "dotenv"; -import { EnvConfig } from "@/service/system/settingsService.js"; +import { EnvConfig } from "@/domain/app-settings/app-settings.service.js"; dotenv.config(); const SERVICE_NAME = "Logger"; diff --git a/server/src/utils/maintenanceWindow.ts b/server/src/utils/maintenanceWindow.ts index aab4efd64..67351639d 100644 --- a/server/src/utils/maintenanceWindow.ts +++ b/server/src/utils/maintenanceWindow.ts @@ -1,4 +1,4 @@ -import type { MaintenanceWindow } from "@/types/index.js"; +import type { MaintenanceWindow } from "@/domain/maintenance-windows/maintenance-window.type.js"; export const isWindowActive = (window: MaintenanceWindow, now: Date = new Date()): boolean => { if (!window.active) { From abec4e6c709b70178c5c8b20117767119daf92ce Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Tue, 9 Jun 2026 12:34:30 -0700 Subject: [PATCH 09/14] update tests --- .../test/helpers/InMemoryIncidentsRepository.ts | 4 ++-- .../test/helpers/InMemoryMonitorsRepository.ts | 5 +++-- server/test/helpers/heartbeatTestHarness.ts | 12 ++++++------ server/test/helpers/makeStatusPage.ts | 2 +- server/test/helpers/notificationMessage.ts | 4 ++-- .../test/helpers/notificationProviderContract.ts | 6 +++--- server/test/helpers/statusProviderContract.ts | 4 ++-- .../integration/heartbeatJobMaintenance.test.ts | 2 +- .../test/integration/incidentLifecycle.test.ts | 11 ++++++----- .../unit/controllers/statusPageThemeFlag.test.ts | 4 ++-- .../providers/network/advancedMatcher.test.ts | 4 ++-- .../unit/providers/network/dnsProvider.test.ts | 6 +++--- .../providers/network/dockerProvider.test.ts | 6 +++--- .../unit/providers/network/gameProvider.test.ts | 6 +++--- .../unit/providers/network/grpcProvider.test.ts | 4 ++-- .../providers/network/hardwareProvider.test.ts | 6 +++--- .../unit/providers/network/httpProvider.test.ts | 6 +++--- .../providers/network/pageSpeedProvider.test.ts | 8 ++++---- .../unit/providers/network/pingProvider.test.ts | 4 ++-- .../unit/providers/network/portProvider.test.ts | 6 +++--- server/test/unit/providers/network/utils.test.ts | 2 +- .../providers/network/webSocketProvider.test.ts | 6 +++--- .../notifications/discordProvider.test.ts | 2 +- .../notifications/emailProvider.test.ts | 4 ++-- .../notifications/matrixProvider.test.ts | 2 +- .../notifications/notificationUtils.test.ts | 4 ++-- .../providers/notifications/ntfyProvider.test.ts | 2 +- .../notifications/pagerdutyProvider.test.ts | 2 +- .../notifications/pushoverProvider.test.ts | 2 +- .../notifications/slackProvider.test.ts | 2 +- .../notifications/teamsProvider.test.ts | 6 +++--- .../notifications/telegramProvider.test.ts | 2 +- .../notifications/twilioProvider.test.ts | 2 +- .../notifications/webhookProvider.test.ts | 2 +- server/test/unit/services/bufferService.test.ts | 11 ++++++----- server/test/unit/services/checkService.test.ts | 7 ++++--- .../test/unit/services/diagnosticService.test.ts | 4 ++-- server/test/unit/services/emailService.test.ts | 6 +++--- .../test/unit/services/geoChecksService.test.ts | 6 +++--- .../test/unit/services/globalPingService.test.ts | 4 ++-- .../test/unit/services/incidentService.test.ts | 14 ++++++++------ server/test/unit/services/inviteService.test.ts | 5 +++-- .../test/unit/services/lessSimpleQueue.test.ts | 4 ++-- .../services/maintenanceWindowService.test.ts | 8 ++++---- server/test/unit/services/monitorService.test.ts | 16 +++++++--------- server/test/unit/services/networkService.test.ts | 8 ++++---- .../services/notificationMessageBuilder.test.ts | 7 ++++--- .../unit/services/notificationsService.test.ts | 8 +++++--- .../test/unit/services/settingsService.test.ts | 8 ++++---- .../test/unit/services/statusPageService.test.ts | 10 +++++----- server/test/unit/services/statusService.test.ts | 14 +++++++++----- .../test/unit/services/superSimpleQueue.test.ts | 4 ++-- .../unit/services/superSimpleQueueHelper.test.ts | 4 ++-- server/test/unit/services/tagsService.test.ts | 4 ++-- server/test/unit/services/userService.test.ts | 4 ++-- server/test/unit/utils/maintenanceWindow.test.ts | 2 +- .../maintenanceWindowValidation.test.ts | 2 +- .../unit/validation/monitorValidation.test.ts | 6 +++++- .../test/unit/validation/userValidation.test.ts | 2 +- 59 files changed, 167 insertions(+), 151 deletions(-) diff --git a/server/test/helpers/InMemoryIncidentsRepository.ts b/server/test/helpers/InMemoryIncidentsRepository.ts index f76236f89..74b79e0e3 100644 --- a/server/test/helpers/InMemoryIncidentsRepository.ts +++ b/server/test/helpers/InMemoryIncidentsRepository.ts @@ -1,5 +1,5 @@ -import type { IIncidentsRepository } from "../../src/repositories/incidents/IIncidentsRepository.ts"; -import type { Incident, IncidentSummary } from "../../src/types/index.ts"; +import type { IIncidentsRepository } from "../../src/domain/incidents/incident.repository.interface.ts"; +import type { Incident, IncidentSummary } from "../../src/domain/incidents/incident.type.ts"; import { randomUUID } from "crypto"; export class InMemoryIncidentsRepository implements IIncidentsRepository { diff --git a/server/test/helpers/InMemoryMonitorsRepository.ts b/server/test/helpers/InMemoryMonitorsRepository.ts index 756a7bfb7..c53f270a7 100644 --- a/server/test/helpers/InMemoryMonitorsRepository.ts +++ b/server/test/helpers/InMemoryMonitorsRepository.ts @@ -1,5 +1,6 @@ -import type { IMonitorsRepository, TeamQueryConfig, SummaryConfig } from "../../src/repositories/monitors/IMonitorsRepository.ts"; -import type { Monitor, MonitorsSummary, CheckSnapshot } from "../../src/types/index.ts"; +import type { IMonitorsRepository, TeamQueryConfig, SummaryConfig } from "../../src/domain/monitors/monitor.repository.interface.ts"; +import type { CheckSnapshot } from "../../src/domain/checks/check.type.ts"; +import type { Monitor, MonitorsSummary } from "../../src/domain/monitors/monitor.types.ts"; export class InMemoryMonitorsRepository implements IMonitorsRepository { private monitors: Monitor[] = []; diff --git a/server/test/helpers/heartbeatTestHarness.ts b/server/test/helpers/heartbeatTestHarness.ts index 9b0592afc..46a6fc630 100644 --- a/server/test/helpers/heartbeatTestHarness.ts +++ b/server/test/helpers/heartbeatTestHarness.ts @@ -1,14 +1,14 @@ import { jest } from "@jest/globals"; -import { QueueHelper } from "../../src/service/infrastructure/JobQueues/QueueHelper.ts"; -import { StatusService } from "../../src/service/infrastructure/statusService.ts"; -import { IncidentService } from "../../src/service/business/incidentService.ts"; +import { QueueHelper } from "../../src/service/job-queues/job-queue.helper.ts"; +import { StatusService } from "../../src/service/statusService.ts"; +import { IncidentService } from "../../src/domain/incidents/incident.service.ts"; import { InMemoryMonitorsRepository } from "./InMemoryMonitorsRepository.ts"; import { InMemoryIncidentsRepository } from "./InMemoryIncidentsRepository.ts"; import { createMockLogger } from "./createMockLogger.ts"; -import type { Monitor } from "../../src/types/monitor.ts"; +import type { Monitor } from "../../src/domain/monitors/monitor.types.ts"; import type { MonitorStatusResponse } from "../../src/types/network.ts"; -import type { Check } from "../../src/types/check.ts"; -import type { MaintenanceWindow } from "../../src/types/maintenanceWindow.ts"; +import type { Check } from "../../src/domain/checks/check.type.ts"; +import type { MaintenanceWindow } from "../../src/domain/maintenance-windows/maintenance-window.type.ts"; let checkCounter = 0; diff --git a/server/test/helpers/makeStatusPage.ts b/server/test/helpers/makeStatusPage.ts index 23c13bca1..56fd26596 100644 --- a/server/test/helpers/makeStatusPage.ts +++ b/server/test/helpers/makeStatusPage.ts @@ -1,4 +1,4 @@ -import type { StatusPage } from "../../src/types/index.ts"; +import type { StatusPage } from "../../src/domain/status-pages/status-page.type.ts"; export const makeStatusPage = (overrides?: Partial): StatusPage => ({ diff --git a/server/test/helpers/notificationMessage.ts b/server/test/helpers/notificationMessage.ts index c25644c81..f73ce67e7 100644 --- a/server/test/helpers/notificationMessage.ts +++ b/server/test/helpers/notificationMessage.ts @@ -1,5 +1,5 @@ -import type { Notification } from "../../src/types/index.ts"; -import type { NotificationMessage } from "../../src/types/notificationMessage.ts"; +import type { Notification } from "../../src/domain/notifications/notification.type.ts"; +import type { NotificationMessage } from "../../src/domain/notifications/notification.type.ts"; export const makeNotification = (overrides?: Partial): Notification => ({ diff --git a/server/test/helpers/notificationProviderContract.ts b/server/test/helpers/notificationProviderContract.ts index f95048f24..3f3c5b80b 100644 --- a/server/test/helpers/notificationProviderContract.ts +++ b/server/test/helpers/notificationProviderContract.ts @@ -1,7 +1,7 @@ import { describe, expect, it } from "@jest/globals"; -import type { INotificationProvider } from "../../src/service/infrastructure/notificationProviders/INotificationProvider.ts"; -import type { Notification } from "../../src/types/index.ts"; -import type { NotificationMessage } from "../../src/types/notificationMessage.ts"; +import type { INotificationProvider } from "../../src/domain/notifications/providers/INotificationProvider.ts"; +import type { Notification } from "../../src/domain/notifications/notification.type.ts"; +import type { NotificationMessage } from "../../src/domain/notifications/notification.type.ts"; const makeMessage = (): NotificationMessage => ({ type: "monitor_down", diff --git a/server/test/helpers/statusProviderContract.ts b/server/test/helpers/statusProviderContract.ts index 6f7c89466..af625f64d 100644 --- a/server/test/helpers/statusProviderContract.ts +++ b/server/test/helpers/statusProviderContract.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from "@jest/globals"; -import type { IStatusProvider } from "../../src/service/infrastructure/network/IStatusProvider.ts"; -import type { Monitor } from "../../src/types/index.ts"; +import type { IStatusProvider } from "../../src/service/network/IStatusProvider.ts"; +import type { Monitor } from "../../src/domain/monitors/monitor.types.ts"; /** * Shared contract tests for all IStatusProvider implementations. diff --git a/server/test/integration/heartbeatJobMaintenance.test.ts b/server/test/integration/heartbeatJobMaintenance.test.ts index 5df287242..3e51814db 100644 --- a/server/test/integration/heartbeatJobMaintenance.test.ts +++ b/server/test/integration/heartbeatJobMaintenance.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, beforeEach } from "@jest/globals"; import { createHeartbeatTestHarness, makeMonitor, type HeartbeatTestHarness } from "../helpers/heartbeatTestHarness.ts"; -import type { MaintenanceWindow } from "../../src/types/maintenanceWindow.ts"; +import type { MaintenanceWindow } from "../../src/domain/maintenance-windows/maintenance-window.type.ts"; const makeMaintenanceWindow = (overrides?: Partial): MaintenanceWindow => { const now = new Date(); diff --git a/server/test/integration/incidentLifecycle.test.ts b/server/test/integration/incidentLifecycle.test.ts index 0fe1ddcf8..3f301113a 100644 --- a/server/test/integration/incidentLifecycle.test.ts +++ b/server/test/integration/incidentLifecycle.test.ts @@ -1,11 +1,12 @@ import { describe, expect, it, jest, beforeEach } from "@jest/globals"; -import { IncidentService } from "../../src/service/business/incidentService.ts"; +import { IncidentService } from "../../src/domain/incidents/incident.service.ts"; import { InMemoryIncidentsRepository } from "../helpers/InMemoryIncidentsRepository.ts"; import { createMockLogger } from "../helpers/createMockLogger.ts"; -import type { IMonitorsRepository, IUsersRepository } from "../../src/repositories/index.ts"; -import type { INotificationMessageBuilder } from "../../src/service/infrastructure/notificationMessageBuilder.ts"; -import type { Monitor } from "../../src/types/monitor.ts"; -import type { MonitorActionDecision } from "../../src/service/infrastructure/JobQueues/QueueHelper.ts"; +import type { IMonitorsRepository } from "../../src/domain/monitors/monitor.repository.interface.ts"; +import type { IUsersRepository } from "../../src/domain/users/user.repository.interface.ts"; +import type { INotificationMessageBuilder } from "../../src/domain/notifications/notification.message-builder.ts"; +import type { Monitor } from "../../src/domain/monitors/monitor.types.ts"; +import type { MonitorActionDecision } from "../../src/service/job-queues/job-queue.helper.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/controllers/statusPageThemeFlag.test.ts b/server/test/unit/controllers/statusPageThemeFlag.test.ts index b4f9435a9..b1d51361a 100644 --- a/server/test/unit/controllers/statusPageThemeFlag.test.ts +++ b/server/test/unit/controllers/statusPageThemeFlag.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from "@jest/globals"; -import { applyDefaultTheme, withoutThemeFields } from "../../../src/controllers/statusPageThemeFlag.ts"; -import { DEFAULT_STATUS_PAGE_THEME, DEFAULT_STATUS_PAGE_THEME_MODE } from "../../../src/types/statusPage.ts"; +import { applyDefaultTheme, withoutThemeFields } from "../../../src/api/controllers/statusPageThemeFlag.ts"; +import { DEFAULT_STATUS_PAGE_THEME, DEFAULT_STATUS_PAGE_THEME_MODE } from "../../../src/domain/status-pages/status-page.type.ts"; import { makeStatusPage } from "../../helpers/makeStatusPage.ts"; describe("statusPageThemeFlag", () => { diff --git a/server/test/unit/providers/network/advancedMatcher.test.ts b/server/test/unit/providers/network/advancedMatcher.test.ts index e0b2c773c..f94e9bb53 100644 --- a/server/test/unit/providers/network/advancedMatcher.test.ts +++ b/server/test/unit/providers/network/advancedMatcher.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, jest } from "@jest/globals"; -import { AdvancedMatcher } from "../../../../src/service/infrastructure/network/AdvancedMatcher.ts"; -import type { Monitor } from "../../../../src/types/index.ts"; +import { AdvancedMatcher } from "../../../../src/service/network/AdvancedMatcher.ts"; +import type { Monitor } from "../../../../src/domain/monitors/monitor.types.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/providers/network/dnsProvider.test.ts b/server/test/unit/providers/network/dnsProvider.test.ts index a96731be5..1c31b3b1d 100644 --- a/server/test/unit/providers/network/dnsProvider.test.ts +++ b/server/test/unit/providers/network/dnsProvider.test.ts @@ -1,8 +1,8 @@ import { beforeEach, describe, expect, it, jest } from "@jest/globals"; import { testStatusProviderContract } from "../../../helpers/statusProviderContract.ts"; -import { NETWORK_ERROR } from "../../../../src/service/infrastructure/network/utils.ts"; -import type { Monitor } from "../../../../src/types/index.ts"; -import { DNSProvider } from "../../../../src/service/infrastructure/network/DNSProvider.ts"; +import { NETWORK_ERROR } from "../../../../src/service/network/utils.ts"; +import type { Monitor } from "../../../../src/domain/monitors/monitor.types.ts"; +import { DNSProvider } from "../../../../src/service/network/DNSProvider.ts"; // ── Mocks ──────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/providers/network/dockerProvider.test.ts b/server/test/unit/providers/network/dockerProvider.test.ts index 0f3dd68f6..f0b743f16 100644 --- a/server/test/unit/providers/network/dockerProvider.test.ts +++ b/server/test/unit/providers/network/dockerProvider.test.ts @@ -1,9 +1,9 @@ import { describe, expect, it, jest } from "@jest/globals"; -import { DockerProvider } from "../../../../src/service/infrastructure/network/DockerProvider.ts"; +import { DockerProvider } from "../../../../src/service/network/DockerProvider.ts"; import { testStatusProviderContract } from "../../../helpers/statusProviderContract.ts"; import { createMockLogger } from "../../../helpers/createMockLogger.ts"; -import { NETWORK_ERROR } from "../../../../src/service/infrastructure/network/utils.ts"; -import type { Monitor } from "../../../../src/types/index.ts"; +import { NETWORK_ERROR } from "../../../../src/service/network/utils.ts"; +import type { Monitor } from "../../../../src/domain/monitors/monitor.types.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/providers/network/gameProvider.test.ts b/server/test/unit/providers/network/gameProvider.test.ts index d34e99621..d166c30f3 100644 --- a/server/test/unit/providers/network/gameProvider.test.ts +++ b/server/test/unit/providers/network/gameProvider.test.ts @@ -1,9 +1,9 @@ import { describe, expect, it, jest } from "@jest/globals"; -import { GameProvider } from "../../../../src/service/infrastructure/network/GameProvider.ts"; +import { GameProvider } from "../../../../src/service/network/GameProvider.ts"; import { testStatusProviderContract } from "../../../helpers/statusProviderContract.ts"; import { createMockLogger } from "../../../helpers/createMockLogger.ts"; -import { NETWORK_ERROR } from "../../../../src/service/infrastructure/network/utils.ts"; -import type { Monitor } from "../../../../src/types/index.ts"; +import { NETWORK_ERROR } from "../../../../src/service/network/utils.ts"; +import type { Monitor } from "../../../../src/domain/monitors/monitor.types.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/providers/network/grpcProvider.test.ts b/server/test/unit/providers/network/grpcProvider.test.ts index efa2e7992..bb1c78aac 100644 --- a/server/test/unit/providers/network/grpcProvider.test.ts +++ b/server/test/unit/providers/network/grpcProvider.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it, jest } from "@jest/globals"; -import { GrpcProvider } from "../../../../src/service/infrastructure/network/GrpcProvider.ts"; +import { GrpcProvider } from "../../../../src/service/network/GrpcProvider.ts"; import { testStatusProviderContract } from "../../../helpers/statusProviderContract.ts"; -import type { Monitor } from "../../../../src/types/index.ts"; +import type { Monitor } from "../../../../src/domain/monitors/monitor.types.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/providers/network/hardwareProvider.test.ts b/server/test/unit/providers/network/hardwareProvider.test.ts index 2f51454a0..2b4583af9 100644 --- a/server/test/unit/providers/network/hardwareProvider.test.ts +++ b/server/test/unit/providers/network/hardwareProvider.test.ts @@ -1,8 +1,8 @@ import { describe, expect, it, jest } from "@jest/globals"; -import { HardwareProvider } from "../../../../src/service/infrastructure/network/HardwareProvider.ts"; +import { HardwareProvider } from "../../../../src/service/network/HardwareProvider.ts"; import { testStatusProviderContract } from "../../../helpers/statusProviderContract.ts"; -import type { HttpProvider } from "../../../../src/service/infrastructure/network/HttpProvider.ts"; -import type { Monitor } from "../../../../src/types/index.ts"; +import type { HttpProvider } from "../../../../src/service/network/HttpProvider.ts"; +import type { Monitor } from "../../../../src/domain/monitors/monitor.types.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/providers/network/httpProvider.test.ts b/server/test/unit/providers/network/httpProvider.test.ts index 1addcba6f..10b66a93a 100644 --- a/server/test/unit/providers/network/httpProvider.test.ts +++ b/server/test/unit/providers/network/httpProvider.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it, jest } from "@jest/globals"; import { testStatusProviderContract } from "../../../helpers/statusProviderContract.ts"; -import { NETWORK_ERROR } from "../../../../src/service/infrastructure/network/utils.ts"; -import type { Monitor } from "../../../../src/types/index.ts"; +import { NETWORK_ERROR } from "../../../../src/service/network/utils.ts"; +import type { Monitor } from "../../../../src/domain/monitors/monitor.types.ts"; // ── Mocks ──────────────────────────────────────────────────────────────────── @@ -38,7 +38,7 @@ jest.unstable_mockModule("got", () => ({ }, })); -const { HttpProvider } = await import("../../../../src/service/infrastructure/network/HttpProvider.ts"); +const { HttpProvider } = await import("../../../../src/service/network/HttpProvider.ts"); const gotModule = await import("got"); const { HTTPError, RequestError } = gotModule; diff --git a/server/test/unit/providers/network/pageSpeedProvider.test.ts b/server/test/unit/providers/network/pageSpeedProvider.test.ts index c461b0ad2..df5beb0be 100644 --- a/server/test/unit/providers/network/pageSpeedProvider.test.ts +++ b/server/test/unit/providers/network/pageSpeedProvider.test.ts @@ -1,10 +1,10 @@ import { describe, expect, it, jest } from "@jest/globals"; -import { PageSpeedProvider } from "../../../../src/service/infrastructure/network/PageSpeedProvider.ts"; +import { PageSpeedProvider } from "../../../../src/service/network/PageSpeedProvider.ts"; import { testStatusProviderContract } from "../../../helpers/statusProviderContract.ts"; import { createMockLogger } from "../../../helpers/createMockLogger.ts"; -import type { HttpProvider } from "../../../../src/service/infrastructure/network/HttpProvider.ts"; -import type { ISettingsService } from "../../../../src/service/system/settingsService.ts"; -import type { Monitor } from "../../../../src/types/index.ts"; +import type { HttpProvider } from "../../../../src/service/network/HttpProvider.ts"; +import type { ISettingsService } from "../../../../src/domain/app-settings/app-settings.service.ts"; +import type { Monitor } from "../../../../src/domain/monitors/monitor.types.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/providers/network/pingProvider.test.ts b/server/test/unit/providers/network/pingProvider.test.ts index 2f38eef00..8f006a470 100644 --- a/server/test/unit/providers/network/pingProvider.test.ts +++ b/server/test/unit/providers/network/pingProvider.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it, jest } from "@jest/globals"; -import { PingProvider } from "../../../../src/service/infrastructure/network/PingProvider.ts"; +import { PingProvider } from "../../../../src/service/network/PingProvider.ts"; import { testStatusProviderContract } from "../../../helpers/statusProviderContract.ts"; -import type { Monitor } from "../../../../src/types/index.ts"; +import type { Monitor } from "../../../../src/domain/monitors/monitor.types.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/providers/network/portProvider.test.ts b/server/test/unit/providers/network/portProvider.test.ts index cbf64af16..8a7d55c4c 100644 --- a/server/test/unit/providers/network/portProvider.test.ts +++ b/server/test/unit/providers/network/portProvider.test.ts @@ -1,8 +1,8 @@ import { describe, expect, it, jest } from "@jest/globals"; -import { PortProvider } from "../../../../src/service/infrastructure/network/PortProvider.ts"; +import { PortProvider } from "../../../../src/service/network/PortProvider.ts"; import { testStatusProviderContract } from "../../../helpers/statusProviderContract.ts"; -import { NETWORK_ERROR } from "../../../../src/service/infrastructure/network/utils.ts"; -import type { Monitor } from "../../../../src/types/index.ts"; +import { NETWORK_ERROR } from "../../../../src/service/network/utils.ts"; +import type { Monitor } from "../../../../src/domain/monitors/monitor.types.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/providers/network/utils.test.ts b/server/test/unit/providers/network/utils.test.ts index 84427152e..b37a5597c 100644 --- a/server/test/unit/providers/network/utils.test.ts +++ b/server/test/unit/providers/network/utils.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "@jest/globals"; -import { timeRequest, NETWORK_ERROR, PING_ERROR, isStatusUp } from "../../../../src/service/infrastructure/network/utils.ts"; +import { timeRequest, NETWORK_ERROR, PING_ERROR, isStatusUp } from "../../../../src/service/network/utils.ts"; describe("network utils", () => { describe("timeRequest", () => { diff --git a/server/test/unit/providers/network/webSocketProvider.test.ts b/server/test/unit/providers/network/webSocketProvider.test.ts index 73e4416a1..12ff32d63 100644 --- a/server/test/unit/providers/network/webSocketProvider.test.ts +++ b/server/test/unit/providers/network/webSocketProvider.test.ts @@ -1,8 +1,8 @@ import { describe, expect, it, jest, beforeEach, afterEach } from "@jest/globals"; -import { WebSocketProvider } from "../../../../src/service/infrastructure/network/WebSocketProvider.ts"; +import { WebSocketProvider } from "../../../../src/service/network/WebSocketProvider.ts"; import { testStatusProviderContract } from "../../../helpers/statusProviderContract.ts"; -import { NETWORK_ERROR } from "../../../../src/service/infrastructure/network/utils.ts"; -import type { Monitor } from "../../../../src/types/index.ts"; +import { NETWORK_ERROR } from "../../../../src/service/network/utils.ts"; +import type { Monitor } from "../../../../src/domain/monitors/monitor.types.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/providers/notifications/discordProvider.test.ts b/server/test/unit/providers/notifications/discordProvider.test.ts index 28c30ed22..bdb431fce 100644 --- a/server/test/unit/providers/notifications/discordProvider.test.ts +++ b/server/test/unit/providers/notifications/discordProvider.test.ts @@ -6,7 +6,7 @@ import { testNotificationProviderContract } from "../../../helpers/notificationP const mockGotPost = jest.fn().mockResolvedValue({}); jest.unstable_mockModule("got", () => ({ default: { post: mockGotPost } })); -const { DiscordProvider } = await import("../../../../src/service/infrastructure/notificationProviders/discord.ts"); +const { DiscordProvider } = await import("../../../../src/domain/notifications/providers/discord.ts"); const createProvider = () => { const logger = createMockLogger(); diff --git a/server/test/unit/providers/notifications/emailProvider.test.ts b/server/test/unit/providers/notifications/emailProvider.test.ts index e0dc8b676..fecce8ef6 100644 --- a/server/test/unit/providers/notifications/emailProvider.test.ts +++ b/server/test/unit/providers/notifications/emailProvider.test.ts @@ -1,9 +1,9 @@ import { describe, expect, it, jest, beforeEach } from "@jest/globals"; -import { EmailProvider } from "../../../../src/service/infrastructure/notificationProviders/email.ts"; +import { EmailProvider } from "../../../../src/domain/notifications/providers/email.ts"; import { createMockLogger } from "../../../helpers/createMockLogger.ts"; import { makeNotification, makeMessage } from "../../../helpers/notificationMessage.ts"; import { testNotificationProviderContract } from "../../../helpers/notificationProviderContract.ts"; -import type { IEmailService } from "../../../../src/service/infrastructure/emailService.ts"; +import type { IEmailService } from "../../../../src/service/emailService.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/providers/notifications/matrixProvider.test.ts b/server/test/unit/providers/notifications/matrixProvider.test.ts index f6ad36692..65305e731 100644 --- a/server/test/unit/providers/notifications/matrixProvider.test.ts +++ b/server/test/unit/providers/notifications/matrixProvider.test.ts @@ -7,7 +7,7 @@ const mockGotPut = jest.fn().mockResolvedValue({}); jest.unstable_mockModule("got", () => ({ default: { put: mockGotPut } })); jest.unstable_mockModule("crypto", () => ({ randomUUID: () => "test-uuid-1234" })); -const { MatrixProvider } = await import("../../../../src/service/infrastructure/notificationProviders/matrix.ts"); +const { MatrixProvider } = await import("../../../../src/domain/notifications/providers/matrix.ts"); const createProvider = () => { const logger = createMockLogger(); diff --git a/server/test/unit/providers/notifications/notificationUtils.test.ts b/server/test/unit/providers/notifications/notificationUtils.test.ts index 53a2666c8..5118e570e 100644 --- a/server/test/unit/providers/notifications/notificationUtils.test.ts +++ b/server/test/unit/providers/notifications/notificationUtils.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, jest } from "@jest/globals"; -import { buildTestEmail, getTestMessage } from "../../../../src/service/infrastructure/notificationProviders/utils.ts"; -import type { IEmailService } from "../../../../src/service/infrastructure/emailService.ts"; +import { buildTestEmail, getTestMessage } from "../../../../src/domain/notifications/providers/utils.ts"; +import type { IEmailService } from "../../../../src/service/emailService.ts"; describe("notification utils", () => { describe("getTestMessage", () => { diff --git a/server/test/unit/providers/notifications/ntfyProvider.test.ts b/server/test/unit/providers/notifications/ntfyProvider.test.ts index d335b5d01..ffd95a0d7 100644 --- a/server/test/unit/providers/notifications/ntfyProvider.test.ts +++ b/server/test/unit/providers/notifications/ntfyProvider.test.ts @@ -6,7 +6,7 @@ import { testNotificationProviderContract } from "../../../helpers/notificationP const mockGotPost = jest.fn().mockResolvedValue({}); jest.unstable_mockModule("got", () => ({ default: { post: mockGotPost } })); -const { NtfyProvider } = await import("../../../../src/service/infrastructure/notificationProviders/ntfy.ts"); +const { NtfyProvider } = await import("../../../../src/domain/notifications/providers/ntfy.ts"); const createProvider = () => { const logger = createMockLogger(); diff --git a/server/test/unit/providers/notifications/pagerdutyProvider.test.ts b/server/test/unit/providers/notifications/pagerdutyProvider.test.ts index f7c9c04c8..8b8d185b4 100644 --- a/server/test/unit/providers/notifications/pagerdutyProvider.test.ts +++ b/server/test/unit/providers/notifications/pagerdutyProvider.test.ts @@ -6,7 +6,7 @@ import { testNotificationProviderContract } from "../../../helpers/notificationP const mockGotPost = jest.fn().mockResolvedValue({}); jest.unstable_mockModule("got", () => ({ default: { post: mockGotPost } })); -const { PagerDutyProvider } = await import("../../../../src/service/infrastructure/notificationProviders/pagerduty.ts"); +const { PagerDutyProvider } = await import("../../../../src/domain/notifications/providers/pagerduty.ts"); const createProvider = () => { const logger = createMockLogger(); diff --git a/server/test/unit/providers/notifications/pushoverProvider.test.ts b/server/test/unit/providers/notifications/pushoverProvider.test.ts index 8d32573b5..a227b0b1b 100644 --- a/server/test/unit/providers/notifications/pushoverProvider.test.ts +++ b/server/test/unit/providers/notifications/pushoverProvider.test.ts @@ -6,7 +6,7 @@ import { testNotificationProviderContract } from "../../../helpers/notificationP const mockGotPost = jest.fn().mockResolvedValue({}); jest.unstable_mockModule("got", () => ({ default: { post: mockGotPost } })); -const { PushoverProvider } = await import("../../../../src/service/infrastructure/notificationProviders/pushover.ts"); +const { PushoverProvider } = await import("../../../../src/domain/notifications/providers/pushover.ts"); const createProvider = () => { const logger = createMockLogger(); diff --git a/server/test/unit/providers/notifications/slackProvider.test.ts b/server/test/unit/providers/notifications/slackProvider.test.ts index 232eccaaa..20058ab11 100644 --- a/server/test/unit/providers/notifications/slackProvider.test.ts +++ b/server/test/unit/providers/notifications/slackProvider.test.ts @@ -6,7 +6,7 @@ import { testNotificationProviderContract } from "../../../helpers/notificationP const mockGotPost = jest.fn().mockResolvedValue({}); jest.unstable_mockModule("got", () => ({ default: { post: mockGotPost }, HTTPError: class extends Error {} })); -const { SlackProvider } = await import("../../../../src/service/infrastructure/notificationProviders/slack.ts"); +const { SlackProvider } = await import("../../../../src/domain/notifications/providers/slack.ts"); const createProvider = () => { const logger = createMockLogger(); diff --git a/server/test/unit/providers/notifications/teamsProvider.test.ts b/server/test/unit/providers/notifications/teamsProvider.test.ts index d27d396a9..c3766ec16 100644 --- a/server/test/unit/providers/notifications/teamsProvider.test.ts +++ b/server/test/unit/providers/notifications/teamsProvider.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, jest, beforeEach } from "@jest/globals"; -import type { Notification } from "../../../../src/types/notification.ts"; -import type { NotificationMessage } from "../../../../src/types/notificationMessage.ts"; +import type { Notification } from "../../../../src/domain/notifications/notification.type.ts"; +import type { NotificationMessage } from "../../../../src/domain/notifications/notification.type.ts"; import { createMockLogger } from "../../../helpers/createMockLogger.ts"; const mockPost = jest.fn(); @@ -9,7 +9,7 @@ jest.unstable_mockModule("got", () => ({ HTTPError: class HTTPError extends Error {}, })); -const { TeamsProvider } = await import("../../../../src/service/infrastructure/notificationProviders/teams.ts"); +const { TeamsProvider } = await import("../../../../src/domain/notifications/providers/teams.ts"); const createNotification = (overrides?: Partial): Notification => ({ id: "notif-1", diff --git a/server/test/unit/providers/notifications/telegramProvider.test.ts b/server/test/unit/providers/notifications/telegramProvider.test.ts index fe9dd2c2e..f8f853e62 100644 --- a/server/test/unit/providers/notifications/telegramProvider.test.ts +++ b/server/test/unit/providers/notifications/telegramProvider.test.ts @@ -6,7 +6,7 @@ import { testNotificationProviderContract } from "../../../helpers/notificationP const mockGotPost = jest.fn().mockResolvedValue({}); jest.unstable_mockModule("got", () => ({ default: { post: mockGotPost } })); -const { TelegramProvider } = await import("../../../../src/service/infrastructure/notificationProviders/telegram.ts"); +const { TelegramProvider } = await import("../../../../src/domain/notifications/providers/telegram.ts"); const createProvider = () => { const logger = createMockLogger(); diff --git a/server/test/unit/providers/notifications/twilioProvider.test.ts b/server/test/unit/providers/notifications/twilioProvider.test.ts index 88bfcdf7e..896a23395 100644 --- a/server/test/unit/providers/notifications/twilioProvider.test.ts +++ b/server/test/unit/providers/notifications/twilioProvider.test.ts @@ -6,7 +6,7 @@ import { testNotificationProviderContract } from "../../../helpers/notificationP const mockGotPost = jest.fn().mockResolvedValue({}); jest.unstable_mockModule("got", () => ({ default: { post: mockGotPost } })); -const { TwilioProvider } = await import("../../../../src/service/infrastructure/notificationProviders/twilio.ts"); +const { TwilioProvider } = await import("../../../../src/domain/notifications/providers/twilio.ts"); const createProvider = () => { const logger = createMockLogger(); diff --git a/server/test/unit/providers/notifications/webhookProvider.test.ts b/server/test/unit/providers/notifications/webhookProvider.test.ts index caf17851b..fd16f2c06 100644 --- a/server/test/unit/providers/notifications/webhookProvider.test.ts +++ b/server/test/unit/providers/notifications/webhookProvider.test.ts @@ -6,7 +6,7 @@ import { testNotificationProviderContract } from "../../../helpers/notificationP const mockGotPost = jest.fn().mockResolvedValue({}); jest.unstable_mockModule("got", () => ({ default: { post: mockGotPost } })); -const { WebhookProvider } = await import("../../../../src/service/infrastructure/notificationProviders/webhook.ts"); +const { WebhookProvider } = await import("../../../../src/domain/notifications/providers/webhook.ts"); const createProvider = () => { const logger = createMockLogger(); diff --git a/server/test/unit/services/bufferService.test.ts b/server/test/unit/services/bufferService.test.ts index f1f395e2d..5a6418c70 100644 --- a/server/test/unit/services/bufferService.test.ts +++ b/server/test/unit/services/bufferService.test.ts @@ -1,10 +1,11 @@ import { describe, expect, it, jest, beforeEach, afterEach } from "@jest/globals"; -import { BufferService } from "../../../src/service/infrastructure/bufferService.ts"; +import { BufferService } from "../../../src/service/bufferService.ts"; import { createMockLogger } from "../../helpers/createMockLogger.ts"; -import type { ICheckService } from "../../../src/service/business/checkService.ts"; -import type { IGeoChecksService } from "../../../src/service/business/geoChecksService.ts"; -import type { ISettingsService } from "../../../src/service/system/settingsService.ts"; -import type { Check, GeoCheck } from "../../../src/types/index.ts"; +import type { ICheckService } from "../../../src/domain/checks/check.service.ts"; +import type { IGeoChecksService } from "../../../src/domain/geo-checks/geo-check.service.ts"; +import type { ISettingsService } from "../../../src/domain/app-settings/app-settings.service.ts"; +import type { Check } from "../../../src/domain/checks/check.type.ts"; +import type { GeoCheck } from "../../../src/domain/geo-checks/geo-check.type.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/services/checkService.test.ts b/server/test/unit/services/checkService.test.ts index 93919df5f..b658c78da 100644 --- a/server/test/unit/services/checkService.test.ts +++ b/server/test/unit/services/checkService.test.ts @@ -1,8 +1,9 @@ import { describe, expect, it, jest } from "@jest/globals"; -import { CheckService } from "../../../src/service/business/checkService.ts"; +import { CheckService } from "../../../src/domain/checks/check.service.ts"; import { createMockLogger } from "../../helpers/createMockLogger.ts"; -import type { IChecksRepository, IMonitorsRepository } from "../../../src/repositories/index.ts"; -import type { MonitorStatusResponse, HardwareStatusPayload, PageSpeedStatusPayload } from "../../../src/types/index.ts"; +import type { IChecksRepository } from "../../../src/domain/checks/check.repository.interface.ts"; +import type { IMonitorsRepository } from "../../../src/domain/monitors/monitor.repository.interface.ts"; +import type { MonitorStatusResponse, HardwareStatusPayload, PageSpeedStatusPayload } from "../../../src/types/network.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/services/diagnosticService.test.ts b/server/test/unit/services/diagnosticService.test.ts index 402c0c527..b44de1986 100644 --- a/server/test/unit/services/diagnosticService.test.ts +++ b/server/test/unit/services/diagnosticService.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, jest, beforeEach, afterEach } from "@jest/globals"; -import { DiagnosticService } from "../../../src/service/business/diagnosticService.ts"; -import type { IDb } from "../../../src/db/IDb.ts"; +import { DiagnosticService } from "../../../src/domain/diagnostics/diagnostic.service.ts"; +import type { IDb } from "../../../src/db/db.interface.ts"; import type { Mongoose } from "mongoose"; // ── Test helpers ───────────────────────────────────────────────────────────── diff --git a/server/test/unit/services/emailService.test.ts b/server/test/unit/services/emailService.test.ts index d4d275ad8..fbfdf15fd 100644 --- a/server/test/unit/services/emailService.test.ts +++ b/server/test/unit/services/emailService.test.ts @@ -1,8 +1,8 @@ import { describe, expect, it, jest, beforeEach } from "@jest/globals"; -import { EmailService } from "../../../src/service/infrastructure/emailService.ts"; +import { EmailService } from "../../../src/service/emailService.ts"; import { createMockLogger } from "../../helpers/createMockLogger.ts"; -import type { ISettingsService } from "../../../src/service/system/settingsService.ts"; -import type { EmailTransportConfig } from "../../../src/types/index.ts"; +import type { ISettingsService } from "../../../src/domain/app-settings/app-settings.service.ts"; +import type { EmailTransportConfig } from "../../../src/domain/app-settings/app-settings.type.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/services/geoChecksService.test.ts b/server/test/unit/services/geoChecksService.test.ts index ab03d319e..8e50fa3e8 100644 --- a/server/test/unit/services/geoChecksService.test.ts +++ b/server/test/unit/services/geoChecksService.test.ts @@ -1,8 +1,8 @@ import { describe, expect, it, jest } from "@jest/globals"; -import { GeoChecksService } from "../../../src/service/business/geoChecksService.ts"; +import { GeoChecksService } from "../../../src/domain/geo-checks/geo-check.service.ts"; import { createMockLogger } from "../../helpers/createMockLogger.ts"; -import type { Monitor } from "../../../src/types/index.ts"; -import type { GeoCheckResult } from "../../../src/types/geoCheck.ts"; +import type { Monitor } from "../../../src/domain/monitors/monitor.types.ts"; +import type { GeoCheckResult } from "../../../src/domain/geo-checks/geo-check.type.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/services/globalPingService.test.ts b/server/test/unit/services/globalPingService.test.ts index 78d195b0f..376653110 100644 --- a/server/test/unit/services/globalPingService.test.ts +++ b/server/test/unit/services/globalPingService.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, jest, beforeEach, afterEach } from "@jest/globals"; import { createMockLogger } from "../../helpers/createMockLogger.ts"; -import type { GeoContinent } from "../../../src/types/geoCheck.ts"; +import type { GeoContinent } from "../../../src/domain/geo-checks/geo-check.type.ts"; // ── got mock ───────────────────────────────────────────────────────────────── @@ -15,7 +15,7 @@ jest.unstable_mockModule("got", () => ({ })); // Dynamic import AFTER mock registration -const { GlobalPingService } = await import("../../../src/service/infrastructure/globalPingService.ts"); +const { GlobalPingService } = await import("../../../src/service/globalPingService.ts"); // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/services/incidentService.test.ts b/server/test/unit/services/incidentService.test.ts index 4274f67d8..f62f4ccf4 100644 --- a/server/test/unit/services/incidentService.test.ts +++ b/server/test/unit/services/incidentService.test.ts @@ -1,11 +1,13 @@ import { describe, expect, it, jest, beforeEach } from "@jest/globals"; -import { IncidentService } from "../../../src/service/business/incidentService.ts"; +import { IncidentService } from "../../../src/domain/incidents/incident.service.ts"; import { createMockLogger } from "../../helpers/createMockLogger.ts"; -import type { IIncidentsRepository, IMonitorsRepository, IUsersRepository } from "../../../src/repositories/index.ts"; -import type { INotificationMessageBuilder } from "../../../src/service/infrastructure/notificationMessageBuilder.ts"; -import type { Monitor } from "../../../src/types/monitor.ts"; -import type { Incident } from "../../../src/types/index.ts"; -import type { MonitorActionDecision } from "../../../src/service/infrastructure/JobQueues/QueueHelper.ts"; +import type { IIncidentsRepository } from "../../../src/domain/incidents/incident.repository.interface.ts"; +import type { IMonitorsRepository } from "../../../src/domain/monitors/monitor.repository.interface.ts"; +import type { IUsersRepository } from "../../../src/domain/users/user.repository.interface.ts"; +import type { INotificationMessageBuilder } from "../../../src/domain/notifications/notification.message-builder.ts"; +import type { Monitor } from "../../../src/domain/monitors/monitor.types.ts"; +import type { Incident } from "../../../src/domain/incidents/incident.type.ts"; +import type { MonitorActionDecision } from "../../../src/service/job-queues/job-queue.helper.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/services/inviteService.test.ts b/server/test/unit/services/inviteService.test.ts index da29d1834..c050d91e6 100644 --- a/server/test/unit/services/inviteService.test.ts +++ b/server/test/unit/services/inviteService.test.ts @@ -1,6 +1,7 @@ import { describe, expect, it, jest } from "@jest/globals"; -import { InviteService } from "../../../src/service/business/inviteService.ts"; -import type { Invite, UserRole } from "../../../src/types/index.ts"; +import { InviteService } from "../../../src/domain/invites/invite.service.ts"; +import type { Invite } from "../../../src/domain/invites/invite.type.ts"; +import type { UserRole } from "../../../src/domain/users/user.type.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/services/lessSimpleQueue.test.ts b/server/test/unit/services/lessSimpleQueue.test.ts index 6351dc5d5..b43383825 100644 --- a/server/test/unit/services/lessSimpleQueue.test.ts +++ b/server/test/unit/services/lessSimpleQueue.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, jest } from "@jest/globals"; import { createMockLogger } from "../../helpers/createMockLogger.ts"; -import type { Monitor } from "../../../src/types/monitor.ts"; +import type { Monitor } from "../../../src/domain/monitors/monitor.types.ts"; // ── Mock Scheduler / MongoStore ────────────────────────────────────────────── @@ -44,7 +44,7 @@ jest.unstable_mockModule("less-simple-scheduler", () => ({ MongoStore: MockMongoStore, })); -const { LessSimpleQueue } = await import("../../../src/service/infrastructure/JobQueues/LessSimpleQueue.ts"); +const { LessSimpleQueue } = await import("../../../src/service/job-queues/job-queue.less-simple.ts"); const createQueueHelper = () => ({ getHeartbeatJob: jest.fn().mockReturnValue(() => Promise.resolve()), diff --git a/server/test/unit/services/maintenanceWindowService.test.ts b/server/test/unit/services/maintenanceWindowService.test.ts index 376b8f20d..9d381ae74 100644 --- a/server/test/unit/services/maintenanceWindowService.test.ts +++ b/server/test/unit/services/maintenanceWindowService.test.ts @@ -1,8 +1,8 @@ import { describe, expect, it, jest } from "@jest/globals"; -import { MaintenanceWindowService } from "../../../src/service/business/maintenanceWindowService.ts"; -import type { IMaintenanceWindowsRepository } from "../../../src/repositories/maintenance-windows/IMaintenanceWindowsRepository.ts"; -import type { IMonitorsRepository } from "../../../src/repositories/monitors/IMonitorsRepository.ts"; -import type { MaintenanceWindow } from "../../../src/types/index.ts"; +import { MaintenanceWindowService } from "../../../src/domain/maintenance-windows/maintenance-window.service.ts"; +import type { IMaintenanceWindowsRepository } from "../../../src/domain/maintenance-windows/maintenance-window.repository.interface.ts"; +import type { IMonitorsRepository } from "../../../src/domain/monitors/monitor.repository.interface.ts"; +import type { MaintenanceWindow } from "../../../src/domain/maintenance-windows/maintenance-window.type.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/services/monitorService.test.ts b/server/test/unit/services/monitorService.test.ts index a21967de8..3dff29f26 100644 --- a/server/test/unit/services/monitorService.test.ts +++ b/server/test/unit/services/monitorService.test.ts @@ -1,13 +1,11 @@ import { describe, expect, it, jest, beforeEach } from "@jest/globals"; -import { MonitorService } from "../../../src/service/business/monitorService.ts"; -import type { - IChecksRepository, - IGeoChecksRepository, - IIncidentsRepository, - IMonitorStatsRepository, - IMonitorsRepository, - IStatusPagesRepository, -} from "../../../src/repositories/index.ts"; +import { MonitorService } from "../../../src/domain/monitors/monitor.service.ts"; +import type { IChecksRepository } from "../../../src/domain/checks/check.repository.interface.ts"; +import type { IGeoChecksRepository } from "../../../src/domain/geo-checks/geo-check.repository.interface.ts"; +import type { IIncidentsRepository } from "../../../src/domain/incidents/incident.repository.interface.ts"; +import type { IMonitorStatsRepository } from "../../../src/domain/monitor-stats/monitor-stats.repository.interface.ts"; +import type { IMonitorsRepository } from "../../../src/domain/monitors/monitor.repository.interface.ts"; +import type { IStatusPagesRepository } from "../../../src/domain/status-pages/status-page-repository.interface.ts"; import { createMockLogger } from "../../helpers/createMockLogger.ts"; const createMonitorsRepositoryMock = () => diff --git a/server/test/unit/services/networkService.test.ts b/server/test/unit/services/networkService.test.ts index c9f496166..268b52e3a 100644 --- a/server/test/unit/services/networkService.test.ts +++ b/server/test/unit/services/networkService.test.ts @@ -1,9 +1,9 @@ import { describe, expect, it, jest } from "@jest/globals"; -import { NetworkService } from "../../../src/service/infrastructure/networkService.ts"; +import { NetworkService } from "../../../src/service/networkService.ts"; import { createMockLogger } from "../../helpers/createMockLogger.ts"; -import { NETWORK_ERROR } from "../../../src/service/infrastructure/network/utils.ts"; -import type { IStatusProvider } from "../../../src/service/infrastructure/network/IStatusProvider.ts"; -import type { Monitor, MonitorType } from "../../../src/types/index.ts"; +import { NETWORK_ERROR } from "../../../src/service/network/utils.ts"; +import type { IStatusProvider } from "../../../src/service/network/IStatusProvider.ts"; +import type { Monitor, MonitorType } from "../../../src/domain/monitors/monitor.types.ts"; import type { AxiosStatic } from "axios"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/services/notificationMessageBuilder.test.ts b/server/test/unit/services/notificationMessageBuilder.test.ts index 4403a8bb3..0ae4d8096 100644 --- a/server/test/unit/services/notificationMessageBuilder.test.ts +++ b/server/test/unit/services/notificationMessageBuilder.test.ts @@ -1,7 +1,8 @@ import { describe, expect, it, beforeEach } from "@jest/globals"; -import { NotificationMessageBuilder } from "../../../src/service/infrastructure/notificationMessageBuilder.ts"; -import type { Monitor, MonitorStatusResponse, HardwareStatusPayload } from "../../../src/types/index.ts"; -import type { MonitorActionDecision } from "../../../src/service/infrastructure/JobQueues/QueueHelper.ts"; +import { NotificationMessageBuilder } from "../../../src/domain/notifications/notification.message-builder.ts"; +import type { Monitor } from "../../../src/domain/monitors/monitor.types.ts"; +import type { MonitorStatusResponse, HardwareStatusPayload } from "../../../src/types/network.ts"; +import type { MonitorActionDecision } from "../../../src/service/job-queues/job-queue.helper.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/services/notificationsService.test.ts b/server/test/unit/services/notificationsService.test.ts index 9527fd3b5..eca1f349b 100644 --- a/server/test/unit/services/notificationsService.test.ts +++ b/server/test/unit/services/notificationsService.test.ts @@ -1,8 +1,10 @@ import { describe, expect, it, jest, beforeEach } from "@jest/globals"; -import { NotificationsService } from "../../../src/service/infrastructure/notificationsService.ts"; +import { NotificationsService } from "../../../src/domain/notifications/notification.service.ts"; import { createMockLogger } from "../../helpers/createMockLogger.ts"; -import type { Notification, Monitor, MonitorStatusResponse } from "../../../src/types/index.ts"; -import type { MonitorActionDecision } from "../../../src/service/infrastructure/JobQueues/QueueHelper.ts"; +import type { Monitor } from "../../../src/domain/monitors/monitor.types.ts"; +import type { Notification } from "../../../src/domain/notifications/notification.type.ts"; +import type { MonitorStatusResponse } from "../../../src/types/network.ts"; +import type { MonitorActionDecision } from "../../../src/service/job-queues/job-queue.helper.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/services/settingsService.test.ts b/server/test/unit/services/settingsService.test.ts index da75d3ee5..af58b5705 100644 --- a/server/test/unit/services/settingsService.test.ts +++ b/server/test/unit/services/settingsService.test.ts @@ -1,8 +1,8 @@ import { describe, expect, it, jest } from "@jest/globals"; -import { SettingsService } from "../../../src/service/system/settingsService.ts"; -import type { ISettingsRepository } from "../../../src/repositories/settings/ISettingsRepository.ts"; -import type { ValidatedEnv } from "../../../src/validation/envValidation.ts"; -import type { Settings } from "../../../src/types/index.ts"; +import { SettingsService } from "../../../src/domain/app-settings/app-settings.service.ts"; +import type { ISettingsRepository } from "../../../src/domain/app-settings/app-settings-repository.interface.ts"; +import type { ValidatedEnv } from "../../../src/config/envValidation.ts"; +import type { Settings } from "../../../src/domain/app-settings/app-settings.type.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/services/statusPageService.test.ts b/server/test/unit/services/statusPageService.test.ts index 2deac9897..066bdff95 100644 --- a/server/test/unit/services/statusPageService.test.ts +++ b/server/test/unit/services/statusPageService.test.ts @@ -1,9 +1,9 @@ import { describe, expect, it, jest } from "@jest/globals"; -import { StatusPageService } from "../../../src/service/business/statusPageService.ts"; -import type { IStatusPagesRepository } from "../../../src/repositories/status-pages/IStatusPagesRepository.ts"; -import type { ISettingsService } from "../../../src/service/system/settingsService.ts"; -import type { StatusPage } from "../../../src/types/index.ts"; -import { DEFAULT_STATUS_PAGE_THEME, DEFAULT_STATUS_PAGE_THEME_MODE } from "../../../src/types/index.ts"; +import { StatusPageService } from "../../../src/domain/status-pages/status-page.service.ts"; +import type { IStatusPagesRepository } from "../../../src/domain/status-pages/status-page-repository.interface.ts"; +import type { ISettingsService } from "../../../src/domain/app-settings/app-settings.service.ts"; +import type { StatusPage } from "../../../src/domain/status-pages/status-page.type.ts"; +import { DEFAULT_STATUS_PAGE_THEME, DEFAULT_STATUS_PAGE_THEME_MODE } from "../../../src/domain/status-pages/status-page.type.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/services/statusService.test.ts b/server/test/unit/services/statusService.test.ts index 75323943b..2bd5fa74c 100644 --- a/server/test/unit/services/statusService.test.ts +++ b/server/test/unit/services/statusService.test.ts @@ -1,10 +1,14 @@ import { describe, expect, it, jest, beforeEach } from "@jest/globals"; -import { StatusService } from "../../../src/service/infrastructure/statusService.ts"; +import { StatusService } from "../../../src/service/statusService.ts"; import { createMockLogger } from "../../helpers/createMockLogger.ts"; -import { MAX_RECENT_CHECKS } from "../../../src/types/index.ts"; -import type { Monitor, MonitorStatus, MonitorStatusResponse, Check, HardwareStatusPayload } from "../../../src/types/index.ts"; -import type { IMonitorsRepository, IMonitorStatsRepository, IChecksRepository } from "../../../src/repositories/index.ts"; -import type { IBufferService } from "../../../src/service/infrastructure/bufferService.ts"; +import { MAX_RECENT_CHECKS } from "../../../src/domain/monitors/monitor.types.ts"; +import type { Monitor, MonitorStatus } from "../../../src/domain/monitors/monitor.types.ts"; +import type { Check } from "../../../src/domain/checks/check.type.ts"; +import type { MonitorStatusResponse, HardwareStatusPayload } from "../../../src/types/network.ts"; +import type { IMonitorsRepository } from "../../../src/domain/monitors/monitor.repository.interface.ts"; +import type { IMonitorStatsRepository } from "../../../src/domain/monitor-stats/monitor-stats.repository.interface.ts"; +import type { IChecksRepository } from "../../../src/domain/checks/check.repository.interface.ts"; +import type { IBufferService } from "../../../src/service/bufferService.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/services/superSimpleQueue.test.ts b/server/test/unit/services/superSimpleQueue.test.ts index b6da507ce..8f446b74f 100644 --- a/server/test/unit/services/superSimpleQueue.test.ts +++ b/server/test/unit/services/superSimpleQueue.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, jest, beforeEach } from "@jest/globals"; import { createMockLogger } from "../../helpers/createMockLogger.ts"; -import type { Monitor } from "../../../src/types/monitor.ts"; +import type { Monitor } from "../../../src/domain/monitors/monitor.types.ts"; // ── Mock Scheduler ─────────────────────────────────────────────────────────── @@ -35,7 +35,7 @@ jest.unstable_mockModule("super-simple-scheduler", () => ({ default: MockScheduler, })); -const { SuperSimpleQueue } = await import("../../../src/service/infrastructure/JobQueues/SuperSimpleQueue.ts"); +const { SuperSimpleQueue } = await import("../../../src/service/job-queues/job-queue.sumper-simple.ts"); const createQueueHelper = () => ({ getHeartbeatJob: jest.fn().mockReturnValue(() => Promise.resolve()), diff --git a/server/test/unit/services/superSimpleQueueHelper.test.ts b/server/test/unit/services/superSimpleQueueHelper.test.ts index 7075051eb..7a369f4db 100644 --- a/server/test/unit/services/superSimpleQueueHelper.test.ts +++ b/server/test/unit/services/superSimpleQueueHelper.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, jest } from "@jest/globals"; -import { QueueHelper } from "../../../src/service/infrastructure/JobQueues/QueueHelper.ts"; -import type { Monitor } from "../../../src/types/monitor.ts"; +import { QueueHelper } from "../../../src/service/job-queues/job-queue.helper.ts"; +import type { Monitor } from "../../../src/domain/monitors/monitor.types.ts"; import { createMockLogger } from "../../helpers/createMockLogger.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/services/tagsService.test.ts b/server/test/unit/services/tagsService.test.ts index d611d641e..7f99906d7 100644 --- a/server/test/unit/services/tagsService.test.ts +++ b/server/test/unit/services/tagsService.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, jest } from "@jest/globals"; -import { TagsService } from "../../../src/service/infrastructure/tagService.ts"; -import type { Tag } from "../../../src/types/index.ts"; +import { TagsService } from "../../../src/domain/tags/tag.service.ts"; +import type { Tag } from "../../../src/domain/tags/tag.type.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/services/userService.test.ts b/server/test/unit/services/userService.test.ts index 51590fb38..e2e11369c 100644 --- a/server/test/unit/services/userService.test.ts +++ b/server/test/unit/services/userService.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it, jest } from "@jest/globals"; -import { UserService } from "../../../src/service/business/userService.ts"; +import { UserService } from "../../../src/domain/users/user.service.ts"; import { createMockLogger } from "../../helpers/createMockLogger.ts"; -import type { User, UserRole } from "../../../src/types/index.ts"; +import type { User, UserRole } from "../../../src/domain/users/user.type.ts"; // ── Helpers ────────────────────────────────────────────────────────────────── diff --git a/server/test/unit/utils/maintenanceWindow.test.ts b/server/test/unit/utils/maintenanceWindow.test.ts index 5a3a39b6a..4c4ed3337 100644 --- a/server/test/unit/utils/maintenanceWindow.test.ts +++ b/server/test/unit/utils/maintenanceWindow.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from "@jest/globals"; import { isWindowActive } from "../../../src/utils/maintenanceWindow.ts"; -import type { MaintenanceWindow } from "../../../src/types/index.ts"; +import type { MaintenanceWindow } from "../../../src/domain/maintenance-windows/maintenance-window.type.ts"; const makeWindow = (overrides?: Partial): MaintenanceWindow => { const now = Date.now(); diff --git a/server/test/unit/validation/maintenanceWindowValidation.test.ts b/server/test/unit/validation/maintenanceWindowValidation.test.ts index a209ba64f..d77fabd2c 100644 --- a/server/test/unit/validation/maintenanceWindowValidation.test.ts +++ b/server/test/unit/validation/maintenanceWindowValidation.test.ts @@ -2,7 +2,7 @@ import { describe, expect, it, jest, afterEach } from "@jest/globals"; import { createMaintenanceWindowBodyValidation, editMaintenanceByIdWindowBodyValidation, -} from "../../../src/validation/maintenanceWindowValidation.ts"; +} from "../../../src/api/validation/maintenanceWindowValidation.ts"; const FROZEN_NOW = new Date("2026-05-07T12:00:00Z").getTime(); diff --git a/server/test/unit/validation/monitorValidation.test.ts b/server/test/unit/validation/monitorValidation.test.ts index 04cf2537e..c08b8be84 100644 --- a/server/test/unit/validation/monitorValidation.test.ts +++ b/server/test/unit/validation/monitorValidation.test.ts @@ -1,5 +1,9 @@ import { describe, expect, it } from "@jest/globals"; -import { createMonitorBodyValidation, editMonitorBodyValidation, importMonitorsBodyValidation } from "../../../src/validation/monitorValidation.ts"; +import { + createMonitorBodyValidation, + editMonitorBodyValidation, + importMonitorsBodyValidation, +} from "../../../src/api/validation/monitorValidation.ts"; const baseDnsBody = { name: "DNS check", diff --git a/server/test/unit/validation/userValidation.test.ts b/server/test/unit/validation/userValidation.test.ts index 2e263d1a9..c50a70caa 100644 --- a/server/test/unit/validation/userValidation.test.ts +++ b/server/test/unit/validation/userValidation.test.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from "@jest/globals"; -import { editUserBodyValidation } from "../../../src/validation/userValidation.ts"; +import { editUserBodyValidation } from "../../../src/api/validation/userValidation.ts"; const validPassword = "OldPass1!"; const validNewPassword = "NewPass1!"; From 3c2b5713139685ec94c19050532d18ac7a3ccd26 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Tue, 9 Jun 2026 12:34:57 -0700 Subject: [PATCH 10/14] update openapi docs --- server/openapi.json | 28 +++++++++++++++++++++- server/openapi/index.ts | 2 +- server/openapi/routes/auth.ts | 4 ++-- server/openapi/routes/check.ts | 2 +- server/openapi/routes/geoCheck.ts | 2 +- server/openapi/routes/incident.ts | 2 +- server/openapi/routes/invite.ts | 2 +- server/openapi/routes/maintenanceWindow.ts | 2 +- server/openapi/routes/monitor.ts | 4 ++-- server/openapi/routes/notification.ts | 2 +- server/openapi/routes/settings.ts | 4 ++-- server/openapi/routes/statusPage.ts | 2 +- 12 files changed, 41 insertions(+), 15 deletions(-) diff --git a/server/openapi.json b/server/openapi.json index 2a5abd6e0..77580866d 100644 --- a/server/openapi.json +++ b/server/openapi.json @@ -3,7 +3,7 @@ "info": { "title": "Checkmate API", "version": "1.0.0", - "description": "Generated from Zod validation schemas. Source of truth: server/src/validation/*.ts" + "description": "Generated from Zod validation schemas. Source of truth: server/src/api/validation/*.ts" }, "servers": [ { @@ -398,6 +398,12 @@ "type": "string" } }, + "customUpCodes": { + "type": "array", + "items": { + "type": "number" + } + }, "secret": { "type": "string" }, @@ -7016,6 +7022,13 @@ "type": "string" } }, + "customUpCodes": { + "type": "array", + "items": { + "type": "number" + }, + "default": [] + }, "secret": { "type": "string" }, @@ -7685,6 +7698,13 @@ }, "default": [] }, + "customUpCodes": { + "type": "array", + "items": { + "type": "number" + }, + "default": [] + }, "secret": { "type": "string" }, @@ -8209,6 +8229,12 @@ "type": "string" } }, + "customUpCodes": { + "type": "array", + "items": { + "type": "number" + } + }, "secret": { "type": "string" }, diff --git a/server/openapi/index.ts b/server/openapi/index.ts index 9758c9d54..ef3e0b1d0 100644 --- a/server/openapi/index.ts +++ b/server/openapi/index.ts @@ -28,7 +28,7 @@ export function getOpenApiSpec(): JsonObject { info: { title: "Checkmate API", version: "1.0.0", - description: "Generated from Zod validation schemas. Source of truth: server/src/validation/*.ts", + description: "Generated from Zod validation schemas. Source of truth: server/src/api/validation/*.ts", }, servers: [{ url: "/api/v1", description: "Current server" }], tags: [ diff --git a/server/openapi/routes/auth.ts b/server/openapi/routes/auth.ts index 66b74382b..72f4cd2d2 100644 --- a/server/openapi/routes/auth.ts +++ b/server/openapi/routes/auth.ts @@ -7,7 +7,7 @@ import { recoveryValidation, recoveryTokenBodyValidation, newPasswordValidation, -} from "@/validation/authValidation.js"; +} from "@/api/validation/authValidation.js"; import { getUserByIdParamValidation, editUserByIdParamValidation, @@ -16,7 +16,7 @@ import { createUserBodyValidation, editUserBodyValidation, userResponseSchema, -} from "@/validation/userValidation.js"; +} from "@/api/validation/userValidation.js"; const tags = ["auth"]; diff --git a/server/openapi/routes/check.ts b/server/openapi/routes/check.ts index a9b6b3804..98ec87b7b 100644 --- a/server/openapi/routes/check.ts +++ b/server/openapi/routes/check.ts @@ -7,7 +7,7 @@ import { getTeamChecksQueryValidation, deleteChecksParamValidation, getChecksSummaryByTeamIdQueryValidation, -} from "@/validation/checkValidation.js"; +} from "@/api/validation/checkValidation.js"; const tags = ["checks"]; diff --git a/server/openapi/routes/geoCheck.ts b/server/openapi/routes/geoCheck.ts index 7b90d0a0d..2650fb3be 100644 --- a/server/openapi/routes/geoCheck.ts +++ b/server/openapi/routes/geoCheck.ts @@ -1,6 +1,6 @@ import { registry } from "../registry.js"; import { bearer, okUnknown, standardErrors } from "../helpers.js"; -import { getChecksParamValidation, getChecksQueryValidation } from "@/validation/checkValidation.js"; +import { getChecksParamValidation, getChecksQueryValidation } from "@/api/validation/checkValidation.js"; registry.registerPath({ method: "get", diff --git a/server/openapi/routes/incident.ts b/server/openapi/routes/incident.ts index 6497a5bd0..6621adc2b 100644 --- a/server/openapi/routes/incident.ts +++ b/server/openapi/routes/incident.ts @@ -1,7 +1,7 @@ import { z } from "zod"; import { registry } from "../registry.js"; import { bearer, okJson, okJsonNoData, standardErrors } from "../helpers.js"; -import { getIncidentsByTeamQueryValidation, getIncidentSummaryQueryValidation } from "@/validation/incidentValidation.js"; +import { getIncidentsByTeamQueryValidation, getIncidentSummaryQueryValidation } from "@/api/validation/incidentValidation.js"; const tags = ["incidents"]; diff --git a/server/openapi/routes/invite.ts b/server/openapi/routes/invite.ts index bf9b568b3..7e31bd2e0 100644 --- a/server/openapi/routes/invite.ts +++ b/server/openapi/routes/invite.ts @@ -1,7 +1,7 @@ import { registry } from "../registry.js"; import { bearer, json, okJson, okJsonNoData, standardErrors } from "../helpers.js"; import { z } from "zod"; -import { inviteBodyValidation, inviteVerificationBodyValidation } from "@/validation/authValidation.js"; +import { inviteBodyValidation, inviteVerificationBodyValidation } from "@/api/validation/authValidation.js"; const tags = ["invite"]; diff --git a/server/openapi/routes/maintenanceWindow.ts b/server/openapi/routes/maintenanceWindow.ts index 6afc57031..8d0506846 100644 --- a/server/openapi/routes/maintenanceWindow.ts +++ b/server/openapi/routes/maintenanceWindow.ts @@ -8,7 +8,7 @@ import { deleteMaintenanceWindowByIdParamValidation, editMaintenanceWindowByIdParamValidation, editMaintenanceByIdWindowBodyValidation, -} from "@/validation/maintenanceWindowValidation.js"; +} from "@/api/validation/maintenanceWindowValidation.js"; const tags = ["maintenance-window"]; diff --git a/server/openapi/routes/monitor.ts b/server/openapi/routes/monitor.ts index 10f988fa8..a941e54bf 100644 --- a/server/openapi/routes/monitor.ts +++ b/server/openapi/routes/monitor.ts @@ -16,8 +16,8 @@ import { getHardwareDetailsByIdParamValidation, getHardwareDetailsByIdQueryValidation, monitorResponseSchema, -} from "@/validation/monitorValidation.js"; -import { updateNotificationsValidation } from "@/validation/notificationValidation.js"; +} from "@/api/validation/monitorValidation.js"; +import { updateNotificationsValidation } from "@/api/validation/notificationValidation.js"; const tags = ["monitors"]; diff --git a/server/openapi/routes/notification.ts b/server/openapi/routes/notification.ts index c66e387f6..f1c70ca6d 100644 --- a/server/openapi/routes/notification.ts +++ b/server/openapi/routes/notification.ts @@ -7,7 +7,7 @@ import { getNotificationByIdParamValidation, editNotificationParamValidation, testAllNotificationsBodyValidation, -} from "@/validation/notificationValidation.js"; +} from "@/api/validation/notificationValidation.js"; const tags = ["notifications"]; diff --git a/server/openapi/routes/settings.ts b/server/openapi/routes/settings.ts index 1297c3e85..4871d9c7b 100644 --- a/server/openapi/routes/settings.ts +++ b/server/openapi/routes/settings.ts @@ -1,7 +1,7 @@ import { registry } from "../registry.js"; import { bearer, json, okJsonNoData, okUnknown, standardErrors } from "../helpers.js"; -import { updateAppSettingsBodyValidation } from "@/validation/settingsValidation.js"; -import { sendTestEmailBodyValidation } from "@/validation/notificationValidation.js"; +import { updateAppSettingsBodyValidation } from "@/api/validation/settingsValidation.js"; +import { sendTestEmailBodyValidation } from "@/api/validation/notificationValidation.js"; const tags = ["settings"]; diff --git a/server/openapi/routes/statusPage.ts b/server/openapi/routes/statusPage.ts index ac315b31c..d0df87972 100644 --- a/server/openapi/routes/statusPage.ts +++ b/server/openapi/routes/statusPage.ts @@ -1,6 +1,6 @@ import { registry } from "../registry.js"; import { bearer, multipart, okJsonNoData, okUnknown, standardErrors } from "../helpers.js"; -import { createStatusPageBodyValidation, getStatusPageParamValidation, getStatusPageQueryValidation } from "@/validation/statusPageValidation.js"; +import { createStatusPageBodyValidation, getStatusPageParamValidation, getStatusPageQueryValidation } from "@/api/validation/statusPageValidation.js"; const tags = ["status-page"]; From f1b104b78deb1b3846d8b50701173255c937a317 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Tue, 9 Jun 2026 12:35:19 -0700 Subject: [PATCH 11/14] ignore unknown on format --- server/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/package.json b/server/package.json index 2812b9b1f..2ac0d47f9 100755 --- a/server/package.json +++ b/server/package.json @@ -22,7 +22,7 @@ "format-check": "prettier --check ." }, "lint-staged": { - "**/*": "prettier --write" + "**/*": "prettier --write --ignore-unknown" }, "keywords": [], "author": "", From 692d4d89d67c4b3f81dcb0f11f25b7203b4217fe Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Tue, 9 Jun 2026 12:35:57 -0700 Subject: [PATCH 12/14] update configs --- server/eslint.config.js | 2 +- server/jest.config.ts | 1 - server/tsconfig.json | 1 + 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/eslint.config.js b/server/eslint.config.js index 817f54bc2..b10e75f6b 100755 --- a/server/eslint.config.js +++ b/server/eslint.config.js @@ -39,7 +39,7 @@ export default [ }, }, rules: { - "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }], // Ignore unused variables that start with '_' + "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_", varsIgnorePattern: "^_" }], // Ignore unused variables that start with '_' "@typescript-eslint/no-explicit-any": "warn", // Warn on 'any' types "mocha/max-top-level-suites": "warn", // Warn if there are too many top-level suites instead of failing }, diff --git a/server/jest.config.ts b/server/jest.config.ts index 1faf98181..c56ce1419 100644 --- a/server/jest.config.ts +++ b/server/jest.config.ts @@ -8,7 +8,6 @@ const config: Config = { "^.+\\.(t|j)sx?$": ["ts-jest", { useESM: true, tsconfig: "./tsconfig.jest.json" }], }, moduleNameMapper: { - "^@/validation/(.*)\\.js$": "/src/validation/$1.js", "^@/utils/(.*)\\.js$": "/src/utils/$1.ts", "^@/(.*)\\.ts$": "/src/$1.ts", "^@/(.*)\\.js$": "/src/$1.ts", diff --git a/server/tsconfig.json b/server/tsconfig.json index d4544d9bb..41f1ab64c 100644 --- a/server/tsconfig.json +++ b/server/tsconfig.json @@ -2,6 +2,7 @@ "compilerOptions": { "allowJs": true, "checkJs": false, + "baseUrl": ".", "paths": { "@/*": ["./src/*"] }, From 7991f3f6a1f0936f562e74d4ae1f3144390a64ec Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Tue, 9 Jun 2026 12:36:16 -0700 Subject: [PATCH 13/14] ignore unknown on format on client --- client/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/package.json b/client/package.json index 28a2a44c0..6e9844b28 100644 --- a/client/package.json +++ b/client/package.json @@ -14,7 +14,7 @@ "format-check": "prettier --check ." }, "lint-staged": { - "**/*": "prettier --write" + "**/*": "prettier --write --ignore-unknown" }, "dependencies": { "@emotion/react": "^11.13.3", From 9fecfa562ff17c29f77d855d0c8f1f711f3b2723 Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Tue, 9 Jun 2026 12:36:38 -0700 Subject: [PATCH 14/14] update claude.md --- CLAUDE.md | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 63a349ae7..1adfd703f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -68,19 +68,23 @@ VITE_APP_LOG_LEVEL="debug" ### Backend Layers ``` server/src/ -├── controllers/ # Route handlers (authController, monitorController, etc.) -├── service/ # Business logic -│ ├── business/ # Core monitoring logic -│ ├── infrastructure/ # Server/system utilities -│ └── system/ # App-level settings +├── api/ # HTTP layer +│ ├── controllers/ # Route handlers (authController, monitorController, etc.) +│ ├── middleware/ # verifyJWT, rateLimiter, sanitization, responseHandler +│ ├── routes/ # API route definitions +│ └── validation/ # Zod request-payload schemas +├── domain/ # Business logic + data access, one folder per entity +│ ├── monitors/ # e.g. monitor.service.ts, monitor.repository.ts, monitor.type.ts +│ ├── checks/ +│ ├── incidents/ +│ └── … # users, teams, status-pages, notifications, etc. +├── service/ # Cross-cutting services (e.g. infrastructure/) +├── config/ # App config wiring (controllers, routes, services, envValidation) ├── db/ -│ ├── models/ # Mongoose schemas (Monitor, Check, Incident, User, etc.) -│ ├── migration/ # Database migrations (run on startup) -│ └── modules/ # Database-specific modules -├── middleware/v1/ # verifyJWT, rateLimiter, sanitization, responseHandler -├── routes/v1/ # API route definitions -├── validation/ # Joi input validation schemas -└── repositories/ # Data access layer +│ └── migration/ # Database migrations (run on startup) +├── templates/ # Email/notification templates +├── types/ # Shared const tuples + derived types +└── utils/ # Shared utilities ``` ### Frontend Structure