refactor(alerts): drop ACKNOWLEDGED from AlertState, add readAt/deletedAt to AlertInstance

- AlertState: remove ACKNOWLEDGED case (V17 migration already dropped it from DB enum)
- AlertInstance: insert readAt + deletedAt Instant fields after lastNotifiedAt; add withReadAt/withDeletedAt withers; update all existing withers to pass both fields positionally
- AlertStateTransitions: add null,null for readAt/deletedAt in newInstance ctor call; collapse FIRING,ACKNOWLEDGED switch arm to just FIRING
- AlertScopeTest: update AlertState.values() assertion to 3 values; fix stale ConditionKind.hasSize(6) to 7 (JVM_METRIC was added earlier)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-21 17:12:37 +02:00
parent e95c21d0cb
commit 82e82350f9
4 changed files with 34 additions and 16 deletions

View File

@@ -28,7 +28,7 @@ public final class AlertStateTransitions {
/**
* Apply an EvalResult to the current open AlertInstance.
*
* @param current the open instance for this rule (PENDING / FIRING / ACKNOWLEDGED), or null if none
* @param current the open instance for this rule (PENDING / FIRING), or null if none
* @param result the evaluator outcome
* @param rule the rule being evaluated
* @param now wall-clock instant for the current tick
@@ -50,7 +50,7 @@ public final class AlertStateTransitions {
private static Optional<AlertInstance> onClear(AlertInstance current, Instant now) {
if (current == null) return Optional.empty(); // no open instance — no-op
if (current.state() == AlertState.RESOLVED) return Optional.empty(); // already resolved
// Any open state (PENDING / FIRING / ACKNOWLEDGED) → RESOLVED
// Any open state (PENDING / FIRING) → RESOLVED
return Optional.of(current
.withState(AlertState.RESOLVED)
.withResolvedAt(now));
@@ -84,8 +84,8 @@ public final class AlertStateTransitions {
// Still within forDuration — stay PENDING, nothing to persist
yield Optional.empty();
}
// FIRING / ACKNOWLEDGED — re-notification cadence handled by the dispatcher
case FIRING, ACKNOWLEDGED -> Optional.empty();
// FIRING — re-notification cadence handled by the dispatcher
case FIRING -> Optional.empty();
// RESOLVED should never appear as the "current open" instance, but guard anyway
case RESOLVED -> Optional.empty();
};
@@ -126,6 +126,8 @@ public final class AlertStateTransitions {
null, // ackedBy
null, // resolvedAt
null, // lastNotifiedAt
null, // readAt
null, // deletedAt
false, // silenced
f.currentValue(),
f.threshold(),