fix: Update notification handling to mark announcements and public notes as Skipped when no related entities are found

This commit is contained in:
Simon Larsen
2025-08-08 19:17:55 +01:00
parent a9ecaf2dc8
commit db1f5a29bb
5 changed files with 185 additions and 11 deletions

View File

@@ -122,8 +122,21 @@ RunCron(
);
if (!announcement.statusPages) {
logger.debug(
`Announcement ${announcement.id} has no status pages; skipping notifications.`,
`Announcement ${announcement.id} has no status pages; marking as Skipped.`,
);
await StatusPageAnnouncementService.updateOneById({
id: announcement.id!,
data: {
subscriberNotificationStatus:
StatusPageSubscriberNotificationStatus.Skipped,
subscriberNotificationStatusMessage:
"No status pages attached to this announcement. Skipping notifications.",
},
props: {
isRoot: true,
ignoreHooks: true,
},
});
continue;
}

View File

@@ -106,15 +106,41 @@ RunCron(
if (!incident) {
logger.debug(
`Incident ${incidentPublicNote.incidentId} not found; skipping public note ${incidentPublicNote.id}.`,
`Incident ${incidentPublicNote.incidentId} not found; marking public note ${incidentPublicNote.id} as Skipped.`,
);
await IncidentPublicNoteService.updateOneById({
id: incidentPublicNote.id!,
data: {
subscriberNotificationStatusOnNoteCreated:
StatusPageSubscriberNotificationStatus.Skipped,
subscriberNotificationStatusMessage:
"Related incident not found. Skipping notifications to subscribers.",
},
props: {
isRoot: true,
ignoreHooks: true,
},
});
continue;
}
if (!incident.monitors || incident.monitors.length === 0) {
logger.debug(
`Incident ${incident.id} has no monitors; skipping notifications for public note ${incidentPublicNote.id}.`,
`Incident ${incident.id} has no monitors; marking public note ${incidentPublicNote.id} as Skipped.`,
);
await IncidentPublicNoteService.updateOneById({
id: incidentPublicNote.id!,
data: {
subscriberNotificationStatusOnNoteCreated:
StatusPageSubscriberNotificationStatus.Skipped,
subscriberNotificationStatusMessage:
"No monitors are attached to the related incident. Skipping notifications.",
},
props: {
isRoot: true,
ignoreHooks: true,
},
});
continue;
}

View File

@@ -75,29 +75,47 @@ RunCron(
logger.debug(
`Processing incident state timeline ${incidentStateTimeline.id}.`,
);
// Set to InProgress at the start of processing
await IncidentStateTimelineService.updateOneById({
id: incidentStateTimeline.id!,
data: {
subscriberNotificationStatus:
StatusPageSubscriberNotificationStatus.Success,
StatusPageSubscriberNotificationStatus.InProgress,
},
props: {
isRoot: true,
ignoreHooks: true,
},
});
logger.debug(
`Incident state timeline ${incidentStateTimeline.id} pre-marked as Success (legacy behavior).`,
);
if (
!incidentStateTimeline.incidentId ||
!incidentStateTimeline.incidentStateId
) {
await IncidentStateTimelineService.updateOneById({
id: incidentStateTimeline.id!,
data: {
subscriberNotificationStatus:
StatusPageSubscriberNotificationStatus.Skipped,
subscriberNotificationStatusMessage:
"Missing incident or incident state reference. Skipping notifications.",
},
props: { isRoot: true, ignoreHooks: true },
});
continue;
}
if (!incidentStateTimeline.incidentState?.name) {
await IncidentStateTimelineService.updateOneById({
id: incidentStateTimeline.id!,
data: {
subscriberNotificationStatus:
StatusPageSubscriberNotificationStatus.Skipped,
subscriberNotificationStatusMessage:
"Incident state has no name. Skipping notifications.",
},
props: { isRoot: true, ignoreHooks: true },
});
continue;
}
@@ -125,20 +143,52 @@ RunCron(
if (!incident) {
logger.debug(
`Incident ${incidentStateTimeline.incidentId} not found; skipping.`,
`Incident ${incidentStateTimeline.incidentId} not found; marking as Skipped.`,
);
await IncidentStateTimelineService.updateOneById({
id: incidentStateTimeline.id!,
data: {
subscriberNotificationStatus:
StatusPageSubscriberNotificationStatus.Skipped,
subscriberNotificationStatusMessage:
"Related incident not found. Skipping notifications.",
},
props: { isRoot: true, ignoreHooks: true },
});
continue;
}
if (!incident.monitors || incident.monitors.length === 0) {
logger.debug(`Incident ${incident.id} has no monitors; skipping.`);
logger.debug(
`Incident ${incident.id} has no monitors; marking timeline ${incidentStateTimeline.id} as Skipped.`,
);
await IncidentStateTimelineService.updateOneById({
id: incidentStateTimeline.id!,
data: {
subscriberNotificationStatus:
StatusPageSubscriberNotificationStatus.Skipped,
subscriberNotificationStatusMessage:
"No monitors are attached to the related incident. Skipping notifications.",
},
props: { isRoot: true, ignoreHooks: true },
});
continue;
}
if (!incident.isVisibleOnStatusPage) {
logger.debug(
`Incident ${incident.id} not visible on status page; skipping.`,
`Incident ${incident.id} not visible on status page; marking as Skipped.`,
);
await IncidentStateTimelineService.updateOneById({
id: incidentStateTimeline.id!,
data: {
subscriberNotificationStatus:
StatusPageSubscriberNotificationStatus.Skipped,
subscriberNotificationStatusMessage:
"Incident is not visible on status page. Skipping notifications.",
},
props: { isRoot: true, ignoreHooks: true },
});
continue; // skip if not visible on status page.
}
@@ -407,6 +457,18 @@ RunCron(
});
logger.debug("Incident Feed created");
// Mark Success at the end
await IncidentStateTimelineService.updateOneById({
id: incidentStateTimeline.id!,
data: {
subscriberNotificationStatus:
StatusPageSubscriberNotificationStatus.Success,
subscriberNotificationStatusMessage:
"Notifications sent successfully to all subscribers",
},
props: { isRoot: true, ignoreHooks: true },
});
}
},
);

