-- Migration 007: Fehler-Stream, Ignore-Regeln, Metrik-Verlauf, Health-Checks
--
-- Additive Migration. Der Migrator toleriert 1050/1060/1061/1062.

-- ---------------------------------------------------------------------------
-- 1. Fehlerklasse getrennt vom Schweregrad
-- ---------------------------------------------------------------------------
-- severity beschreibt die geschaeftliche Dringlichkeit (low ... critical),
-- error_level die technische Art des Ereignisses. Ein "Duplicate entry" ist
-- technisch ein error, geschaeftlich aber belanglos - beides zu vermischen
-- war der Grund, warum solche Meldungen bisher als Bug im Dashboard landeten.
ALTER TABLE bugtracker_items
  ADD COLUMN error_level ENUM('fatal','error','warning') NULL AFTER severity;

-- Status "ignored": bekannt, harmlos, wird weiter gezaehlt, aber nicht gemeldet.
ALTER TABLE bugtracker_items
  MODIFY COLUMN status ENUM('open','planned','in_progress','resolved','closed','rejected','ignored')
  NOT NULL DEFAULT 'open';

-- Rollendes Stundenfenster fuer die Ratenerkennung. Interessant ist nicht,
-- DASS ein bekannter Fehler auftritt, sondern wenn er ploetzlich viel
-- haeufiger auftritt.
ALTER TABLE bugtracker_items ADD COLUMN rate_window_start DATETIME NULL AFTER occurrence_count;
ALTER TABLE bugtracker_items ADD COLUMN rate_window_count INT NOT NULL DEFAULT 0 AFTER rate_window_start;
ALTER TABLE bugtracker_items ADD COLUMN rate_alerted_at   DATETIME NULL AFTER rate_window_count;

-- Welche Regel hat dieses Item stummgeschaltet?
ALTER TABLE bugtracker_items ADD COLUMN ignore_rule_id INT NULL AFTER error_level;

ALTER TABLE bugtracker_items ADD KEY ix_bt_error_level (error_level, last_seen_at);

-- ---------------------------------------------------------------------------
-- 2. Ignore-Regeln
-- ---------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS bugtracker_ignore_rules (
  id            INT AUTO_INCREMENT PRIMARY KEY,
  project_slug  VARCHAR(64)  NULL,          -- NULL = gilt fuer alle Projekte
  match_type    ENUM('contains','regex','exception_class') NOT NULL DEFAULT 'contains',
  pattern       VARCHAR(255) NOT NULL,
  -- Warum ist das harmlos? Pflichtfeld, damit in sechs Monaten noch
  -- nachvollziehbar ist, weshalb hier weggeschaut wird.
  reason        TEXT         NOT NULL,
  -- Ab wie vielen Vorkommnissen pro Stunde soll trotzdem alarmiert werden?
  -- NULL = nie alarmieren.
  alert_on_rate INT          NULL,
  enabled       TINYINT(1)   NOT NULL DEFAULT 1,
  match_count   BIGINT       NOT NULL DEFAULT 0,
  last_match_at DATETIME     NULL,
  created_by    VARCHAR(100) NOT NULL DEFAULT 'admin',
  created_at    DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP,
  KEY ix_ignore_project (project_slug, enabled)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- ---------------------------------------------------------------------------
-- 3. Metrik-Verlauf
-- ---------------------------------------------------------------------------
-- Bisher wurde metrics_json bei jedem Heartbeat ueberschrieben - es gab immer
-- nur den letzten Moment. Damit laesst sich "Platte laeuft seit drei Tagen
-- voll" nicht erkennen, sondern nur "Platte ist voll".
CREATE TABLE IF NOT EXISTS watchdog_metrics (
  id           BIGINT AUTO_INCREMENT PRIMARY KEY,
  source       VARCHAR(100) NOT NULL,
  instance     VARCHAR(100) NOT NULL DEFAULT 'default',
  metric_key   VARCHAR(64)  NOT NULL,
  metric_value DOUBLE       NOT NULL,
  recorded_utc DATETIME     NOT NULL,
  KEY ix_metric_lookup (source, instance, metric_key, recorded_utc),
  KEY ix_metric_time (recorded_utc)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- ---------------------------------------------------------------------------
-- 4. Health-Checks per Push
-- ---------------------------------------------------------------------------
-- Die Anwendung sendet ihren Gesundheitszustand im Heartbeat mit. Das
-- Deploymentcenter interpretiert die Namen der Pruefungen nicht - es liest
-- nur ok und message. Damit muessen auf den Zielmaschinen keine Ports
-- geoeffnet werden.
ALTER TABLE watchdog_monitors ADD COLUMN health_json JSON NULL AFTER metrics_json;
ALTER TABLE watchdog_monitors ADD COLUMN failing_checks VARCHAR(255) NULL AFTER health_json;

-- Alarme fuer Kinder unterdruecken, solange der Parent unten ist.
ALTER TABLE watchdog_monitors ADD COLUMN alert_suppressed_by VARCHAR(100) NULL AFTER failing_checks;

-- Aufraeumauftrag fuer den Metrik-Verlauf
INSERT INTO watchdog_cron_jobs (name, interval_sec, enabled) VALUES
('metrics_cleanup', 86400, 1)
ON DUPLICATE KEY UPDATE interval_sec = VALUES(interval_sec);

-- ---------------------------------------------------------------------------
-- 5. Beispielregel, damit der Aufbau sofort erkennbar ist
-- ---------------------------------------------------------------------------
-- Bewusst deaktiviert (enabled = 0): sie dient als Vorlage und greift erst,
-- wenn sie im WebUI bewusst eingeschaltet wird.
INSERT INTO bugtracker_ignore_rules
  (project_slug, match_type, pattern, reason, alert_on_rate, enabled, created_by)
SELECT 'polytrader', 'contains', 'Duplicate entry',
       'Marktdaten kommen doppelt aus dem Feed. Der Eintrag wird ohnehin nur einmal benoetigt, die Verarbeitung laeuft normal weiter. Alarm erst bei auffaelliger Haeufung.',
       500, 0, 'system:vorlage'
WHERE NOT EXISTS (
  SELECT 1 FROM bugtracker_ignore_rules WHERE project_slug = 'polytrader' AND pattern = 'Duplicate entry'
);
