266 Zeilen
10 KiB
Markdown
266 Zeilen
10 KiB
Markdown
# AegisSight-Monitor-Verwaltung
|
|
|
|
> Admin-Portal für Mandanten, Lizenzen, Nutzer, Grundquellen und Token-Verbrauch des AegisSight-Monitors
|
|
|
|
## Übersicht
|
|
|
|
```yaml
|
|
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
|
|
|
|
```yaml
|
|
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
|
|
|
|
```yaml
|
|
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)
|
|
|
|
```yaml
|
|
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
|
|
|
|
```yaml
|
|
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
|
|
|
|
```yaml
|
|
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:
|
|
|
|
```yaml
|
|
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**:
|
|
```bash
|
|
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/)
|
|
|
|
```yaml
|
|
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
|
|
|
|
```yaml
|
|
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)
|
|
|
|
```yaml
|
|
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
|
|
```
|
|
|
|
## Cache-Buster bei Frontend-Aenderungen
|
|
|
|
```yaml
|
|
cache_buster:
|
|
hintergrund: |
|
|
src/static/dashboard.html und index.html laden JS+CSS mit Versions-Suffix
|
|
?v=YYYYMMDD. Ohne den Bump cacht der Browser alte JS aggressiv.
|
|
Symptom: User sieht alte UI obwohl Live aktuell deployed ist.
|
|
|
|
regel: |
|
|
Bei JEDER Aenderung an .js oder .css unter src/static/ das ?v=YYYYMMDD
|
|
auf das aktuelle Datum bumpen. Genuegt einmal pro Tag - mehrfache
|
|
Aenderungen am selben Tag teilen sich die Version.
|
|
|
|
betroffene_files:
|
|
- src/static/dashboard.html (4x JS, 1x CSS)
|
|
- src/static/index.html (1x CSS)
|
|
|
|
schnelle_aktualisierung: |
|
|
sed -i 's/?v=2026[0-9]\{4\}/?v='$(date +%Y%m%d)'/g' src/static/dashboard.html src/static/index.html
|
|
|
|
testen: "Strg+Shift+R im Browser (Hard-Reload) zeigt sofort die neue Version."
|
|
```
|
|
|