Dateien
AegisSight-Monitor/CLAUDE.md

5.8 KiB

OSINT Lagemonitor

Lokale Arbeitskopie für das OSINT-Monitor-Projekt auf Server alt

Übersicht

projekt: osint-monitor
url: https://osint.intelsight.de
beschreibung: "OSINT-basiertes Lagemonitoring mit Claude-KI-Agenten"
server: alt (91.99.192.14, User: claude-dev)
pfad_server: /home/claude-dev/osint-monitor
pfad_lokal: C:\Users\Administrator\Desktop\OSINT-monitor
status: aktiv (systemd service läuft)

Technologie-Stack

backend:
  framework: FastAPI (Python 3, venv /home/claude-dev/.venvs/osint/)
  datenbank: SQLite (WAL-Modus, aiosqlite) @ /mnt/gitea/osint-data/osint.db
  auth: JWT (HS256, bcrypt, 24h Ablauf)
  scheduler: APScheduler (Auto-Refresh jede Minute + Cleanup stündlich)
  websocket: FastAPI native
  ki_agenten: Claude CLI (WebSearch + WebFetch Tools)
  port: 8891 (localhost, Nginx Reverse Proxy)

frontend:
  typ: Vanilla JS (kein Framework)
  design: AegisSight Dark Theme (Navy/Gold)
  fonts: Poppins (Titel), Inter (Body)
  echtzeit: WebSocket mit Auto-Reconnect

Projektstruktur

osint-monitor/:
  CLAUDE.md: "Projektdokumentation"
  requirements.txt: "Python-Abhängigkeiten"
  setup_users.py: "Nutzer-Initialisierung (rac00n, ch33tah)"
  data/: "Symlink -> /mnt/gitea/osint-data/ (SQLite DB)"
  logs/: "Anwendungs-Logs"
  src/:
    main.py: "FastAPI App, WebSocket-Manager, Scheduler, Lifespan"
    config.py: "Konfiguration (JWT, Claude CLI, RSS-Feeds, Excluded Sources)"
    auth.py: "JWT-Authentifizierung (bcrypt, HTTPBearer)"
    database.py: "SQLite Schema + Migrationen (8 Tabellen: users, incidents, articles, fact_checks, refresh_log, incident_snapshots, sources, notifications)"
    models.py: "Pydantic Request/Response-Schemas (inkl. Source CRUD + Notifications)"
    source_rules.py: "Dynamische Quellen-Regeln aus DB (RSS-Feeds + Blacklist)"
    routers/:
      auth.py: "POST /api/auth/login, GET /api/auth/me"
      incidents.py: "CRUD /api/incidents, /api/incidents/{id}/articles|factchecks|refresh"
      sources.py: "CRUD /api/sources, /api/sources/stats, /api/sources/refresh-counts"
      notifications.py: "GET /api/notifications, GET /api/notifications/unread-count, PUT /api/notifications/mark-read"
      feedback.py: "POST /api/feedback (Rate-Limited, HTML-E-Mail an feedback@aegis-sight.de)"
    agents/:
      claude_client.py: "Shared Claude CLI Client mit JSON-Output + Usage-Tracking (ClaudeUsage, UsageAccumulator)"
      orchestrator.py: "AsyncQueue, koordiniert Agenten-Pipeline sequentiell, Token-Akkumulation + Snapshots + DB-Notifications"
      researcher.py: "Claude WebSearch Agent (Ad-hoc + Deep Research Modus)"
      analyzer.py: "Analyse-Agent (Zusammenfassung + Briefing-Format)"
      factchecker.py: "Faktencheck-Agent (quellengebunden)"
    feeds/:
      rss_parser.py: "RSS-Feed Aggregation (dynamisch aus DB, Fallback auf config.py)"
    static/:
      index.html: "Login-Seite"
      dashboard.html: "Hauptdashboard"
      css/style.css: "AegisSight Design System"
      js/: "api.js, app.js, components.js, ws.js"

Architektur

agenten_pipeline:
  1_rss: "RSS-Feeds durchsuchen (nur Ad-hoc-Lagen)"
  2_claude_recherche: "Claude CLI WebSearch (Ad-hoc oder Deep Research)"
  3_analyse: "Zusammenfassung/Briefing mit Inline-Zitaten [1][2] + sources_json"
  4_faktencheck: "Claims gegen unabhängige Quellen prüfen"
  orchestrierung: "Sequentielle Queue (1 Auftrag gleichzeitig)"

incident_typen:
  adhoc: "Breaking News -> RSS + WebSearch -> Plaintext-Summary mit Quellenreferenzen"
  research: "Hintergrundrecherche -> Nur Deep Research -> Markdown-Briefing mit Quellenverzeichnis"

internationale_quellen:
  toggle: "Pro Lage konfigurierbar (Checkbox beim Anlegen/Bearbeiten)"
  international_true: "DE + internationale Feeds (Reuters, BBC, Al Jazeera) + mehrsprachige Claude-Recherche"
  international_false: "Nur deutschsprachige Quellen (DE, AT, CH), internationale RSS-Kategorie übersprungen"
  db_feld: "international_sources INTEGER DEFAULT 1"
  betroffene_agenten: "RSSParser (Kategorien-Filter), ResearcherAgent (Sprach-Prompts), Orchestrator (Weiterleitung)"

quellenanzeige:
  inline_zitate: "Klickbare [1][2] Verweise im Lagebild → Quellenverzeichnis"
  quellenverzeichnis: "Am Ende des Lagebilds, nummeriert mit Links"
  quellenübersicht: "Aggregierte Ansicht aller Quellen pro Lage mit Sprach-Statistik"
  timeline_expand: "Artikel klickbar → Inhaltsvorschau + Link zum Original"
  sprach_badges: "EN/FR etc. Badge bei fremdsprachigen Artikeln"
  evidence_text: "Faktencheck zeigt erklärenden Text + Quellen-Chips"
  deduplizierung: "URL-Normalisierung + Headline-Ähnlichkeit (www, trailing slash, query params)"

benachrichtigungen:
  persistenz: "DB-Tabelle notifications (pro Nutzer, 7 Tage Aufbewahrung)"
  erzeugung: "Orchestrator schreibt nach refresh_summary in DB (öffentlich=alle Nutzer, privat=nur Ersteller)"
  frontend: "NotificationCenter lädt aus DB beim Init, optimistisches UI bei WebSocket-Events, Debounced DB-Sync"
  gelesen: "Als gelesen markieren (is_read=1) → visuell abgeblendet, nicht gelöscht"
  tab_badge: "document.title = '(N) IntelSight...' bei ungelesenen Notifications"
  cleanup: "Stündlicher Job löscht Notifications älter als 7 Tage"

quellenverwaltung:
  db_tabelle: "sources (id, name, url, domain, source_type, category, status, notes, added_by, article_count, last_seen_at, created_at)"
  source_types: "rss_feed | web_source | excluded"
  kategorien: "nachrichtenagentur, oeffentlich-rechtlich, qualitaetszeitung, behoerde, fachmedien, think-tank, international, regional, sonstige"
  seeding: "Beim Start aus config.py RSS_FEEDS + EXCLUDED_SOURCES (wenn Tabelle leer)"
  dynamisch: "source_rules.py liest aktive Quellen aus DB, Fallback auf config.py"
  frontend: "Modal mit Filter, Suche, Inline-Formular; Sidebar: 'Quellen verwalten' Button + Mini-Stats"

deployment:
  workflow: "scp Dateien -> ssh alt -> systemctl restart osint-monitor"