• v1.4.0 adac7d9a3f

    v1.4.0
    All checks were successful
    CD / test (push) Successful in 3m35s
    CD / deploy (push) Successful in 25s
    Stable

    claude-bot released this 2026-07-19 04:36:59 +00:00 | 122 commits to main since this release

    Tech-debt and structure work from the 2026-07-17 audit (F-18, F-19, F-24, F-30). No breaking changes; one user-visible feature addition.

    Added

    • SPC fire-weather Day 2 (#63) — fire-weather outlook coverage now includes Day 2 (categorical ELEV/CRIT/EXTR), matching the Day 1-3 convective coverage. Previously only Day-1 fire geometry was fetched while the Day-2 text was fetched every poll and discarded.

    Changed — structure

    • Dashboard assembly extracted from main.py (#58) — the / route is now auth + a build_dashboard_context() service call + render (~10 lines, from ~318). The 13-request live SPC fan-out on every page load is gone; the dashboard reads SPC outlooks from the records poll_spc_dashboard already maintains, so a load makes zero direct SPC upstream requests.
    • Consolidated the two drifted SPC match-context builders into one shared implementation (#58).

    Fixed

    • ORM ↔ DB index metadata drift (#57) — models now reproduce the live schema exactly, so alembic revision --autogenerate yields an empty diff. Also restored the missing alembic/script.py.mako (absent since init — alembic revision failed on a fresh clone without it).
    • Dashboard-dedup NULL gap (#57) — a partial unique index (nws_alert_id, location_id WHERE channel_id IS NULL) now enforces uniqueness that Postgres NULL semantics left unprotected. The migration de-duplicates existing rows first (this had accumulated to 18 groups / up to 147 copies on the dev DB), and the racing poll_spc / poll_spc_dashboard dashboard inserts are now savepoint-guarded (#109).
    • UI consistency pass (#69)✕ encoding fix, confirm() parity, double-submit guards, inline error surfacing (replacing alert()), aria-labels on icon-only buttons, a defined --color-accent, and removal of a dead unreachable afterSwap JSON block.

    Testing

    ruff clean; bulk suite 670 passed; Postgres tier 4 passed. Migration verified against a restored copy of the real dev DB (de-dup to zero, index created). PRs: #107 (Phase 1), #108 (Phase 2), #109 (deploy hotfix), #110 (Phase 3), #111 (changelog).

    Downloads