Files
Dash/apps/backend/internal/db/migrations/0006_ops.sql
T
Tomas DvorakandDevin c84a4be876 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>
2026-09-21 19:21:21 +02:00

46 lines
1.7 KiB
SQL

-- +goose Up
CREATE TABLE incidents (
id TEXT PRIMARY KEY,
title TEXT NOT NULL,
severity TEXT NOT NULL DEFAULT 'major', -- minor | major | critical
status TEXT NOT NULL DEFAULT 'open', -- open | ack | resolved | closed
monitor_id TEXT REFERENCES monitors(id) ON DELETE SET NULL,
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now')),
updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now'))
);
CREATE INDEX idx_incidents_status ON incidents(status);
CREATE TABLE incident_updates (
id INTEGER PRIMARY KEY AUTOINCREMENT,
incident_id TEXT NOT NULL REFERENCES incidents(id) ON DELETE CASCADE,
status TEXT NOT NULL,
message TEXT NOT NULL DEFAULT '',
at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now'))
);
CREATE INDEX idx_incident_updates_inc ON incident_updates(incident_id);
CREATE TABLE maintenance_windows (
id TEXT PRIMARY KEY,
title TEXT NOT NULL,
starts_at TEXT NOT NULL,
ends_at TEXT NOT NULL,
monitor_ids TEXT NOT NULL DEFAULT '[]', -- JSON array; empty covers all
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now'))
);
CREATE TABLE status_pages (
id TEXT PRIMARY KEY,
slug TEXT NOT NULL UNIQUE,
title TEXT NOT NULL,
description TEXT NOT NULL DEFAULT '',
monitor_ids TEXT NOT NULL DEFAULT '[]', -- JSON array; empty = all monitors
system_ids TEXT NOT NULL DEFAULT '[]',
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now'))
);
-- +goose Down
DROP TABLE IF EXISTS status_pages;
DROP TABLE IF EXISTS maintenance_windows;
DROP TABLE IF EXISTS incident_updates;
DROP TABLE IF EXISTS incidents;