Dateien
AegisSight-Monitor-Verwaltung/CLAUDE.md
claude-dev 00cd81f177 Phase 12: Test-Suite (30 pytest-Tests) + CLAUDE.md aktualisiert
tests/:
  conftest.py        - minimale Env-Vars + sys.path-Setup
  test_auth.py       - Magic-Token + JWT Round-Trip (4 Tests)
  test_audit.py      - diff() + _to_json() Helper (8 Tests)
  test_models.py     - Pydantic-Validierung (7 Tests)
  test_source_meta.py - Single Source of Truth Konsistenz (7 Tests)
  test_imports.py    - alle Backend-Module importierbar (4 Tests)

requirements-dev.txt: pytest, ftfy, pyflakes

Tests sind reine Unit-Tests (kein DB-Zugriff, kein HTTP-Server),
laufen in <0.5s, geben sofortiges Catch-Net fuer Syntax/Import-Bugs.

Aufruf: PYTHONPATH=src ./venv/bin/python -m pytest tests/ -v

CLAUDE.md erweitert um:
- Sektion Tests (Framework, Pfad, Ausfuehrung)
- Sektion Phasen-Historie (alle 12 Phasen der Aufraeum-Aktion 2026-05-09
  mit kurzer Erklaerung)
2026-05-09 03:55:30 +00:00

9.3 KiB

AegisSight-Monitor-Verwaltung

Admin-Portal für Mandanten, Lizenzen, Nutzer, Grundquellen und Token-Verbrauch des AegisSight-Monitors

Übersicht

projekt: AegisSight-Monitor-Verwaltung
url: https://monitor-verwaltung.aegis-sight.de
server: ssh monitor (46.225.141.13, User: claude-dev)
pfad: /home/claude-dev/AegisSight-Monitor-Verwaltung
quellcode: /home/claude-dev/AegisSight-Monitor-Verwaltung/src/
datenbank: /mnt/gitea/osint-data/osint.db (SQLite WAL, geteilt mit AegisSight-Monitor)
gitea: https://gitea-undso.aegis-sight.de/AegisSight/AegisSight-Monitor-Verwaltung
service: verwaltungsportal.service (systemd, Port 8892, Nginx Reverse Proxy)
venv: /home/claude-dev/.venvs/verwaltung/ (Python 3.12)

Technologie-Stack

backend:
  framework: FastAPI + Uvicorn
  datenbank: SQLite WAL (aiosqlite, async) - geteilt mit AegisSight-Monitor
  auth: Passwort-Login (bcrypt, JWT HS256, 8 Stunden)
  brute_force_schutz: 5 Fehlversuche pro 15 Minuten Block, Aufräumen nach 24 Stunden
  audit: jede Mutation via log_action -> portal_audit Tabelle
  email: aiosmtplib (smtp.ionos.de:587 TLS) - für Magic-Link-Einladungen Richtung Monitor

frontend:
  typ: Vanilla JS (kein Framework, kein Build-Step)
  design: AegisSight Dark Theme (gemeinsame Optik wie Monitor)
  fonts: Poppins (Titel), Inter (Body)

Projektstruktur

src/:
  main.py: "FastAPI App, Login + Brute-Force-Logik, Lifespan, statische Routen"
  config.py: "Konfiguration (DB-Pfad, JWT, SMTP, Source-Discovery-Konstanten)"
  auth.py: "Passwort-Hash (bcrypt), JWT erstellen/verifizieren, get_current_admin Dependency"
  database.py: "DB-Connection-Pool, Schema-Helper"
  models.py: "Pydantic Request/Response-Schemas"
  audit.py: "log_action, get_client_ip, row_to_dict, /api/audit Router"

  routers/:
    organizations.py: "CRUD Mandanten (organizations + Org-Settings + Token-Budget)"
    licenses.py: "CRUD Lizenzen (Org-Lizenzen, Ablauf, Nutzer-Limit, Module)"
    users.py: "CRUD User pro Org, Magic-Link-Einladung an info@aegis-sight.de"
    sources.py: "Grundquellen, Tenant-Quellen-Übersicht, Discovery, Health-Check, KI-Vorschläge"
    dashboard.py: "Aggregat-Endpoints für Übersichts-Tab"
    token_usage.py: "Token-Verbrauch pro Org/Monat, Budget-Steuerung"
    audit.py: "Audit-Log-Abfrage, Filter"

  email_utils/:
    sender.py: "Async SMTP Versand"
    templates.py: "HTML-Templates (Magic-Link für neue Nutzer)"

  static/:
    index.html: "Login (Passwort)"
    dashboard.html: "Hauptdashboard mit Tabs (Dashboard, Orgs, Lizenzen, Quellen, Audit)"
    favicon.svg: "AegisSight Logo"
    css/: "Stylesheets (Dark Theme)"
    js/:
      app.js: "Hauptlogik, Login, Tab-Switching, Dashboard-Render"
      sources.js: "Grundquellen + Kundenquellen Management"
      source-health.js: "Quellen-Health & KI-Vorschläge"
      audit.js: "Audit-Log Tab"

