From 247b72133e59c611e838bc3c4a03ad1f6f0905e9 Mon Sep 17 00:00:00 2001 From: claude-dev Date: Wed, 4 Mar 2026 18:55:17 +0100 Subject: [PATCH] CLAUDE.md aktualisiert + broadcast_for_incident tenant_id Fix - CLAUDE.md komplett neu geschrieben mit aktueller Projektstruktur - broadcast_for_incident: tenant_id Parameter hinzugefuegt (TypeError Fix) --- CLAUDE.md | 215 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 144 insertions(+), 71 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index d910077..e7e267f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,121 +1,194 @@ -# OSINT Lagemonitor +# AegisSight-Monitor -> Lokale Arbeitskopie für das OSINT-Monitor-Projekt auf Server `alt` +> OSINT-Monitoringsystem mit KI-gestützter Nachrichtenanalyse ## Übersicht ```yaml -projekt: osint-monitor +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_server: /home/claude-dev/osint-monitor -pfad_lokal: C:\Users\Administrator\Desktop\OSINT-monitor -status: aktiv (systemd service läuft) +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, 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 + 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 Theme (Navy/Gold) + design: AegisSight Dark/Light Theme (Navy/Gold) fonts: Poppins (Titel), Inter (Body) - echtzeit: WebSocket mit Auto-Reconnect + layout: gridstack.js (Drag-and-Drop Dashboard-Kacheln) + echtzeit: WebSocket mit Auto-Reconnect und Ping/Pong ``` ## Projektstruktur ```yaml -osint-monitor/: - CLAUDE.md: "Projektdokumentation" - requirements.txt: "Python-Abhängigkeiten" - setup_users.py: "Nutzer-Initialisierung (rac00n, ch33tah)" +AegisSight-Monitor/: + CLAUDE.md: "Diese Datei" + requirements.txt: "Python-Abhaengigkeiten" data/: "Symlink -> /mnt/gitea/osint-data/ (SQLite DB)" - logs/: "Anwendungs-Logs" + logs/: "Anwendungs-Logs (osint-monitor.log)" + 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)" + 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: "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)" + 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 mit JSON-Output + Usage-Tracking (ClaudeUsage, UsageAccumulator)" - orchestrator.py: "AsyncQueue, koordiniert Agenten-Pipeline sequentiell, Token-Akkumulation + Snapshots + DB-Notifications" + 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-Format)" - factchecker.py: "Faktencheck-Agent (quellengebunden)" + 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, Fallback auf config.py)" + 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" - dashboard.html: "Hauptdashboard" - css/style.css: "AegisSight Design System" - js/: "api.js, app.js, components.js, ws.js" + 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_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)" + 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 -> Plaintext-Summary mit Quellenreferenzen" - research: "Hintergrundrecherche -> Nur Deep Research -> Markdown-Briefing mit Quellenverzeichnis" + adhoc: "Breaking News: RSS + WebSearch, Fliesstext-Summary" + research: "Hintergrundrecherche: Deep Research, Markdown-Briefing" -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)" +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: - 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" + 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: - 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" + 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: - workflow: "scp Dateien -> ssh alt -> systemctl restart osint-monitor" + 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)" ```