View File

@@ -101,8 +101,21 @@ RunCron(
if (!event) {
logger.debug(
`Scheduled maintenance ${publicNote.scheduledMaintenanceId} not found; skipping public note ${publicNote.id}.`,
`Scheduled maintenance ${publicNote.scheduledMaintenanceId} not found; marking public note ${publicNote.id} as Skipped.`,
);
await ScheduledMaintenancePublicNoteService.updateOneById({
id: publicNote.id!,
data: {
subscriberNotificationStatusOnNoteCreated:
StatusPageSubscriberNotificationStatus.Skipped,
subscriberNotificationStatusMessage:
"Related scheduled maintenance not found. Skipping notifications to subscribers.",
},
props: {
isRoot: true,
ignoreHooks: true,
},
});
continue;
}
@@ -203,6 +216,26 @@ RunCron(
}) || [],
);
if (!statusPages || statusPages.length === 0) {
logger.debug(
`No status pages found to notify for public note ${publicNote.id}; marking as Skipped.`,
);
await ScheduledMaintenancePublicNoteService.updateOneById({
id: publicNote.id!,
data: {
subscriberNotificationStatusOnNoteCreated:
StatusPageSubscriberNotificationStatus.Skipped,
subscriberNotificationStatusMessage:
"No status pages are configured for this scheduled maintenance. Skipping notifications.",
},
props: {
isRoot: true,
ignoreHooks: true,
},
});
continue;
}
for (const statuspage of statusPages) {
if (!statuspage.id) {
logger.debug("Encountered a status page without an id; skipping.");

View File

@@ -86,10 +86,30 @@ RunCron(
!scheduledEventStateTimeline.scheduledMaintenanceId ||
!scheduledEventStateTimeline.scheduledMaintenanceStateId
) {
await ScheduledMaintenanceStateTimelineService.updateOneById({
id: scheduledEventStateTimeline.id!,
data: {
subscriberNotificationStatus:
StatusPageSubscriberNotificationStatus.Skipped,
subscriberNotificationStatusMessage:
"Missing scheduled maintenance or state reference. Skipping notifications.",
},
props: { isRoot: true, ignoreHooks: true },
});
continue;
}
if (!scheduledEventStateTimeline.scheduledMaintenanceState?.name) {
await ScheduledMaintenanceStateTimelineService.updateOneById({
id: scheduledEventStateTimeline.id!,
data: {
subscriberNotificationStatus:
StatusPageSubscriberNotificationStatus.Skipped,
subscriberNotificationStatusMessage:
"Scheduled maintenance state has no name. Skipping notifications.",
},
props: { isRoot: true, ignoreHooks: true },
});
continue;
}
@@ -119,10 +139,30 @@ RunCron(
});
if (!event) {
await ScheduledMaintenanceStateTimelineService.updateOneById({
id: scheduledEventStateTimeline.id!,
data: {
subscriberNotificationStatus:
StatusPageSubscriberNotificationStatus.Skipped,
subscriberNotificationStatusMessage:
"Related scheduled maintenance not found. Skipping notifications.",
},
props: { isRoot: true, ignoreHooks: true },
});
continue;
}
if (!event.isVisibleOnStatusPage) {
await ScheduledMaintenanceStateTimelineService.updateOneById({
id: scheduledEventStateTimeline.id!,
data: {
subscriberNotificationStatus:
StatusPageSubscriberNotificationStatus.Skipped,
subscriberNotificationStatusMessage:
"Scheduled maintenance is not visible on status page. Skipping notifications.",
},
props: { isRoot: true, ignoreHooks: true },
});
continue; // skip if not visible on status page.
}