From 05fcbdd8b8bcad3e734b3cf3a92707191f497326 Mon Sep 17 00:00:00 2001 From: James Maes Date: Fri, 16 Oct 2026 15:33:59 -0500 Subject: [PATCH] fix(alerts): stable chain break alert title The wormaudit.chain.break title was the first break reason, so the bell text changed on every run. The title is now "Audit chain verification found N problems"; the first reasons move to the summary. Dedupe key and severity are unchanged. Co-Authored-By: Claude Opus 5.5 --- .../wormaudit/processes/VerificationRuns.java | 15 ++++++++++++++- .../qbits/wormaudit/ProcessesAndAlertsTest.java | 3 ++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/kingsrook/qbits/wormaudit/processes/VerificationRuns.java b/src/main/java/com/kingsrook/qbits/wormaudit/processes/VerificationRuns.java index 30e6bbd..ce097df 100644 --- a/src/main/java/com/kingsrook/qbits/wormaudit/processes/VerificationRuns.java +++ b/src/main/java/com/kingsrook/qbits/wormaudit/processes/VerificationRuns.java @@ -24,6 +24,7 @@ package com.kingsrook.qbits.wormaudit.processes; import java.time.Instant; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; import com.kingsrook.qbits.wormaudit.WormAuditQBitConfig; import com.kingsrook.qbits.wormaudit.chain.AuditStore; import com.kingsrook.qbits.wormaudit.model.WormAuditTables; @@ -43,6 +44,11 @@ import com.kingsrook.qqq.backend.core.model.data.QRecord; *******************************************************************************/ public final class VerificationRuns { + /** How many break reasons the alert summary spells out; the title carries the total. */ + private static final int ALERT_SUMMARY_REASONS = 3; + + + /******************************************************************************* ** Utility class. *******************************************************************************/ @@ -79,8 +85,15 @@ public final class VerificationRuns } else { + long problems = result.getBreakCount(); + String summary = result.getBreaks().stream().limit(ALERT_SUMMARY_REASONS).map(b -> b.reason()).collect(Collectors.joining("; ")); + if(problems > ALERT_SUMMARY_REASONS) + { + summary += "; and " + (problems - ALERT_SUMMARY_REASONS) + " more"; + } QAlerts.raise(new AlertSignal("wormaudit.chain.break").withDedupKey("chain") - .withTitle(result.getBreaks().getFirst().reason()).withRecordRef(new AlertRecordRef(WormAuditTables.VERIFICATION, row.getValue("id")))); + .withTitle("Audit chain verification found " + problems + (problems == 1 ? " problem" : " problems")).withSummary(summary) + .withRecordRef(new AlertRecordRef(WormAuditTables.VERIFICATION, row.getValue("id")))); } } return (result); diff --git a/src/test/java/com/kingsrook/qbits/wormaudit/ProcessesAndAlertsTest.java b/src/test/java/com/kingsrook/qbits/wormaudit/ProcessesAndAlertsTest.java index 2c06ffd..bb1842c 100644 --- a/src/test/java/com/kingsrook/qbits/wormaudit/ProcessesAndAlertsTest.java +++ b/src/test/java/com/kingsrook/qbits/wormaudit/ProcessesAndAlertsTest.java @@ -142,7 +142,8 @@ class ProcessesAndAlertsTest assertThat(Sink.raised.getFirst().getDedupKey()).isEqualTo("chain"); assertThat(Sink.raised.getFirst().getRecordRefs().getFirst().getTableName()) .isEqualTo(WormAuditTables.VERIFICATION); - assertThat(Sink.raised.getFirst().getTitle()).contains("Break at link 1"); + assertThat(Sink.raised.getFirst().getTitle()).isEqualTo("Audit chain verification found 1 problem"); + assertThat(Sink.raised.getFirst().getSummary()).contains("Break at link 1"); var first = STORE.all(WormAuditTables.VERIFICATION).getFirst(); assertThat(first.getValueLong("first_break_link_id")).isEqualTo(1); assertThat(first.getValueLong("first_break_audit_id")).isEqualTo(1); -- 2.54.0