Initial commit: AegisSight-Monitor (OSINT-Monitoringsystem)

Dieser Commit ist enthalten in:
claude-dev
2026-03-04 17:53:18 +01:00
Commit 8312d24912
51 geänderte Dateien mit 19355 neuen und 0 gelöschten Zeilen

121
CLAUDE.md Normale Datei
Datei anzeigen

@@ -0,0 +1,121 @@
# OSINT Lagemonitor
> Lokale Arbeitskopie für das OSINT-Monitor-Projekt auf Server `alt`
## Übersicht
```yaml
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
```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
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
```yaml
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
```yaml
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"
```