v1.5.0 Phase 3: radar-at-alert-time snapshot (#85) + activity/stats view (#83) #114

Merged
claude-bot merged 2 commits from feat/v1.5.0-phase3-radar-stats into main 2026-07-19 15:45:08 +00:00
Contributor

Two v2.0.0-Explorer down-payments.

#85 — radar snapshot at alert time (opt-in)

Off by default (ALERT_RADAR_SNAPSHOT_ENABLED). When on, the first time an alert fires for a location the current radar image is captured and attached to the dashboard record, so the public alert page and the future Historical Explorer (#22) can show conditions at the moment the alert was issued.

  • SentAlert.radar_snapshot_path + radar_snapshot_at (migration 0027, nullable).
  • Capture is best-effort and fully decoupled from dispatch: after the dashboard record commits, a tracked background task fetches the radar PNG and writes it in its own session; any failure just logs and leaves the columns null. Only the dashboard record triggers it; dedup hits don't re-capture.
  • Served by GET /media/alert-radar/{sent_alert_id}.png (immutable long-TTL, filename re-validated + traversal-guarded). Shown as a "Radar at alert time (HH:MM local)" panel on public_alert.html, distinct from live radar.
  • Retention cleans orphan snapshot files in the daily job.
  • Assumes radar_cache_dir is a persistent volume (as the existing SPC cache already is).

#83 — activity / statistics view

GET /stats ("Activity" nav): counts off the retained sent_alerts dashboard records — a deliberately lightweight slice of #22, not a competing build.

  • Totals + breakdowns by location, event type (top 15 + "other"), and month, over channel_id IS NULL rows, restricted to visible locations. Month grouping done in Python for dialect portability.
  • Self-contained stats.html (simple bars/tables, no chart library); graceful empty state; readonly users may view.

Testing (dev server)

ruff clean; 14 new feature tests; bulk suite 723 passed; migration 0027 applied on a restored copy of the real dev DB (both columns present, applies from dev's current 0026).

Closes #83, #85

🤖 Generated with Claude Code

Two v2.0.0-Explorer down-payments. ## #85 — radar snapshot at alert time (opt-in) Off by default (`ALERT_RADAR_SNAPSHOT_ENABLED`). When on, the first time an alert fires for a location the current radar image is captured and attached to the dashboard record, so the public alert page and the future Historical Explorer (#22) can show conditions **at the moment the alert was issued**. - `SentAlert.radar_snapshot_path` + `radar_snapshot_at` (migration **0027**, nullable). - Capture is **best-effort and fully decoupled from dispatch**: after the dashboard record commits, a tracked background task fetches the radar PNG and writes it in its own session; any failure just logs and leaves the columns null. Only the dashboard record triggers it; dedup hits don't re-capture. - Served by `GET /media/alert-radar/{sent_alert_id}.png` (immutable long-TTL, filename re-validated + traversal-guarded). Shown as a "Radar at alert time (HH:MM local)" panel on `public_alert.html`, distinct from live radar. - Retention cleans orphan snapshot files in the daily job. - Assumes `radar_cache_dir` is a persistent volume (as the existing SPC cache already is). ## #83 — activity / statistics view `GET /stats` ("Activity" nav): counts off the retained `sent_alerts` dashboard records — a deliberately lightweight slice of #22, not a competing build. - Totals + breakdowns by location, event type (top 15 + "other"), and month, over `channel_id IS NULL` rows, restricted to visible locations. Month grouping done in Python for dialect portability. - Self-contained `stats.html` (simple bars/tables, no chart library); graceful empty state; readonly users may view. ## Testing (dev server) ruff clean; 14 new feature tests; bulk suite **723 passed**; migration 0027 applied on a **restored copy of the real dev DB** (both columns present, applies from dev's current 0026). Closes #83, #85 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Off by default (ALERT_RADAR_SNAPSHOT_ENABLED). When on, the first time an alert
fires for a location, the current radar image is captured and attached to the
dashboard record so the public alert page — and the future v2.0.0 Historical
Explorer (#22) — can show conditions at the moment the alert was issued.

- SentAlert gains nullable radar_snapshot_path + radar_snapshot_at (migration 0027).
- Capture is best-effort and fully decoupled from dispatch: after the dashboard
  record commits, a tracked background task fetches radar._fetch_radar(...) and
  writes {radar_cache_dir}/alert_snapshots/{lifecycle}__{location}.png in its own
  session; any failure just logs and leaves the columns null. Only the dashboard
  record (channel_id IS NULL) triggers it; dedup hits don't re-capture.
- Served by GET /media/alert-radar/{sent_alert_id}.png (immutable long-TTL,
  filename re-validated + path-traversal guarded).
- public_alert.html shows a "Radar at alert time (HH:MM local)" panel when present,
  distinct from live radar.
- Retention: orphan snapshot files (no surviving referencing row) are cleaned in
  the daily job.

Assumes radar_cache_dir is a persistent volume (as the existing SPC cache already
is), else snapshots and their DB paths can drift across container rebuilds.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add alert activity / statistics view (#83)
All checks were successful
CI / test (pull_request) Successful in 4m14s
a9b40c64c7
GET /stats ("Activity" nav): a lightweight down-payment on the v2.0.0 Historical
Explorer (#22) — counts off the sent_alerts dashboard records already retained.

- Totals + breakdowns by location, by event type (top 15 + "other"), and by month,
  over channel_id IS NULL rows (no per-channel double counting), restricted to
  locations visible to the user (visible_location_filter). Month grouping is done in
  Python to stay dialect-portable (Postgres date_trunc vs SQLite).
- Self-contained stats.html (simple bars/tables, no chart library); graceful empty
  state; readonly users may view (mirrors /alerts). Framed in-code as a #22
  down-payment, not a competing build.

Full suite green on the dev server: 723 passed; migration 0027 verified on a
real-DB copy.

Closes #83, #85

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
claude-bot deleted branch feat/v1.5.0-phase3-radar-stats 2026-07-19 15:45:08 +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!114
No description provided.