migrations/:
  einmal_migrationen: "Backfill-Skripte (DE-Übersetzungen, Umlaute, HTML-Strip etc.)"

Datenbank-Tabellen (relevant fürs Portal)

kern: "organizations, licenses, users, magic_links, portal_admins"
quellen: "sources (geteilt mit Monitor), source_health_checks, source_suggestions"
verbrauch: "token_usage_monthly"
audit: "portal_audit"

Verwandte Projekte

monitor:
  pfad: /home/claude-dev/AegisSight-Monitor
  url: https://monitor.aegis-sight.de
  service: aegis-monitor.service (Port 8891)
  geteilte_db: ja
  geteilte_module:
    - source_rules: "Domain-Erkennung, RSS-Discovery, Claude-Feed-Bewertung"
    - services/source_health: "Health-Check-Logik"
    - services/source_suggester: "KI-Quellenvorschläge"
    - agents/claude_client: "Shared Claude CLI Client"
  hinweis: "Verwaltung importiert diese Module; sys.path-Hacks sollen schrittweise durch eigene Kopien in src/shared/ ersetzt werden"

Regeln

regeln:
  - "Jede Änderung MUSS sofort committed und nach Gitea gepusht werden"
  - "Echte Umlaute (ü, ä, ö, ß), niemals Umschreibungen (ue, ae, oe, ss) - gilt auch in Code-Kommentaren, Logs, UI-Texten"
  - "Keine Passwörter oder Secrets in den Code committen (.env nicht im Repo)"
  - "Service nach Backend-Änderungen: sudo systemctl restart verwaltungsportal"
  - "Frontend-Änderungen (HTML/JS/CSS) brauchen keinen Neustart"
  - "Backup-Dateien (.bak) nicht committen, vor Push löschen"
  - "Code-Fixes immer über develop -> Staging -> Promote, niemals direkt auf main"
  - "Direkte Live-DB-Patches nur nach Vorab-Ankündigung"

Changelog-Workflow

Bei JEDER Änderung an dieser Anwendung müssen zwei Dinge passieren:

  1. TaskMate Wissensdatenbank (Kategorie: "Changelog Verwaltung", category_id=34)
  2. Git Commit + Push zu Gitea

Siehe AegisSight-Monitor/CLAUDE.md für vollständiges Beispiel des TaskMate-Aufrufs.

Staging-Umgebung

Wird im Rahmen des Aufräum-Plans (Phase 0) aufgesetzt. Geplante Eckdaten:

staging:
  url: https://staging.monitor-verwaltung.aegis-sight.de
  server: 46.225.141.13 (gleicher Host wie Live)
  pfad: /home/claude-dev/AegisSight-Monitor-Verwaltung-staging
  branch: develop
  port: 18892 (Live: 8892)
  service: aegis-verwaltung-staging.service
  venv: /home/claude-dev/AegisSight-Monitor-Verwaltung-staging/venv (eigenes venv)
  zugriff: Magic-Link-Login an info@aegis-sight.de (Cookie 30 Tage, vorgelagerter Auth-Service)

  datenbank:
    plan: eigene SQLite-Kopie der Live-DB in ~/AegisSight-Monitor-Verwaltung-staging/data/osint.db
    drift: gewollt - Änderungen in Staging beeinflussen Live nicht
    abstimmung: gemeinsame DB mit Monitor-Staging möglich, wird beim Aufbau entschieden

  auth_service:
    pfad: /opt/aegis-verwaltung-staging-auth
    service: aegis-verwaltung-staging-auth.service
    port: 127.0.0.1:8098 (Monitor-Staging-Auth liegt schon auf 8095)
    cookie_domain: staging.monitor-verwaltung.aegis-sight.de
    cookie_name: aegis_verwaltung_staging_auth

