Files
ServerKit/backend/app
Juan DenisandClaude Opus 4.8 6ef998515d feat(wordpress): per-site uptime + auto-incidents (#26)
Make a managed WordPress site appear on a status page with a real uptime %
and auto-incidents, driven by an autonomous server-side health poller.

Scheduler: a single-worker-guarded daemon thread (_start_health_check_
scheduler, 300s) runs EnvironmentHealthService.check_health for every RUNNING
production site (skips archived/stopped so an intentional stop is not an
outage). This keeps health_status fresh autonomously — so #27's transition
alerts fire without the browser health card open — and drives bound
status-page components. HealthCheck samples are pruned to 90 days (once/day)
to bound growth.

Schema (Alembic 010 + the boot-time _fix_missing_columns auto-add):
- status_components.wordpress_site_id  (-> wordpress_sites)
- status_incidents.component_id        (-> status_components)
The existing HealthCheck table is reused as the uptime sample store.

StatusPageService.sync_component_from_health maps the health verdict
(healthy->operational, degraded->degraded, unhealthy->major_outage; unknown
skipped), records a HealthCheck, recomputes a real COUNT-based uptime %
(24h/7d/30d/90d; only fully-healthy checks count), and auto-opens an incident
on ENTERING a major outage / auto-resolves on LEAVING it (operational OR
degraded, so a degraded intermediate never strands the incident).

Routes GET/POST/DELETE /sites/<id>/status-page read the binding + attach
(production-only) / detach (resolves & unlinks the incident first -> no
dangling FK on PostgreSQL, no stale public incident). New Uptime tab on the
site detail (health + uptime % + attach/detach).

Security: internal probe config (check_target, intervals) is stripped from the
unauthenticated public-page projection, and a health-driven component stores
no internal localhost:port target.

Review fixes (3-lens adversarial pass): incident-resolve edge for the
degraded-recovery path; detach FK/orphan cleanup in delete_component; public
check_target leak; production-only attach; uptime-prune; degraded-uptime
semantics documented. Verified: backend py_compile, frontend lint + build.
Not runtime-exercised on a real Docker host (Windows dev).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 00:47:26 -04:00
..