v1.2.0 Phase C2: location snooze/mute + ack & escalation #102

Merged
claude-bot merged 1 commit from feat/v1.2.0-phaseC2-snooze-escalation into main 2026-07-18 22:08:18 +00:00
Contributor

The final v1.2.0 slice.

#82 — Temporary location snooze / mute

Location.snoozed_until (migration 0022). While snoozed, a location's alerts still record the dashboard-only history row but channel dispatch is suppressed (no notifications); snooze auto-expires (a past value = not snoozed, no cleanup job). POST /api/locations/{id}/snooze (duration or until) + /unsnooze, can-manage-location + CSRF, with a snooze control + "🔕 Snoozed" badge in the UI.

#81 — Acknowledgement + escalation for warnings

Ack + escalation fields on the dashboard SentAlert row (migration 0023). POST /api/alerts/{id}/ack (any viewer, CSRF) + a dashboard "Acknowledge" button. A scheduler job re-notifies active, unacknowledged, warning-class alerts every ESCALATION_INTERVAL_MINUTES, up to ESCALATION_MAX_COUNT, reusing the delivery outbox with kind="escalation" (excluded from the alert-retry worker, so a reminder and a retry can never both fire). Bounds only advance on a successful send; acknowledging, clearing, expiry, or snooze stops escalation (snoozed locations skip without consuming budget). Opt-in via ESCALATION_ENABLED (default off — re-notifying is potentially noisy). snoozed_until now exposed in LocationRead.

Testing

Full suite green on the dev server: 635 passed (18 new tests); migrations 0022/0023 apply cleanly to head on real Postgres.

Notes

  • Ack on the dashboard's grouped multi-location cards acks the representative location's lifecycle (correct per the per-(alert, location) model); acking every location behind one shared nws_alert_id in one click is a possible UX follow-up.

Closes #82, #81

🤖 Generated with Claude Code

The final v1.2.0 slice. ## #82 — Temporary location snooze / mute `Location.snoozed_until` (migration `0022`). While snoozed, a location's alerts still record the dashboard-only history row but **channel dispatch is suppressed** (no notifications); snooze auto-expires (a past value = not snoozed, no cleanup job). `POST /api/locations/{id}/snooze` (duration or `until`) + `/unsnooze`, can-manage-location + CSRF, with a snooze control + "🔕 Snoozed" badge in the UI. ## #81 — Acknowledgement + escalation for warnings Ack + escalation fields on the dashboard `SentAlert` row (migration `0023`). `POST /api/alerts/{id}/ack` (any viewer, CSRF) + a dashboard "Acknowledge" button. A scheduler job re-notifies **active, unacknowledged, warning-class** alerts every `ESCALATION_INTERVAL_MINUTES`, up to `ESCALATION_MAX_COUNT`, reusing the **delivery outbox** with `kind="escalation"` (excluded from the alert-retry worker, so a reminder and a retry can never both fire). Bounds only advance on a *successful* send; acknowledging, clearing, expiry, or snooze stops escalation (snoozed locations skip without consuming budget). **Opt-in** via `ESCALATION_ENABLED` (default off — re-notifying is potentially noisy). `snoozed_until` now exposed in `LocationRead`. ## Testing Full suite green on the dev server: **635 passed** (18 new tests); migrations `0022`/`0023` apply cleanly to head on real Postgres. ## Notes - Ack on the dashboard's grouped multi-location cards acks the representative location's lifecycle (correct per the per-`(alert, location)` model); acking every location behind one shared `nws_alert_id` in one click is a possible UX follow-up. Closes #82, #81 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Add location snooze/mute and warning acknowledgement + escalation
All checks were successful
CI / test (pull_request) Successful in 4m12s
b6f749686f
Snooze (#82): a nullable Location.snoozed_until (migration 0022). While a location
is snoozed, its alerts still record the dashboard-only history row but channel
dispatch is suppressed; snooze auto-expires. POST /api/locations/{id}/snooze +
/unsnooze (can-manage-location, CSRF) and a snooze control + badge in the UI.

Acknowledgement + escalation (#81): ack/escalation fields on the dashboard
SentAlert row (migration 0023). POST /api/alerts/{id}/ack (any viewer, CSRF) plus
a dashboard "Acknowledge" action. A scheduler job re-notifies active,
unacknowledged, warning-class alerts every ESCALATION_INTERVAL_MINUTES up to
ESCALATION_MAX_COUNT, reusing the delivery outbox with kind="escalation" (excluded
from the alert-retry worker so reminders can't double-send). Bounds only advance
on a successful send; snoozed locations are skipped without consuming budget.
Opt-in via ESCALATION_ENABLED (default off). snoozed_until exposed in LocationRead.

Full suite green on the dev server: 635 passed; migrations 0022/0023 apply cleanly.

Closes #82, #81

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
claude-bot deleted branch feat/v1.2.0-phaseC2-snooze-escalation 2026-07-18 22:08:18 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
rbrooks/WeatherBot!102
No description provided.