mirror of
https://github.com/OneUptime/oneuptime.git
synced 2026-04-06 00:32:12 +02:00
feat(AutoResolve): implement resolve delay logic based on incident grouping rules
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
import RunCron from "../../Utils/Cron";
|
||||
import OneUptimeDate from "Common/Types/Date";
|
||||
import { EVERY_MINUTE } from "Common/Utils/CronTime";
|
||||
import IncidentEpisodeService from "Common/Server/Services/IncidentEpisodeService";
|
||||
import IncidentEpisodeMemberService from "Common/Server/Services/IncidentEpisodeMemberService";
|
||||
import IncidentStateService from "Common/Server/Services/IncidentStateService";
|
||||
import IncidentGroupingRuleService from "Common/Server/Services/IncidentGroupingRuleService";
|
||||
import IncidentService from "Common/Server/Services/IncidentService";
|
||||
import logger from "Common/Server/Utils/Logger";
|
||||
import IncidentEpisode from "Common/Models/DatabaseModels/IncidentEpisode";
|
||||
import IncidentGroupingRule from "Common/Models/DatabaseModels/IncidentGroupingRule";
|
||||
import IncidentState from "Common/Models/DatabaseModels/IncidentState";
|
||||
import Incident from "Common/Models/DatabaseModels/Incident";
|
||||
import ObjectID from "Common/Types/ObjectID";
|
||||
@@ -33,6 +36,7 @@ RunCron(
|
||||
select: {
|
||||
_id: true,
|
||||
projectId: true,
|
||||
incidentGroupingRuleId: true,
|
||||
lastIncidentAddedAt: true,
|
||||
},
|
||||
props: {
|
||||
@@ -71,6 +75,31 @@ const checkAndResolveEpisode: CheckAndResolveEpisodeFunction = async (
|
||||
return;
|
||||
}
|
||||
|
||||
// Get resolve delay from the grouping rule if exists and enabled
|
||||
let resolveDelayMinutes: number = 0;
|
||||
let enableResolveDelay: boolean = false;
|
||||
|
||||
if (episode.incidentGroupingRuleId) {
|
||||
const rule: IncidentGroupingRule | null =
|
||||
await IncidentGroupingRuleService.findOneById({
|
||||
id: episode.incidentGroupingRuleId,
|
||||
select: {
|
||||
enableResolveDelay: true,
|
||||
resolveDelayMinutes: true,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (rule) {
|
||||
enableResolveDelay = rule.enableResolveDelay || false;
|
||||
if (enableResolveDelay && rule.resolveDelayMinutes) {
|
||||
resolveDelayMinutes = rule.resolveDelayMinutes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get all incidents in this episode
|
||||
const incidentIds: ObjectID[] =
|
||||
await IncidentEpisodeMemberService.getIncidentsInEpisode(episode.id);
|
||||
@@ -108,6 +137,7 @@ const checkAndResolveEpisode: CheckAndResolveEpisodeFunction = async (
|
||||
|
||||
// Check if all incidents are in resolved state or higher
|
||||
let allResolved: boolean = true;
|
||||
let lastResolvedAt: Date | null = null;
|
||||
|
||||
for (const incidentId of incidentIds) {
|
||||
const incident: Incident | null = await IncidentService.findOneById({
|
||||
@@ -133,6 +163,13 @@ const checkAndResolveEpisode: CheckAndResolveEpisodeFunction = async (
|
||||
allResolved = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Track the latest resolved time among incidents
|
||||
if (incident.updatedAt) {
|
||||
if (!lastResolvedAt || incident.updatedAt > lastResolvedAt) {
|
||||
lastResolvedAt = incident.updatedAt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!allResolved) {
|
||||
@@ -142,6 +179,22 @@ const checkAndResolveEpisode: CheckAndResolveEpisodeFunction = async (
|
||||
return;
|
||||
}
|
||||
|
||||
// All incidents are resolved. Check if resolve delay has passed (only if enabled)
|
||||
if (enableResolveDelay && resolveDelayMinutes > 0 && lastResolvedAt) {
|
||||
const timeSinceLastResolved: number =
|
||||
OneUptimeDate.getDifferenceInMinutes(
|
||||
lastResolvedAt,
|
||||
OneUptimeDate.getCurrentDate(),
|
||||
);
|
||||
|
||||
if (timeSinceLastResolved < resolveDelayMinutes) {
|
||||
logger.debug(
|
||||
`IncidentEpisode:AutoResolve - Episode ${episode.id} waiting for resolve delay (${resolveDelayMinutes} minutes)`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve the episode
|
||||
logger.info(
|
||||
`IncidentEpisode:AutoResolve - Resolving episode ${episode.id} as all incidents are resolved`,
|
||||
|
||||
Reference in New Issue
Block a user