fix(alerting): populate AlertInstance.rule_snapshot so history survives rule delete

- Add withRuleSnapshot(Map) wither to AlertInstance (same pattern as other withers)
- Call snapshotRule(rule) + withRuleSnapshot in both applyResult (single-firing) and
  applyBatchFiring paths so every persisted instance carries a non-empty JSONB snapshot
- Strip null values from the Jackson-serialized map before wrapping in the immutable
  snapshot so Map.copyOf in the compact ctor does not throw NPE on nullable rule fields
- Add ruleSnapshotIsPersistedOnInstanceCreation IT: asserts name/severity/conditionKind
  appear in the rule_snapshot column after a tick fires an instance
- Add historySurvivesRuleDelete IT: fires an instance, deletes the rule, asserts
  rule_id IS NULL and rule_snapshot still contains the rule name (spec §5 guarantee)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-19 20:09:28 +02:00
parent 15c0a8273c
commit bf178ba141
3 changed files with 66 additions and 3 deletions

View File

@@ -92,4 +92,11 @@ public record AlertInstance(
currentValue, threshold, context, title, message,
targetUserIds, targetGroupIds, targetRoleNames);
}
public AlertInstance withRuleSnapshot(Map<String, Object> snapshot) {
return new AlertInstance(id, ruleId, snapshot, environmentId,
state, severity, firedAt, ackedAt, ackedBy, resolvedAt, lastNotifiedAt, silenced,
currentValue, threshold, context, title, message,
targetUserIds, targetGroupIds, targetRoleNames);
}
}