Skip to content

Add incidents and scheduled maintenance#102

Draft
lewispb wants to merge 5 commits into
public-status-polishfrom
incidents-and-maintenance
Draft

Add incidents and scheduled maintenance#102
lewispb wants to merge 5 commits into
public-status-polishfrom
incidents-and-maintenance

Conversation

@lewispb

@lewispb lewispb commented Jul 2, 2026

Copy link
Copy Markdown
Member

Adds operator-authored incidents and scheduled maintenance to the status page.

Model

  • Incident (STI base + reactive incident) with a shared IncidentUpdate timeline and IncidentAffectedService links (services are FrozenRecord, so linked by code).
  • Maintenance < Incident — planned window (starts_at/ends_at), impact forced to maintenance, own lifecycle.
  • Behaviour lives in concerns: Incidents::Lifecycle (scopes + record_update) and Services::MaintenanceStatus (mixed into Service).

Status stays probe-derived — an incident is a narrative overlay, not a status source.

Behaviour

  • Active maintenance suppresses its services from the live degraded alarm and shows a blue "under maintenance" state; a real (probe-detected) outage still outranks maintenance for the top-level banner.
  • Public page gains an active-events banner, an upcoming-maintenance section, and feed items.
  • Admin CRUD under /incidents (authenticated), linked from the header nav.
  • A recurring job advances maintenance windows scheduled → in_progress → completed.

Not included (deferred)

  • Excluding maintenance windows from the uptime fraction (cosmetic suppression only for now).
  • Subscriber email/SMS notifications and pre-start reminders.

Notes

  • Persistent-DB migration (create_upright_incidents) plus persistent_schema update.
  • The recurring job must be scheduled and the persistent migration run in the host app deploy; those live in the host repo.
  • 17 model/concern tests added and passing.

lewispb added 5 commits July 2, 2026 12:05
Operator-authored incidents and scheduled maintenance windows, shown on the
public status page and managed from the admin area.

Maintenance is modelled as an STI subclass of Incident, sharing the update
timeline and affected-service links. Status is probe-derived, so an incident is
a narrative overlay rather than a status source; an active maintenance suppresses
its services from the live alarm and shows an "under maintenance" state, while a
real outage still outranks it for the top-level banner. A recurring job advances
maintenance windows through their lifecycle.
Rebuild the incident/maintenance index and form with a status-spine visual
language: a colored rail that adopts the public-page status colour as impact
and kind are chosen, a segmented type toggle, a colour-swatch impact picker,
service chips, and a lifecycle stepper and timeline on edit. Keep native
datetime-local inputs, made legible in dark mode via color-scheme.

Also give admin pages meaningful titles via a content_for-driven layout title.
Add a public permalink for each incident and maintenance with its full update
timeline, linked from the status page cards and the RSS feed. An active
incident's impact now raises the top-level banner alongside probe-derived
status (worst wins; maintenance stays lowest).

Refactor to house style: incidents seed their default status and first update
via model callbacks so the controller just builds and saves, params.expect for
strong params, conditional checks over guard returns, and a page_title_tag
helper driving per-page titles. Document the dummy-app test/DB workflow.
A display name isn't unique across probes — an HTTP and a traceroute check
can share one — so keying ProbeRollup on (probe_name, period_start) collided
them into a single row, silently dropping one probe's uptime and its
probe_service for the day. On the public status page that left the affected
service showing no history at all.

Add probe_type/probe_target to the rollup and dedupe on the full probe
identity. Elevate [name, type, probe_target] as probe_key on Probeable and
its Probes::Status::Probe value object, reused by Status#build_probes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant