# AegisSight-Monitor > OSINT-Monitoringsystem mit KI-gestützter Nachrichtenanalyse ## Übersicht ```yaml projekt: AegisSight-Monitor url: https://osint.intelsight.de beschreibung: "OSINT-basiertes Lagemonitoring mit Claude-KI-Agenten" server: alt (91.99.192.14, User: claude-dev) pfad: /home/claude-dev/AegisSight-Monitor datenbank: /mnt/gitea/osint-data/osint.db (geteilt mit AegisSight-Monitor-Verwaltung) gitea: https://gitea-undso.aegis-sight.de/AegisSight/AegisSight-Monitor git_push_regel: "Jede Aenderung MUSS sofort committed und nach Gitea gepusht werden." service: osint-monitor.service (systemd, Port 8891, Nginx Reverse Proxy) venv: /home/claude-dev/.venvs/osint/ status: aktiv ``` ## Technologie-Stack ```yaml backend: framework: FastAPI (Python 3.12) datenbank: SQLite (WAL-Modus, aiosqlite) auth: Magic-Link-Login per E-Mail (JWT HS256, 24h Ablauf) scheduler: APScheduler (Auto-Refresh jede Minute, Cleanup stuendlich) websocket: FastAPI native (Echtzeit-Updates) ki_agenten: Claude CLI (WebSearch + WebFetch Tools) email: aiosmtplib (Magic Links, Benachrichtigungen) port: 8891 (localhost, Nginx Reverse Proxy) frontend: typ: Vanilla JS (kein Framework) design: AegisSight Dark/Light Theme (Navy/Gold) fonts: Poppins (Titel), Inter (Body) layout: gridstack.js (Drag-and-Drop Dashboard-Kacheln) echtzeit: WebSocket mit Auto-Reconnect und Ping/Pong ``` ## Projektstruktur ```yaml AegisSight-Monitor/: CLAUDE.md: "Diese Datei" requirements.txt: "Python-Abhaengigkeiten" data/: "Symlink -> /mnt/gitea/osint-data/ (SQLite DB)" logs/: "Anwendungs-Logs (osint-monitor.log)" src/: main.py: "FastAPI App, WebSocketManager, Scheduler (lifespan), statische Routen" config.py: "Konfiguration (JWT, Claude CLI Pfad/Timeout, SMTP, RSS-Default-Feeds, Excluded Sources, Zeitzone)" auth.py: "JWT-Token erstellen/verifizieren, Magic-Link/Code generieren, get_current_user Dependency" database.py: "SQLite Schema (13 Tabellen), Migrationen, init_db()" models.py: "Pydantic Request/Response-Schemas" source_rules.py: "Dynamische Quellen-Regeln aus DB, Domain-Kategorisierung, Feed-Discovery" routers/: auth.py: "Magic-Link-Login: POST /api/auth/magic-link, /verify, /verify-code, GET /api/auth/me" incidents.py: "CRUD Lagen, Artikel, Snapshots, Faktenchecks, Refresh, Export, E-Mail-Subscriptions" sources.py: "CRUD Quellen, Discovery (Single/Multi), Domain sperren/entsperren, Stats" notifications.py: "GET/PUT Benachrichtigungen (Liste, ungelesen, als gelesen markieren)" feedback.py: "POST /api/feedback (Rate-Limited, E-Mail an feedback@aegis-sight.de)" agents/: claude_client.py: "Shared Claude CLI Client (JSON-Output, Usage-Tracking: Token, Kosten)" orchestrator.py: "AsyncQueue, Agenten-Pipeline, Cancel, Snapshots, E-Mail-Benachrichtigungen, Quellen-Discovery" researcher.py: "Claude WebSearch Agent (Ad-hoc + Deep Research Modus)" analyzer.py: "Analyse-Agent (Zusammenfassung/Briefing mit Inline-Zitaten)" factchecker.py: "Faktencheck-Agent (Claims gegen unabhaengige Quellen pruefen)" feeds/: rss_parser.py: "RSS-Feed Aggregation (dynamisch aus DB, Keyword-Matching)" services/: license_service.py: "Lizenzpruefung (check_license), Nutzer-Limit, Ablauf-Check" middleware/: license_check.py: "FastAPI Dependencies: require_active_license, require_writable_license" migration/: migrate_to_multitenancy.py: "Einmal-Migration: Single-Tenant zu Multi-Tenant" email_utils/: sender.py: "Async SMTP E-Mail-Versand (aiosmtplib, TLS)" templates.py: "HTML-E-Mail-Templates (Magic-Link-Login, Incident-Benachrichtigungen)" rate_limiter.py: "Rate-Limiting fuer Magic-Links und Code-Verifizierung" static/: index.html: "Login-Seite (Magic-Link: E-Mail eingeben, Code eingeben)" dashboard.html: "Hauptdashboard (Sidebar + Grid + Modals)" css/: style.css: "AegisSight Design System (Dark/Light Theme, alle Komponenten)" js/: api.js: "REST-API-Client (fetch-basiert, 30s Timeout, Auto-Redirect bei 401)" app.js: "Hauptlogik: ThemeManager, A11yManager, NotificationCenter, App-Objekt" components.js: "UI-Rendering: Sidebar-Items, Faktenchecks, Evidence-Chips, Toasts, Fortschritt, Quellen" layout.js: "gridstack.js Wrapper (Drag und Resize, localStorage-Persistenz)" ws.js: "WebSocket-Client (Reconnect mit exponential Backoff, Ping/Pong)" ``` ## Architektur ```yaml auth: methode: "Magic-Link per E-Mail (kein Passwort-Login)" flow: "E-Mail eingeben, Code per E-Mail, Code eingeben oder Link klicken, JWT" rate_limiting: "3 Magic-Links pro E-Mail/15min, 5 Fehlversuche Code/E-Mail" multi_tenancy: "JWT enthaelt tenant_id, org_slug, role" agenten_pipeline: 1_rss: "RSS-Feeds durchsuchen (nur Ad-hoc-Lagen)" 2_claude_recherche: "Claude CLI WebSearch (Ad-hoc oder Deep Research)" 3_deduplizierung: "URL-Normalisierung + Headline-Aehnlichkeit" 4_analyse: "Zusammenfassung/Briefing mit Inline-Zitaten [1][2]" 5_faktencheck: "Claims gegen unabhaengige Quellen pruefen" orchestrierung: "Sequentielle AsyncQueue (1 Auftrag gleichzeitig, 3 Retries)" incident_typen: adhoc: "Breaking News: RSS + WebSearch, Fliesstext-Summary" research: "Hintergrundrecherche: Deep Research, Markdown-Briefing" sidebar: aktive_lagen: "Lagen mit type=adhoc und status=active" aktive_recherchen: "Lagen mit type=research und status=active" archiv: "Alle Lagen mit status=archived (standardmaessig zugeklappt)" zaehler: "Anzahl pro Sektion in Klammern" filter: "Alle / Eigene" benachrichtigungen: in_app: "NotificationCenter (Glocke + Badge, DB-persistent, 7 Tage)" email: einstellung: "Pro Lage konfigurierbar (3 Toggles im Lage-Modal)" optionen: "Neues Lagebild, Neue Artikel, Statusaenderung Faktencheck" tabelle: "incident_subscriptions (pro User pro Lage)" versand: "Nach jedem Refresh (ab dem 2.) basierend auf Subscriptions" quellenverwaltung: features: "Anlegen, Bearbeiten, Loeschen, Discovery (Multi-Feed), Domain sperren" source_types: "rss_feed, web_source, excluded" lizenz_anzeige: header: "Org-Name + Lizenz-Badge (Trial/Annual/Permanent/Abgelaufen)" read_only: "Warnung wenn Lizenz abgelaufen" dashboard_kacheln: lagebild: "Markdown-Zusammenfassung mit klickbaren Zitaten" faktencheck: "Status-Icons, Evidence-Chips, Filter" quellenübersicht: "Aggregiert nach Quellen mit Sprach-Statistik" timeline: "Interaktive Zeitleiste mit Bucketing, Filtern, Suche" datenbank_tabellen: organizations: "Multi-Tenancy Organisationen" licenses: "Lizenzen pro Organisation (trial/annual/permanent)" users: "Nutzer (E-Mail, Org, Rolle)" magic_links: "Login-Tokens (10 Min. gueltig)" portal_admins: "Admin-Zugaenge (genutzt von AegisSight-Monitor-Verwaltung)" incidents: "Lagen/Recherchen" articles: "Gesammelte Artikel (original + deutsche Uebersetzung)" fact_checks: "Faktenchecks (claim, status, evidence)" refresh_log: "Refresh-Protokoll (Token-Statistiken, Kosten)" incident_snapshots: "Archivierte Lageberichte" sources: "Quellen-Verwaltung (RSS-Feeds, Web-Quellen, Blacklist)" notifications: "Persistente In-App-Benachrichtigungen" incident_subscriptions: "E-Mail-Abo-Einstellungen pro User/Lage" deployment: service: "systemd osint-monitor.service" restart: "sudo systemctl restart osint-monitor" logs: "tail -f ~/AegisSight-Monitor/logs/osint-monitor.log" status: "systemctl status osint-monitor" ``` ## Verwandte Projekte ```yaml verwaltungsportal: pfad: /home/claude-dev/AegisSight-Monitor-Verwaltung beschreibung: "Admin-Portal fuer Organisationen, Lizenzen, Nutzer" geteilte_db: /mnt/gitea/osint-data/osint.db service: verwaltungsportal.service (Port 8892) ``` ## Regeln ```yaml regeln: - "Jede Aenderung MUSS sofort committed und nach Gitea gepusht werden" - "Echte Umlaute in UI-Texten verwenden, Umschreibungen in YAML/Code-Kommentaren OK" - "Keine Passwoerter oder Secrets in den Code committen" - "Service nach Backend-Aenderungen neustarten: sudo systemctl restart osint-monitor" - "Frontend-Aenderungen brauchen keinen Neustart (statische Dateien)" ```