store: migration 0013 — alerts.last_seen_at

This commit is contained in:
2026-05-04 19:16:59 +01:00
parent 4b70939ab5
commit e6d965d7a5
2 changed files with 49 additions and 0 deletions
+33
View File
@@ -0,0 +1,33 @@
package store
import (
"context"
"path/filepath"
"testing"
)
func TestMigration0013AlertsLastSeen(t *testing.T) {
t.Parallel()
dir := t.TempDir()
st, err := Open(context.Background(), filepath.Join(dir, "rm.db"))
if err != nil {
t.Fatalf("open: %v", err)
}
defer st.Close()
// Column must exist after migration. Best signal: PRAGMA table_info.
rows, err := st.DB().Query(`SELECT name FROM pragma_table_info('alerts')`)
if err != nil {
t.Fatalf("pragma: %v", err)
}
defer rows.Close()
cols := map[string]bool{}
for rows.Next() {
var n string
_ = rows.Scan(&n)
cols[n] = true
}
if !cols["last_seen_at"] {
t.Fatalf("alerts.last_seen_at not present after migration; cols=%v", cols)
}
}
@@ -0,0 +1,16 @@
-- 0013_alerts_last_seen.sql
--
-- Add alerts.last_seen_at to support open-alert dedup with
-- recurrence-tracking. The engine bumps this column on every tick
-- where a rule still matches an existing open alert, so the UI can
-- render "still happening · Ns ago" without sending a fresh
-- notification.
--
-- Column-level ALTER per CLAUDE.md (no rebuild — alerts has inbound
-- FK from acknowledged_by → users; rebuild would risk cascade).
-- Backfill last_seen_at = created_at for any pre-existing rows so
-- the column is non-null in practice (stays nullable in the schema
-- for forwards-compat with rows that haven't been touched yet).
ALTER TABLE alerts ADD COLUMN last_seen_at TEXT;
UPDATE alerts SET last_seen_at = created_at WHERE last_seen_at IS NULL;