feat: ops layer — incidents, maintenance, status pages, badges, metrics (merge plan M4)

incidents + incident_updates + maintenance_windows + status_pages
tables. Monitor transitions auto-open incidents on down and
auto-resolve on recovery; an active maintenance window covering
the monitor suppresses alerts and auto-incidents, and status
pages report the covered monitor as `maintenance`.

Public status view: GET /api/status-pages/:slug/public aggregates
overall state, monitor uptime, systems, open incidents, and
scheduled maintenance; rendered read-only at /status/:slug.

GET /api/badge/:kind/:id.svg serves stateless shields; GET
/api/metrics exposes Prometheus text over existing tables;
POST /api/import/csv?kind=monitors|domains does header-driven
bulk import; /api/export v2 folds monitors/domains/systems rows
into the backup payload.

Frontend: /incidents with timeline + status flow, /status admin
for pages + windows, /status/:slug public page; nav and palette
wired.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Tomas DvorakandDevin committed 2026-09-21 19:21:21 +02:00
1 parent 74c987c18a
commit c84a4be876
17 files changed
+2212 -11

No files matched your search

+7 -7
View File
@@ -182,13 +182,13 @@ Beszel-style server monitoring, push-based.
### Phase M4 — Ops layer → v0.7.0
- [ ] Incidents: `incidents` + `incident_updates`; manual CRUD + auto-open on monitor down, auto-resolve on recovery; severity + status flow (open → ack → resolved → closed)
- [ ] Maintenance windows: `maintenance_windows`; suppress alerts, show `maintenance` state while active
- [ ] Status pages: `status_pages` + `status_page_monitors`; public `/status/:slug` route + public API endpoint
- [ ] Badges: `GET /badge/:kind/:id.svg` — stateless SVG from live data (status/uptime/response/domain/system)
- [ ] `GET /metrics` Prometheus exposition
- [ ] Bulk: CSV import monitors + domains; JSON export folded into existing `/api/export`
- [ ] ⌘K palette + header nav wired for new pages
- [x] Incidents: `incidents` + `incident_updates`; manual CRUD + auto-open on monitor down, auto-resolve on recovery; severity + status flow (open → ack → resolved → closed)
- [x] Maintenance windows: `maintenance_windows` (monitor_ids empty = all); suppress alerts + auto-incidents, status pages show `maintenance` state while active
- [x] Status pages: `status_pages` (monitor_ids/system_ids JSON columns — a join table for ≤ dozens of ids is ceremony); admin `/status`, public `/status/:slug` + `GET /api/status-pages/:slug/public`
- [x] Badges: `GET /api/badge/:kind/:id.svg` — stateless SVG from live data (monitor status+uptime, domain days-left, system status)
- [x] `GET /api/metrics` Prometheus exposition
- [x] Bulk: `POST /api/import/csv?kind=monitors|domains` header-driven CSV; monitors/domains/systems rows folded into `/api/export` (v2, additive)
- [x] ⌘K palette + header nav wired for new pages
## Phase 4 — Open-source launch → v1.0.0