scripts/sync_shared.py: hält src/shared/ in sync mit dem Monitor-Repo - --check: Drift-Diagnose ohne Schreiben (Exit 1 bei auto-sync-Drift, 0 bei nur LOCKED-Drift = informativ) - --apply: schreibt Drift, ueberspringt LOCKED_FILES - Mojibake-Schutz via ftfy (Monitor-Originale haben teilweise noch Doppel- Encoded UTF-8, das fixed wird beim Sync) - Imports-Patch: from agents. -> from shared.agents. (etc.) damit Module innerhalb von src/shared/ ihre Geschwister korrekt finden LOCKED_FILES (nicht auto-syncbar): - src/shared/services/source_health.py (Phase-2-Fork: tenant_id-Filter weg, History-Archivierung, Config-Konstanten - waere im Monitor unsinnig) Hintergrund: Phase 1 hat src/shared/ als 1:1-Kopie aus dem Monitor angelegt. Phase 2 hat source_health.py spezifisch fuer die Verwaltung erweitert. Ein blinder Sync wuerde Phase-2-Aenderungen ueberschreiben - Lock-Mechanismus verhindert das, meldet aber Drift zur Information. CLAUDE.md: Sektion Shared-Module-Sync mit Workflow-Doku.
7.2 KiB
7.2 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:
- TaskMate Wissensdatenbank (Kategorie: "Changelog Verwaltung", category_id=34)
- 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)
-
Änderung in develop machen:
cd ~/AegisSight-Monitor-Verwaltung git checkout develop # Änderung git add . && git commit -m '...' && git push origin develop -
Auto-Deploy (geplant, Phase 0f): Gitea-Webhook -> aegis-staging-deploy.service -> pullt develop ins Staging-Verzeichnis -> restartet aegis-verwaltung-staging
-
Auf https://staging.monitor-verwaltung.aegis-sight.de prüfen
-
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."
beim_drift:
nicht_locked: "einfach --apply, dann committen"
locked: "diff anschauen, ueberlegen ob die Monitor-Aenderung im Verwaltungs-Fork sinnvoll ist"