Skip to content

Data model

The schema is defined in lib/db/schema.ts. Enum values are declared as constants in the same file and reused by the Zod validators and the UI, so the database, the validation and the forms cannot drift apart.

Core entities

Table Purpose
component_groups Named groups of services. Group names are globally unique.
components Services (called "components" in the schema). Hold the current status cache, the mode (service_status), owner, notification settings, SLA targets, SLA plan, incident SLA metrics and uptime-check configuration. Service names are unique per group.
component_status_events Append-only history of active status windows per component. See Status model.
incidents Incident header: title, impact, lifecycle status, occurred, responded and resolved timestamps, review and close data.
incident_updates Public timeline entries of an incident (including the automatic occurred entry).
incident_components Affected components of an incident, with optional exact outage window per component.
incident_notes Private internal team notes. Never visible publicly.
maintenances Scheduled maintenance windows with start/end, status and notification markers.
maintenance_components Components affected by a maintenance window.

SLA entities

Table Purpose
sla_plans / sla_plan_entries A plan defines one time window (from–to in minutes) per weekday. from == to means closed. The plan also holds the optional holiday list, the holiday window and the option ignore_outages_during_maintenance.
holiday_lists / holiday_list_dates Holidays per list. A date with year NULL recurs yearly; a date with a year applies once.
sla_reports Reports for month, quarter or year, with status open → in_progress → confirmed → completed. confirmed_snapshot holds the report frozen on confirmation (since #349 including the calculation time zone timeZone), report_data the result at the time of Generate. pdf_path is only a marker for whether the list shows the download links. No file is stored.
sla_report_outages One row per outage in a monthly report that must be confirmed (to_confirm / confirmed).

Platform entities

Table Purpose
settings Singleton row (CHECK (id = 1)) with site configuration. Secrets are stored encrypted.
users Team accounts with role (admin, service_manager, service_owner, sla_manager) and session_version (used to revoke sessions).
subscribers Public and admin-managed e-mail recipients, with double opt-in state.
notification_templates One row per event type with per-channel enable flags. Missing row means "do not send".
notification_events Log of e-mail notifications with status pending → processing → sent | failed. sent_chunks counts the recipient chunks already delivered, so retries never deliver twice.
webhook_endpoints / webhook_deliveries Webhook targets and delivery attempts.
sms_recipients / sms_deliveries SMS recipients and delivery attempts.
push_subscriptions / push_deliveries Browser push subscriptions and delivery attempts.
uptime_check_results Results of automatic HTTP checks, with response time and retention.
api_tokens / api_token_components Hashed API tokens, optional expiry, revocation and service scope.
auth_throttle Rate-limit counters: failed login and token attempts per client IP, and requests of the public forms per IP and per address (publicform:…).
audit_log Append-only log of all mutating admin actions with before/after JSON.
__drizzle_migrations Migration journal maintained by scripts/migrate.ts.

Invariants worth knowing

  • components.status is a cache of the most severe open window. It is only written together with the status windows (setComponentsStatusTx).
  • maintenances_end_after_start_chk enforces scheduled_end > scheduled_start.
  • sla_reports_month_period_chk enforces how the month column is interpreted per period: calendar month (1–12) for monthly reports, the first month of the quarter (1/4/7/10) for quarterly reports, and 1 for yearly reports.
  • CHECKs on sla_plan_entries: day_of_week 0–6, from_min 0–1439, to_min 0–1440.
  • holiday_list_dates_unique_date prevents duplicate dates in a holiday list.
  • settings_singleton_chk guarantees exactly one settings row. If the row is missing, getSettings() returns complete defaults.
  • incident_notes and audit_log are append-only at the application level.