OpenNIT

Quelltext des aktuellen Standes

Fassung 1.1.1

233_status_subscribers.sql

3 KB
-- Migration 233: Statusseite – Besucher über Störungen benachrichtigen
--
-- Wer wissen will, ob eine Störung begonnen hat oder behoben ist, musste die
-- Statusseite selbst aufrufen. Besucher können ihre Adresse jetzt eintragen
-- und bekommen beide Nachrichten zugeschickt.
--
-- Der Versand läuft über eine Warteschlange statt direkt aus dem Request: Eine
-- Störung wird gemeldet, während Leute darauf warten – das Melden darf nicht
-- so lange dauern, wie der Mailserver für hundert Adressen braucht.

-- ------------------------------------------------------------
-- 1. Eintragungen
-- ------------------------------------------------------------
-- Eine Adresse gilt erst als eingetragen, wenn sie bestätigt wurde
-- (`confirmed_at`). Bis dahin liegt nur die Bitte um Bestätigung vor –
-- so lässt sich niemand mit einer fremden Adresse anmelden.
CREATE TABLE IF NOT EXISTS `status_subscribers` (
    `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    `email` VARCHAR(255) NOT NULL,
    `token` CHAR(64) NOT NULL COMMENT 'Bestätigen und Abmelden – ein Wert für beides',
    `confirmed_at` DATETIME NULL,
    `last_sent_at` DATETIME NULL,
    `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    UNIQUE KEY `uq_status_subscribers_email` (`email`),
    UNIQUE KEY `uq_status_subscribers_token` (`token`),
    INDEX `idx_status_subscribers_confirmed` (`confirmed_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='Besucher, die über Störungen der Statusseite benachrichtigt werden';

-- ------------------------------------------------------------
-- 2. Warteschlange
-- ------------------------------------------------------------
-- Eine Zeile je Adresse und Ereignis. `sent_at` trennt Offenes von Erledigtem,
-- `attempts` begrenzt das Wiederholen einer dauerhaft scheiternden Zustellung.
CREATE TABLE IF NOT EXISTS `status_notification_queue` (
    `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
    `subscriber_id` BIGINT UNSIGNED NOT NULL,
    `incident_id` BIGINT UNSIGNED NULL,
    `kind` ENUM('opened','resolved') NOT NULL,
    `subject` VARCHAR(255) NOT NULL,
    `body_html` MEDIUMTEXT NOT NULL,
    `attempts` TINYINT UNSIGNED NOT NULL DEFAULT 0,
    `last_error` VARCHAR(500) NULL,
    `sent_at` DATETIME NULL,
    `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    INDEX `idx_status_queue_offen` (`sent_at`, `attempts`, `id`),
    INDEX `idx_status_queue_incident` (`incident_id`),
    CONSTRAINT `fk_status_queue_subscriber` FOREIGN KEY (`subscriber_id`)
        REFERENCES `status_subscribers` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT `fk_status_queue_incident` FOREIGN KEY (`incident_id`)
        REFERENCES `status_incidents` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
COMMENT='Ausstehende Benachrichtigungen an Statusseiten-Besucher';

-- ------------------------------------------------------------
-- 3. Versand als Aufgabe der Zeitsteuerung
-- ------------------------------------------------------------
INSERT IGNORE INTO `cron_tasks`
    (`name`, `label`, `description`, `handler_class`, `frequency_minutes`, `enabled`, `run_in_background`, `max_runtime_seconds`)
VALUES
    ('status_notify', 'Statusseite: Benachrichtigungen versenden',
     'Verschickt die ausstehenden Störungs- und Entwarnungsnachrichten an die eingetragenen Besucher der Statusseite.',
     'OpenNIT\\Cron\\Handlers\\StatusNotifyHandler', 5, 1, 0, 300);