From e62e4898b9d6e0a28320828b7dabb46ab71fba6f Mon Sep 17 00:00:00 2001 From: Alex Holliday Date: Mon, 5 Jan 2026 04:35:01 +0000 Subject: [PATCH] notificaitons --- .../src/services/business/IncidentService.ts | 24 +++++++++++-------- .../infrastructure/NotificationService.ts | 7 +++--- .../NotificationServices/Discord.ts | 9 +++---- .../NotificationServices/Email.ts | 10 ++++---- .../NotificationServices/IMessageService.ts | 4 ++-- .../NotificationServices/Slack.ts | 9 +++---- .../NotificationServices/Webhook.ts | 9 +++---- .../services/infrastructure/StatusService.ts | 12 +++++----- 8 files changed, 39 insertions(+), 45 deletions(-) diff --git a/server/src/services/business/IncidentService.ts b/server/src/services/business/IncidentService.ts index 09c5832f3..ec5625bbc 100644 --- a/server/src/services/business/IncidentService.ts +++ b/server/src/services/business/IncidentService.ts @@ -11,6 +11,7 @@ import mongoose from "mongoose"; import { getChildLogger } from "@/logger/Logger.js"; import { ThresholdEvaluationResult } from "@/services/infrastructure/StatusService.js"; import { getStartDate } from "@/utils/TimeUtils.js"; +import type { Monitor as MonitorEntity } from "@/types/domain/monitor.js"; type IncidentPopulated = Omit & { monitorId: IMonitor; @@ -19,11 +20,11 @@ type IncidentPopulated = Omit & { export interface IIncidentService { handleStatusChange: ( - updatedMonitor: IMonitor, + updatedMonitor: MonitorEntity, lastCheck: ICheck ) => Promise; handleThresholdBreach: ( - updatedMonitor: IMonitor, + updatedMonitor: MonitorEntity, lastCheck: ICheck, evalResult: ThresholdEvaluationResult ) => Promise; @@ -66,17 +67,20 @@ class IncidentService implements IIncidentService { this.SERVICE_NAME = SERVICE_NAME; } - handleStatusChange = async (updatedMonitor: IMonitor, lastCheck: ICheck) => { + handleStatusChange = async ( + updatedMonitor: MonitorEntity, + lastCheck: ICheck + ) => { if (updatedMonitor.status === "down") { const incident = await this.create( - updatedMonitor.teamId, - updatedMonitor._id, + new mongoose.Types.ObjectId(updatedMonitor.teamId), + new mongoose.Types.ObjectId(updatedMonitor.id), lastCheck._id ); return incident; } else if (updatedMonitor.status === "up") { const incident = await Incident.findOne({ - monitorId: updatedMonitor._id, + monitorId: updatedMonitor.id, teamId: updatedMonitor.teamId, resolved: false, }); @@ -97,12 +101,12 @@ class IncidentService implements IIncidentService { }; handleThresholdBreach = async ( - updatedMonitor: IMonitor, + updatedMonitor: MonitorEntity, lastCheck: ICheck, evalResult: ThresholdEvaluationResult ) => { const existing = await Incident.findOne({ - monitorId: updatedMonitor._id, + monitorId: updatedMonitor.id, teamId: updatedMonitor.teamId, resolved: false, }); @@ -110,8 +114,8 @@ class IncidentService implements IIncidentService { if (evalResult.hasBreach) { if (!existing) { const incident = await this.create( - updatedMonitor.teamId, - updatedMonitor._id, + new mongoose.Types.ObjectId(updatedMonitor.teamId), + new mongoose.Types.ObjectId(updatedMonitor.id), lastCheck._id ); if (evalResult.notes.length) { diff --git a/server/src/services/infrastructure/NotificationService.ts b/server/src/services/infrastructure/NotificationService.ts index a1844f06a..9b41b70e9 100644 --- a/server/src/services/infrastructure/NotificationService.ts +++ b/server/src/services/infrastructure/NotificationService.ts @@ -16,6 +16,7 @@ import SettingsService from "@/services/system/SettingsService.js"; import ApiError from "@/utils/ApiError.js"; import { getChildLogger } from "@/logger/Logger.js"; import type { IEmailTransport } from "./NotificationServices/Email.js"; +import type { Monitor as MonitorEntity } from "@/types/domain/index.js"; const SERVICE_NAME = "NotificationService"; const logger = getChildLogger(SERVICE_NAME); @@ -28,7 +29,7 @@ export interface ITestResult { } export interface INotificationService { handleNotifications: ( - monitor: IMonitor, + monitor: MonitorEntity, incident: IIncident ) => Promise; testNotificationChannels: ( @@ -58,7 +59,7 @@ class NotificationService implements INotificationService { this.webhookService = new WebhookService(); } - handleNotifications = async (monitor: IMonitor, incident: IIncident) => { + handleNotifications = async (monitor: MonitorEntity, incident: IIncident) => { const notificationIds = monitor.notificationChannels || []; if (notificationIds.length === 0) { @@ -88,7 +89,7 @@ class NotificationService implements INotificationService { private sendForChannel = async ( channel: INotificationChannel, - monitor: IMonitor, + monitor: MonitorEntity, incident: IIncident ): Promise => { try { diff --git a/server/src/services/infrastructure/NotificationServices/Discord.ts b/server/src/services/infrastructure/NotificationServices/Discord.ts index e52ba60dc..c0d0aeeb1 100644 --- a/server/src/services/infrastructure/NotificationServices/Discord.ts +++ b/server/src/services/infrastructure/NotificationServices/Discord.ts @@ -1,8 +1,5 @@ -import { - IMonitor, - INotificationChannel, - IIncident, -} from "@/db/models/index.js"; +import { INotificationChannel, IIncident } from "@/db/models/index.js"; +import type { Monitor } from "@/types/domain/index.js"; import { IAlert, IMessageService } from "./IMessageService.js"; import got from "got"; import ApiError from "@/utils/ApiError.js"; @@ -52,7 +49,7 @@ class DiscordService implements IMessageService { }; }; - buildAlert = (monitor: IMonitor, incident: IIncident) => { + buildAlert = (monitor: Monitor, incident: IIncident) => { const name = monitor?.name || "Unnamed monitor"; const monitorStatus = monitor?.status || "unknown status"; const url = monitor?.url || "no URL"; diff --git a/server/src/services/infrastructure/NotificationServices/Email.ts b/server/src/services/infrastructure/NotificationServices/Email.ts index b6714151c..3a321c1a0 100644 --- a/server/src/services/infrastructure/NotificationServices/Email.ts +++ b/server/src/services/infrastructure/NotificationServices/Email.ts @@ -1,8 +1,6 @@ -import { - IMonitor, - INotificationChannel, - IIncident, -} from "@/db/models/index.js"; +import { INotificationChannel, IIncident } from "@/db/models/index.js"; +import type { Monitor } from "@/types/domain/index.js"; + import { IMessageService, IAlert } from "./IMessageService.js"; import nodemailer, { Transporter } from "nodemailer"; import { config } from "@/config/index.js"; @@ -123,7 +121,7 @@ class EmailService implements IEmailService { } }; - buildAlert = (monitor: IMonitor, incident: IIncident) => { + buildAlert = (monitor: Monitor, incident: IIncident) => { const name = monitor?.name || "Unnamed monitor"; const monitorStatus = monitor?.status || "unknown status"; const url = monitor?.url || "no URL"; diff --git a/server/src/services/infrastructure/NotificationServices/IMessageService.ts b/server/src/services/infrastructure/NotificationServices/IMessageService.ts index e9c294b89..9840ec297 100644 --- a/server/src/services/infrastructure/NotificationServices/IMessageService.ts +++ b/server/src/services/infrastructure/NotificationServices/IMessageService.ts @@ -1,9 +1,9 @@ import { - IMonitor, INotificationChannel, IIncident, ResolutionType, } from "@/db/models/index.js"; +import type { Monitor } from "@/types/domain/index.js"; export interface IAlert { name: string; @@ -18,7 +18,7 @@ export interface IAlert { alertTime: Date; } export interface IMessageService { - buildAlert: (monitor: IMonitor, incident: IIncident) => IAlert; + buildAlert: (monitor: Monitor, incident: IIncident) => IAlert; sendMessage: ( alert: IAlert, channel: INotificationChannel diff --git a/server/src/services/infrastructure/NotificationServices/Slack.ts b/server/src/services/infrastructure/NotificationServices/Slack.ts index 861bfef28..7327fef14 100644 --- a/server/src/services/infrastructure/NotificationServices/Slack.ts +++ b/server/src/services/infrastructure/NotificationServices/Slack.ts @@ -1,10 +1,7 @@ -import { - IMonitor, - INotificationChannel, - IIncident, -} from "@/db/models/index.js"; +import { INotificationChannel, IIncident } from "@/db/models/index.js"; import { IAlert, IMessageService } from "./IMessageService.js"; import got from "got"; +import { Monitor } from "@/types/domain/index.js"; import { getChildLogger } from "@/logger/Logger.js"; const SERVICE_NAME = "SlackService"; @@ -113,7 +110,7 @@ class SlackService implements IMessageService { ]; }; - buildAlert = (monitor: IMonitor, incident: IIncident) => { + buildAlert = (monitor: Monitor, incident: IIncident) => { const name = monitor?.name || "Unnamed monitor"; const monitorStatus = monitor?.status || "unknown status"; const url = monitor?.url || "no URL"; diff --git a/server/src/services/infrastructure/NotificationServices/Webhook.ts b/server/src/services/infrastructure/NotificationServices/Webhook.ts index 88931a870..0f73716e8 100644 --- a/server/src/services/infrastructure/NotificationServices/Webhook.ts +++ b/server/src/services/infrastructure/NotificationServices/Webhook.ts @@ -1,12 +1,9 @@ -import { - IMonitor, - INotificationChannel, - IIncident, -} from "@/db/models/index.js"; +import { INotificationChannel, IIncident } from "@/db/models/index.js"; import { IAlert, IMessageService } from "./IMessageService.js"; import ApiError from "@/utils/ApiError.js"; import got from "got"; import { getChildLogger } from "@/logger/Logger.js"; +import type { Monitor } from "@/types/domain/index.js"; const SERVICE_NAME = "WebhookService"; const logger = getChildLogger(SERVICE_NAME); @@ -17,7 +14,7 @@ class WebhookService implements IMessageService { this.SERVICE_NAME = SERVICE_NAME; } - buildAlert = (monitor: IMonitor, incident: IIncident) => { + buildAlert = (monitor: Monitor, incident: IIncident) => { const name = monitor?.name || "Unnamed monitor"; const monitorStatus = monitor?.status || "unknown status"; const url = monitor?.url || "no URL"; diff --git a/server/src/services/infrastructure/StatusService.ts b/server/src/services/infrastructure/StatusService.ts index 7dfc2bd9f..1ef4179cf 100644 --- a/server/src/services/infrastructure/StatusService.ts +++ b/server/src/services/infrastructure/StatusService.ts @@ -49,12 +49,12 @@ export interface IStatusService { ) => number; updateMonitorStats: ( - monitor: IMonitor, + monitor: MonitorEntity, status: StatusResponse, statusChanged: boolean ) => Promise; evaluateThresholds: ( - monitor: IMonitor, + monitor: MonitorEntity, check: ICheck ) => Promise; } @@ -151,14 +151,14 @@ class StatusService implements IStatusService { }; updateMonitorStats = async ( - monitor: IMonitor, + monitor: MonitorEntity, statusResponse: StatusResponse, statusChanged: boolean ) => { - let stats = await MonitorStats.findOne({ monitorId: monitor._id }); + let stats = await MonitorStats.findOne({ monitorId: monitor.id }); if (!stats) { stats = await MonitorStats.create({ - monitorId: monitor._id, + monitorId: monitor.id, currentStreakStartedAt: Date.now(), }); } @@ -203,7 +203,7 @@ class StatusService implements IStatusService { }; evaluateThresholds = async ( - monitor: IMonitor, + monitor: MonitorEntity, check: ICheck ): Promise => { try {