"""Migration 2026-07-25: Preistabelle billing_tariff anlegen und befüllen. Die Tabelle ist die pflegbare Quelle der Credits-Sätze je Aktion. Der Monitor legt sie beim Start selbst an (init_db, mit seinen Konfigurationswerten als Erstbefüllung). Die Portal-Staging-Umgebung nutzt aber eine EIGENE Datenbank, auf der kein Monitor läuft, deshalb braucht sie dieses Skript. Idempotent, vorhandene Sätze werden NICHT überschrieben (INSERT OR IGNORE). Ausführung: DB_PATH=/home/claude-dev/AegisSight-Monitor-staging/data/osint.db python3 migrations/2026-07-25_billing_tariff.py DB_PATH=/home/claude-dev/osint-data/osint.db python3 migrations/2026-07-25_billing_tariff.py """ import os import sqlite3 import sys # Beschlossene Verkaufssätze (23.07.2026), identisch zu den Monitor-Defaults SEED = { "monitor_adhoc": 45.0, "monitor_research": 40.0, "analysis": 12.0, "factcheck": 12.0, "chat": 1.0, "enhance": 1.0, "globe": 1.0, } 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.execute(""" CREATE TABLE IF NOT EXISTS billing_tariff ( tariff_key TEXT PRIMARY KEY, credits REAL NOT NULL, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) """) print(" + billing_tariff angelegt (oder vorhanden)") for key, credits in SEED.items(): cur = conn.execute( "INSERT OR IGNORE INTO billing_tariff (tariff_key, credits) VALUES (?, ?)", (key, credits), ) if cur.rowcount: print(f" + Satz {key} = {credits}") else: print(f" = Satz {key} war bereits gesetzt") 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))