Commit Graph

16 Commits

Author SHA1 Message Date
pulse-triage[bot] 0f2d7ae055 Make notification delivery failures actionable 2026-08-31 00:39:53 +01:00
Pulse Test 5ee1cdd002 Make informational alerts a first-class severity 2026-08-28 00:45:20 +01:00
Pulse Test ff6c6a7fe7 Make mock alert history lifecycle-consistent 2026-08-27 23:36:55 +01:00
rcourtman 8ade613dfd Add complete mock alert timelines 2026-08-27 22:04:26 +01:00
rcourtman 1878245cdb Make alert incident timelines complete 2026-08-27 21:42:25 +01:00
pulse-triage[bot] 5f6bfefa56 Make notification destination updates durable 2026-08-27 19:46:40 +01:00
rcourtman 8df9db7ab1 feat(alerts): add destination severity routing 2026-08-27 19:13:32 +01:00
rcourtman ff507a6e44 feat(alerts): add per-alert snooze 2026-08-27 17:20:32 +01:00
rcourtman f4e1e47e74 feat(alerts): add external dead-man monitoring 2026-08-27 16:27:46 +01:00
pulse-triage[bot] 30b4fbd95e test(notifications): isolate terminal recovery paths 2026-08-27 16:08:53 +01:00
rcourtman 9572a113ae feat(alerts): append-only alert event log with suppression reasons
Adds internal/alerts/eventlog: a SQLite-backed, additive event log that
records lifecycle transitions (resolved, acknowledged, unacknowledged,
escalated, flapping detected) and notification decisions (dispatched,
deferred by quiet hours, suppressed — with the mechanism that held
them). Appends never block alert evaluation: a full buffer drops the
event and counts the drop; a store that fails to open degrades to
recording nothing. 90-day retention, hourly prune.

The manager emits at the existing funnels only — dispatchAlert and the
safe-call resolve/ack/escalate seams — so no lifecycle behavior
changes. Lifecycle "fired" is deliberately not recorded yet: the
active-alert store funnel also runs on persisted restore, so firing
waits for the explicit activation seam in a later phase. The monitoring
bootstrap enables the log per manager; ephemeral managers and tests
record nothing unless they opt in.

GET /api/alerts/events (monitoring:read) reads the log with
alertIdentifier/type/since/limit filters, newest first.

Phase 0 of docs/ALERT_ENGINE_EVOLUTION.md (coverage gap
alert-engine-suppression-observability).
2026-08-26 21:15:37 +01:00
rcourtman 515aa319e8 feat(alerts): bulk delivery diagnosis for all active alerts
GET /api/alerts/delivery-diagnosis without alertIdentifier now returns
the diagnosis array for every active alert in one manager pass, so list
surfaces do not need a request per alert. Extracts the per-alert
diagnosis into a locked helper shared by both paths; single-alert
behavior is unchanged.

First slice of coverage gap alert-engine-suppression-observability
(docs/ALERT_ENGINE_EVOLUTION.md Phase 0).
2026-08-26 21:05:37 +01:00
rcourtman cba1e2abeb Reconcile delivery health and Proxmox Assistant controls 2026-08-26 18:33:41 +01:00
rcourtman a7f87471f4 Stop returning the stored Apprise API key from the notifications API
GET /api/notifications/apprise and the PUT echo returned the saved API key
verbatim, so any settings:read token could exfiltrate a write-capable
secret while the sibling email handler blanks the SMTP password under the
same scope. Responses now drop the key and report hasApiKey instead, the
update and test-send paths fall back to the saved key when the request
leaves it blank (matching the email password contract), and the settings
form tells the user a saved key is kept when the field stays empty.
2026-08-23 14:39:07 +01:00
rcourtman bce5564025 fix notification terminal failure recovery 2026-08-23 09:05:54 +01:00
rcourtman 58bf77c1ae Extract alert delivery API package 2026-08-21 14:56:04 +01:00