The Monitors list now opens with a count strip (down, up with how many
degraded, pending, paused) and sorts down, degraded, pending, up, paused,
by name within each. Degraded is up but worth a look: uptime at or below
its warning floor, or the latest response past its critical cutoff, both
from Settings → Thresholds; a slow-but-tolerable reply is coloured, not
sorted.
A monitor had no page of its own: every link went to the list. Now
/monitors/<id> shows its state and since when, latency, uptime for 24h/7d/
30d, TLS days, the last checks, recent failures with their errors, and its
settings (HTTP header names, never their values). Status links to it, and
adding or editing returns to it.
Adding is its own page (/monitors/new, form.html shared with edit) behind
an "Add monitor" button; a refused add re-renders the form with the error
and what was typed instead of a bare 400 text. Row actions are labelled
icon buttons, type names read Ping/TCP/DNS/HTTP (|monitor_type), and the
heartbeat uses pill-up/pill-down, so HEX_CEILING drops to 56.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#5120 "Status page: what is wrong first".
- A "Needs attention" card heads the Status board: each down monitor with
how long it has been down, and each active alert (firing, acknowledged,
pending, no data) with its condition and how long, linking to its history.
- StatusEntry.since / since_at_least: when the current up/down run began,
from the recent checks (streak_start); "for at least" when every check we
have agrees.
- Counts as stat tiles (Down, Active alerts, Pending, Up); names wrap
instead of being cut off; dots carry their label.
- Uptime and TLS are coloured by status_class against Settings → Thresholds
instead of literal cutoffs; heartbeat pills and DOWN/UP use tokens and
status_badge rather than hex and bold.
- tests/core/test_status_page.py: streak_start cases, and the rows render
with the problem card before the list, each since-time, threshold tones
and no hex colour.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds a Kuma-style "is everything up?" surface that aggregates heterogeneous
monitor types via a status-source registry (steward/core/status.py): each
type registers an async source(db) -> [StatusEntry]. Core registers ping/DNS;
the http plugin registers its own from setup() so core never imports plugin
tables. Per entry: current up/down, last-30 heartbeat bar, uptime %
(24h/7d/30d), latest latency + response sparkline, and TLS expiry countdown
(HTTP). New /status page (live htmx refresh) + a status_overview dashboard
widget + nav link. Pure-function unit tests for registry + sparkline.
First deliverable of milestone #68 (task #866).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>