Populate tenant_id on new alert_state/delivery_log rows

Phase 4 added a NOT NULL tenant_id column to both tables (migrations
0022/0023, backfilled via a join through alert_rules.id), but Store's
Create and ApplyTransition were never updated to populate it on new
inserts -- every existing row already had a value from the backfill,
which is exactly why this went uncaught: nothing created a *new* rule
against a Phase-4-or-later database until now. Every alert rule
creation since those migrations landed was silently broken.

Create's alert_state insert now passes rule.TenantID explicitly.
ApplyTransition only receives a rule ID, not a full Rule, so its
delivery_log insert resolves tenant_id via a subquery against
alert_rules. Confirmed against a live stack: rule creation, evaluation,
firing, and a real delivery attempt all completed end to end.
This commit is contained in:
2026-08-16 12:36:21 -07:00
parent 8ec370dcee
commit 9862bcccae
+4 -4
View File
@@ -137,8 +137,8 @@ func (s *Store) Create(ctx context.Context, r *Rule) error {
}
_, err = tx.Exec(ctx, `
INSERT INTO alert_state (rule_id, state, last_eval_status, next_eval_at)
VALUES ($1, 'ok', 'ok', now())`, r.ID)
INSERT INTO alert_state (rule_id, tenant_id, state, last_eval_status, next_eval_at)
VALUES ($1, $2, 'ok', 'ok', now())`, r.ID, r.TenantID)
if err != nil {
return fmt.Errorf("inserting initial alert_state: %w", err)
}
@@ -293,8 +293,8 @@ func (s *Store) ApplyTransition(ctx context.Context, ruleID string, next AlertSt
if notify != nil {
_, err = tx.Exec(ctx, `
INSERT INTO delivery_log (rule_id, notification_target_id, event_type, status, next_attempt_at, payload)
VALUES ($1, $2, $3, 'pending', now(), $4)`,
INSERT INTO delivery_log (rule_id, tenant_id, notification_target_id, event_type, status, next_attempt_at, payload)
VALUES ($1, (SELECT tenant_id FROM alert_rules WHERE id = $1), $2, $3, 'pending', now(), $4)`,
ruleID, notify.NotificationTargetID, notify.EventType, notify.Payload)
if err != nil {
return fmt.Errorf("inserting delivery_log outbox row: %w", err)