diff --git a/client/src/pages/incidents/IncidentTable.tsx b/client/src/pages/incidents/IncidentTable.tsx
index d1cee514d..b00a8c68c 100644
--- a/client/src/pages/incidents/IncidentTable.tsx
+++ b/client/src/pages/incidents/IncidentTable.tsx
@@ -37,7 +37,7 @@ export const IncidentTable = ({
id: "name",
content: t("incidentsTableMonitorName"),
render: (row) => {
- return row.monitorId.name || "N/A";
+ return row.monitorId?.name || "N/A";
},
},
{
@@ -70,7 +70,7 @@ export const IncidentTable = ({
render: (row) => {
return (
- {row.monitorId.status}
+ {row.monitorId?.status}
);
},
diff --git a/server/src/db/models/monitors/Monitor.ts b/server/src/db/models/monitors/Monitor.ts
index b190647dd..050185adb 100644
--- a/server/src/db/models/monitors/Monitor.ts
+++ b/server/src/db/models/monitors/Monitor.ts
@@ -1,5 +1,5 @@
import mongoose, { Schema, Document, Types } from "mongoose";
-import { Check, MonitorStats } from "@/db/models/index.js";
+import { Check, Incident, MonitorStats } from "@/db/models/index.js";
export const MonitorTypes = [
"http",
@@ -99,6 +99,7 @@ MonitorSchema.pre(
const monitorId = this._id;
await Check.deleteMany({ "metadata.monitorId": monitorId });
await MonitorStats.deleteMany({ monitorId });
+ await Incident.deleteMany({ monitorId });
next();
} catch (error: any) {
next(error);
@@ -117,6 +118,7 @@ MonitorSchema.pre(
if (monitorIds.length > 0) {
await Check.deleteMany({ "metadata.monitorId": { $in: monitorIds } });
await MonitorStats.deleteMany({ monitorId: { $in: monitorIds } });
+ await Incident.deleteMany({ monitorId: { $in: monitorIds } });
}
next();
} catch (error: any) {
diff --git a/server/src/services/business/IncidentService.ts b/server/src/services/business/IncidentService.ts
index 5ad6653a9..6fcd11930 100644
--- a/server/src/services/business/IncidentService.ts
+++ b/server/src/services/business/IncidentService.ts
@@ -1,4 +1,10 @@
-import { IIncident, Incident, IMonitor, ICheck } from "@/db/models/index.js";
+import {
+ IIncident,
+ Incident,
+ IMonitor,
+ Monitor,
+ ICheck,
+} from "@/db/models/index.js";
import type { ResolutionType } from "@/db/models/index.js";
import mongoose from "mongoose";
import { getChildLogger } from "@/logger/Logger.js";
@@ -39,10 +45,11 @@ export interface IIncidentService {
teamId: mongoose.Types.ObjectId,
incidentId: mongoose.Types.ObjectId
) => Promise;
+ cleanupOrphanedIncidents: () => Promise;
}
const SERVICE_NAME = "IncidentService";
-
+const logger = getChildLogger(SERVICE_NAME);
class IncidentService implements IIncidentService {
public SERVICE_NAME: string;
constructor() {
@@ -199,6 +206,20 @@ class IncidentService implements IIncidentService {
});
return result.deletedCount === 1;
};
+
+ async cleanupOrphanedIncidents() {
+ try {
+ const monitorIds = await Monitor.find().distinct("_id");
+ const result = await Incident.deleteMany({
+ monitorId: { $nin: monitorIds },
+ });
+ logger.info(`Deleted ${result.deletedCount} orphaned Incidents.`);
+ return true;
+ } catch (error) {
+ logger.error("Error cleaning up orphaned Incidents:", error);
+ return false;
+ }
+ }
}
export default IncidentService;
diff --git a/server/src/services/infrastructure/JobGenerator.ts b/server/src/services/infrastructure/JobGenerator.ts
index 6324046a6..971d939c7 100644
--- a/server/src/services/infrastructure/JobGenerator.ts
+++ b/server/src/services/infrastructure/JobGenerator.ts
@@ -98,6 +98,7 @@ class JobGenerator implements IJobGenerator {
try {
await this.checkService.cleanupOrphanedChecks();
await this.monitorStatsService.cleanupOrphanedMonitorStats();
+ await this.incidentService.cleanupOrphanedIncidents();
} catch (error) {
throw error;
}