Workflow develop -> Staging -> Live (Plan)

  1. Änderung in develop machen:

    cd ~/AegisSight-Monitor-Verwaltung
    git checkout develop
    # Änderung
    git add . && git commit -m '...' && git push origin develop
    
  2. Auto-Deploy (geplant, Phase 0f): Gitea-Webhook -> aegis-staging-deploy.service -> pullt develop ins Staging-Verzeichnis -> restartet aegis-verwaltung-staging

  3. Auf https://staging.monitor-verwaltung.aegis-sight.de prüfen

  4. Promote zu Live über https://deploy.aegis-sight.de (Phase 0g) -> Gitea-PR develop->main automerge -> Live-Listener pullt main -> systemctl restart verwaltungsportal

Shared-Module-Sync (src/shared/)

shared:
  pfad: src/shared/
  inhalt: source_rules + services/source_health + services/source_suggester + agents/claude_client
  herkunft: lokale Kopie aus AegisSight-Monitor/src/
  drift_lösung: scripts/sync_shared.py

  workflow:
    pruefen: "./venv/bin/python scripts/sync_shared.py --check"
    anwenden: "./venv/bin/python scripts/sync_shared.py --apply"

  locked_files:
    src/shared/services/source_health.py:
      grund: "Verwaltungs-Fork mit tenant_id-Filter weg + Historie + Config-Konstanten"
      hinweis: "Auto-Sync schreibt NICHT. Drift wird gemeldet, manuell entscheiden."

  voraussetzung:
    ftfy installieren: "pip install ftfy" (im venv des Repos)
    grund: "Sync-Skript fixed Mojibake aus Monitor-Originalen automatisch."
    fail_safe: "Ohne ftfy bricht das Skript ab wenn Mojibake erkannt - schuetzt vor Mojibake-Reimport."

  beim_drift:
    nicht_locked: "einfach --apply, dann committen"
    locked: "diff anschauen, ueberlegen ob die Monitor-Aenderung im Verwaltungs-Fork sinnvoll ist"

Tests

tests:
  framework: pytest
  pfad: tests/
  ausfuehren: "PYTHONPATH=src ./venv/bin/python -m pytest tests/ -v"
  install: "./venv/bin/pip install -r requirements-dev.txt"

  abdeckung:
    test_auth.py: Magic-Token + JWT Round-Trip
    test_audit.py: diff() + _to_json() Helper
    test_models.py: Pydantic-Validierung (MagicLink, Org, License, User)
    test_source_meta.py: Single Source of Truth Konsistenz
    test_imports.py: alle Backend-Module importierbar (Syntax-Catchnet)

  philosophie:
    - reine Unit-Tests, kein DB-Zugriff, kein HTTP-Server
    - schnell (<1 Sekunde fuer das ganze Set)
    - sollten lokal vor jedem Commit laufen

Phasen-Historie (Aufraeum-Aktion 2026-05-09)

phasen:
  P0:  Verwaltungs-Staging mit develop-Branch + Auto-Deploy + Promote-UI
  P0i: Login-Auth komplett auf Magic-Link (Passwort entfernt)
  P1:  Backend-Hygiene Quellen (sys.path-Hack weg, Mojibake gefixt, DDL ausgelagert)
  P2:  Health-Check tenant-faehig + source_health_history (Verlauf bleibt)
  P3a: Toast-System statt alert/confirm
  P3b: GET /api/sources/meta - Single Source of Truth fuer Kategorien/Typen
  P3c: Kundenquellen-Tab Filter+Sort+Bulk-Promote
  P4:  Stats-Bar + Health-Badge inline + Letzter-Treffer-Spalte
  P5:  Audit-Spur pro Quelle (ausklappbares Modal)
  P6:  Verwendungs-Sicht: Aktivitaet 7d/30d + Tenant-Sperren
  P7:  scripts/sync_shared.py + Lock-Mechanismus + Mojibake-fail-safe
  P8a: Pre-Commit-Hook fuer src/shared/ Drift
  P8b: Audit-Log UI um resource_id-Filter
  P8c: Monitor-Repo Mojibake gefixt (source_suggester + source_health)
  P9:  Code-Hygiene - alle pyflakes-Issues bereinigt
  P10: Bug 2 Buckelwal-Diagnose: Lagentitel-Eigennamen als Pflicht-Keywords
  P11: Backup-Rotation via Cron (KEEP=5 letzte .bak-Files)
  P12: Test-Suite (pytest, 30 Tests) + Doku