"""Migration 2026-05-09d: source_health_history (Verlauf der Health-Checks). Bislang wurde vor jedem Health-Check-Run die Tabelle source_health_checks geleert (DELETE FROM source_health_checks). Damit ging die Historie verloren - kein Trend, keine Vergleichsmöglichkeit über Runs. Diese Migration legt eine reine Append-Tabelle source_health_history an. Vor jedem Health-Check-Run wird der aktuelle Stand von source_health_checks hier archiviert (mit run_id und archived_at). Ausführung: DB_PATH=/home/claude-dev/osint-data/osint.db python3 migrations/2026-05-09d_source_health_history.py DB_PATH=/home/claude-dev/AegisSight-Monitor-staging/data/osint.db python3 migrations/2026-05-09d_source_health_history.py """ import os import sqlite3 import sys def main(db_path: str) -> int: if not os.path.exists(db_path): print(f"FEHLER: DB nicht gefunden: {db_path}", file=sys.stderr) return 1 conn = sqlite3.connect(db_path, timeout=60) conn.execute("PRAGMA busy_timeout = 60000") conn.execute("PRAGMA journal_mode = WAL") print(f"Migration auf {db_path}") conn.executescript(""" CREATE TABLE IF NOT EXISTS source_health_history ( id INTEGER PRIMARY KEY AUTOINCREMENT, run_id TEXT NOT NULL, source_id INTEGER NOT NULL, check_type TEXT NOT NULL, status TEXT NOT NULL, message TEXT, details TEXT, checked_at TIMESTAMP, archived_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX IF NOT EXISTS idx_source_health_history_run ON source_health_history(run_id); CREATE INDEX IF NOT EXISTS idx_source_health_history_source ON source_health_history(source_id, archived_at DESC); CREATE INDEX IF NOT EXISTS idx_source_health_history_status ON source_health_history(status, archived_at DESC); """) print(" + source_health_history + Indizes (idempotent)") conn.commit() conn.close() print("Migration abgeschlossen.") return 0 if __name__ == "__main__": db_path = os.environ.get("DB_PATH", "/home/claude-dev/osint-data/osint.db") sys.exit(main(db_path))