fix(alerting/B-1): PostgresAlertRuleRepository.save() now persists alert_rule_targets
saveTargets() is called unconditionally at the end of save() — it deletes existing targets and re-inserts from the current targets list. findById() and listByEnvironment() already call withTargets() so reads are consistent. PostgresAlertRuleRepositoryIT adds saveTargets_roundtrip and saveTargets_updateReplacesExistingTargets to cover the new write path. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -66,6 +66,44 @@ class PostgresAlertRuleRepositoryIT extends AbstractPostgresIT {
|
||||
assertThat(repo.findRuleIdsByOutboundConnectionId(UUID.randomUUID())).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void saveTargets_roundtrip() {
|
||||
// Rule saved with a USER target and a ROLE target
|
||||
UUID ruleId = UUID.randomUUID();
|
||||
AlertRuleTarget userTarget = new AlertRuleTarget(UUID.randomUUID(), ruleId, TargetKind.USER, "alice");
|
||||
AlertRuleTarget roleTarget = new AlertRuleTarget(UUID.randomUUID(), ruleId, TargetKind.ROLE, "OPERATOR");
|
||||
var rule = newRuleWithId(ruleId, List.of(), List.of(userTarget, roleTarget));
|
||||
|
||||
repo.save(rule);
|
||||
|
||||
// findById must return the targets that were persisted by saveTargets()
|
||||
var found = repo.findById(ruleId).orElseThrow();
|
||||
assertThat(found.targets()).hasSize(2);
|
||||
assertThat(found.targets()).extracting(AlertRuleTarget::targetId)
|
||||
.containsExactlyInAnyOrder("alice", "OPERATOR");
|
||||
assertThat(found.targets()).extracting(t -> t.kind().name())
|
||||
.containsExactlyInAnyOrder("USER", "ROLE");
|
||||
}
|
||||
|
||||
@Test
|
||||
void saveTargets_updateReplacesExistingTargets() {
|
||||
// Save rule with one target
|
||||
UUID ruleId = UUID.randomUUID();
|
||||
AlertRuleTarget initial = new AlertRuleTarget(UUID.randomUUID(), ruleId, TargetKind.USER, "bob");
|
||||
var rule = newRuleWithId(ruleId, List.of(), List.of(initial));
|
||||
repo.save(rule);
|
||||
|
||||
// Update: replace with a different target
|
||||
AlertRuleTarget updated = new AlertRuleTarget(UUID.randomUUID(), ruleId, TargetKind.GROUP, "team-ops");
|
||||
var updated_rule = newRuleWithId(ruleId, List.of(), List.of(updated));
|
||||
repo.save(updated_rule);
|
||||
|
||||
var found = repo.findById(ruleId).orElseThrow();
|
||||
assertThat(found.targets()).hasSize(1);
|
||||
assertThat(found.targets().get(0).targetId()).isEqualTo("team-ops");
|
||||
assertThat(found.targets().get(0).kind()).isEqualTo(TargetKind.GROUP);
|
||||
}
|
||||
|
||||
@Test
|
||||
void claimDueRulesAtomicSkipLocked() {
|
||||
var rule = newRule(List.of());
|
||||
@@ -80,11 +118,15 @@ class PostgresAlertRuleRepositoryIT extends AbstractPostgresIT {
|
||||
}
|
||||
|
||||
private AlertRule newRule(List<WebhookBinding> webhooks) {
|
||||
return newRuleWithId(UUID.randomUUID(), webhooks, List.of());
|
||||
}
|
||||
|
||||
private AlertRule newRuleWithId(UUID id, List<WebhookBinding> webhooks, List<AlertRuleTarget> targets) {
|
||||
return new AlertRule(
|
||||
UUID.randomUUID(), envId, "rule-" + UUID.randomUUID(), "desc",
|
||||
id, envId, "rule-" + id, "desc",
|
||||
AlertSeverity.WARNING, true, ConditionKind.AGENT_STATE,
|
||||
new AgentStateCondition(new AlertScope(null, null, null), "DEAD", 60),
|
||||
60, 0, 60, "t", "m", webhooks, List.of(),
|
||||
60, 0, 60, "t", "m", webhooks, targets,
|
||||
Instant.now().minusSeconds(10), null, null, Map.of(),
|
||||
Instant.now(), "test-user", Instant.now(), "test-user");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user