wiki/c-work/4-done/2026-04-compliance-audit-view-and-navigation-overviews.md
ValueOn AG 788b63907a upd
2026-04-14 10:27:48 +02:00

269 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- status: done -->
<!-- started: 2026-04-13 -->
<!-- completed: 2026-04-14 -->
<!-- component: gateway | frontend-nyla | platform -->
# Compliance & Audit View + Navigations-Rubrik "Übersichten"
## Beschreibung und Kontext
**Was:** Zwei zusammenhängende Verbesserungen:
1. **Neue Navigations-Rubrik "Übersichten"** unter "Meine Sicht" — dorthin die bestehende "Integrationen"-Seite verschieben und eine neue "Compliance & AI-Audit"-Seite hinzufügen.
2. **Compliance & AI-Audit-Seite** — ein mächtiges Werkzeug für Compliance-Manager und Datenschutzbeauftragte, um alle AI-Datenflüsse und Audit-Ereignisse transparent einzusehen.
**Warum jetzt:** Investoren und Treuhänder fragen nach Nachvollziehbarkeit und Datenschutz-Compliance. Eine dedizierte Audit-Ansicht schafft Vertrauen und ist ein Differenzierungsmerkmal gegenüber generischen AI-Tools. Für die Kundendemos ist dies ein starkes Signal: "Jeder AI-Call ist nachvollziehbar."
**Business-Treiber:**
- Treuhänder unterliegen Revisionsanforderungen — sie müssen nachweisen können, welche Daten an welche AI-Modelle gesendet wurden.
- Investoren wollen sehen, dass PORTA Enterprise-ready ist (Audit-Trail, Compliance).
- Datenschutzbeauftragte brauchen eine Übersicht über alle AI-Datenflüsse pro Mandant.
**Abhängigkeiten:**
- Bestehendes `AuditLogEntry`-System (`gateway/modules/shared/auditLogger.py`) — schreibt bereits Security/GDPR/Permission-Events.
- Bestehendes Billing-System (`serviceBilling.recordUsage`) — zeichnet AI-Usage pro Call auf (Provider, Model, Kosten, Bytes).
- Bestehende Integrationsseite (`IntegrationsOverviewPage.tsx`) — wird in neue Rubrik verschoben.
- Navigation-System (`mainSystem.py` → `NAVIGATION_SECTIONS`) — muss um Subgroup erweitert werden.
**Risiko bei Nicht-Umsetzung:** Kunden sehen PORTA als "Black Box" — keine Transparenz über AI-Datenflüsse. Compliance-Anforderungen können nicht erfüllt werden.
## Fokus und kritische Details
### Ist-Zustand
**Navigation:**
- "Integrationen" ist ein Top-Level-Item unter "Meine Sicht" (order 15).
- Es gibt keine Rubrik "Übersichten".
**Audit-Logging:**
- `AuditLogEntry` erfasst: userId, mandateId, featureInstanceId, category, action, resourceType, resourceId, details, IP, userAgent, success/error.
- Kategorien: `access`, `key`, `data`, `security`, `gdpr`, `permission`, `system`.
- **Kein API-Endpoint** zum Lesen von Audit-Logs im Frontend — `getAuditLogs()` existiert nur intern auf `AuditLogger`.
**AI-Usage-Logging:**
- `serviceBilling.recordUsage` erfasst pro AI-Call: mandateId, userId, featureInstanceId, featureCode, aicoreProvider, aicoreModel, priceCHF, processingTime, bytesSent, bytesReceived, errorCount.
- **Fehlend:** Der tatsächliche Content (Prompt/Response) wird nicht persistiert — nur Metadaten und Kosten.
- Billing-Transaktionen sind über `GET /api/billing/transactions` abrufbar, aber nicht als Audit-View aufbereitet.
### Architektur-Entscheid: AI-Content-Audit-Log
Für den Compliance-View brauchen wir ein **neues AI-Audit-Log**, das pro AI-Interaktion speichert:
- Wer (User), wann, in welcher Instanz, mit welchem Modell
- Was gesendet wurde (Content-Hash oder Content selbst, konfigurierbar)
- Was empfangen wurde (Response-Zusammenfassung)
- Ob Neutralisierung aktiv war (und welche Mappings angewandt wurden)
- Download-Möglichkeit für den vollständigen Content
**Wichtig:** Content-Speicherung muss **mandantenspezifisch konfigurierbar** sein (manche Mandanten wollen Full-Content-Audit, andere nur Metadaten). RBAC muss sicherstellen, dass nur berechtigte Rollen (Compliance-Manager, Admin) Zugriff haben.
### Kritische Stellen
- **Datenmenge:** AI-Audit-Logs können schnell gross werden — Pagination und Zeitraum-Filter sind Pflicht.
- **RBAC:** Audit-Daten sind sensitiv — nur Mandate-Admins und Compliance-Rollen dürfen sie sehen.
- **Performance:** Statistik-Aggregationen (Tab C) müssen effizient sein — ggf. materialisierte Views oder Pre-Aggregation.
- **Content-Speicherung:** Vollständiger Prompt/Response-Content kann gross sein — separate Tabelle oder Object Storage.
## Ziel und Nicht-Ziele
**Ziel:**
- Neue Subgroup "Übersichten" unter "Meine Sicht" mit Integrationen + Compliance-Seite
- Compliance-Seite mit 3 Tabs:
- **Tab A: AI-Datenfluss-Log** — Tabelle: wann, wer, welche Instanz, welches AI-Modell, welche Daten, Download
- **Tab B: Audit-Log** — Tabelle: alle Security/GDPR/Permission-Events (bestehende `AuditLogEntry`-Daten)
- **Tab C: Audit-Statistik** — Grafische Auswertung mit Zeitraum- und Kontext-Filtern
- API-Endpoints für alle drei Tabs mit RBAC-Filterung
- AI-Content-Audit-Log als neues Datenmodell im Gateway
**Explizit NICHT:**
- Kein Real-Time-Streaming der Logs (Polling/Refresh reicht)
- Keine Änderung am bestehenden Billing-System (ergänzend, nicht ersetzend)
- Kein Log-Export als PDF/Excel in V1 (kommt ggf. später)
- Keine mandantenübergreifende Ansicht für Nicht-SysAdmins
## Betroffene Module
- **Gateway:**
- `modules/datamodels/datamodelAiAudit.py` (neu — AI-Audit-Log Datenmodell)
- `modules/shared/aiAuditLogger.py` (neu — Logger für AI-Datenflüsse)
- `modules/routes/routeAudit.py` (neu — API-Endpoints für Audit-Daten)
- `modules/system/mainSystem.py` (Navigation: neue Subgroup "Übersichten")
- `modules/serviceCenter/services/serviceAi/mainServiceAi.py` (AI-Audit-Log-Einträge schreiben)
- `modules/serviceCenter/services/serviceAgent/mainServiceAgent.py` (Agent-Calls loggen)
- **Frontend:**
- `pages/ComplianceAuditPage.tsx` (neu — Hauptseite mit 3 Tabs)
- `api/auditApi.ts` (neu — API-Funktionen)
- `hooks/useAudit.ts` (neu — Hooks für Audit-Daten)
- `config/pageRegistry.tsx` (Icon-Eintrag)
- `App.tsx` (Route)
- `components/Navigation/MandateNavigation.tsx` (ggf. Anpassung für Subgroup-Rendering)
- **DB-Migration:** ja — neue Tabelle `ai_audit_log`
- **Andere Komponenten:** keine
## Entscheidungen
| Datum | Entscheidung | Begründung |
|-------|-------------|------------|
| 2026-04-13 | Neues `AiAuditLog`-Modell statt Erweiterung von `AuditLogEntry` | AuditLogEntry ist für Security/GDPR optimiert. AI-Datenflüsse haben andere Felder (Model, Tokens, Content). Trennung hält beide Systeme sauber. |
| 2026-04-13 | Content-Speicherung als opt-in pro Mandant | Datenschutz: nicht jeder Mandant will, dass Prompts/Responses gespeichert werden. Default: nur Metadaten. |
| 2026-04-13 | "Übersichten" als Subgroup unter "Meine Sicht" (nicht als eigene Section) | Konsistent mit bestehendem Pattern (Basisdaten, Nutzung sind auch Subgroups). Kein neuer Top-Level-Block nötig. |
| 2026-04-13 | RBAC: Mandate-Admin + neue Rolle `compliance-viewer` | Nicht jeder Admin braucht Audit-Zugriff. Dedizierte Rolle ermöglicht feingranulare Kontrolle. |
---
## Umsetzungs-Checkliste
### Phase 1: Navigation — Subgroup "Übersichten" (Gateway + Frontend)
- [x] **`mainSystem.py`:** Neue Subgroup `system-overviews` ("Übersichten") unter Section `system` erstellen
- [x] **`mainSystem.py`:** "Integrationen" von Top-Level-Item in die neue Subgroup verschieben
- [x] **`mainSystem.py`:** Neues Item "Compliance & Audit" in Subgroup `system-overviews` hinzufügen
- `objectKey: "ui.system.complianceAudit"`, `path: "/compliance-audit"`, `icon: "FaShieldAlt"`
- [x] **`pageRegistry.tsx`:** Icon-Eintrag für `page.system.complianceAudit`
- [x] **`App.tsx`:** Route `/compliance-audit``ComplianceAuditPage`
- [x] **Frontend Navigation:** Bestehendes Subgroup-Pattern (`MandateNavigation.tsx`) rendert korrekt — keine Änderung nötig
### Phase 2: Backend — AI-Audit-Log Datenmodell & Logger
- [x] **`datamodelAiAudit.py`** (neu) — Datenmodell:
```python
class AiAuditLogEntry(BaseModel):
id: str
timestamp: float
userId: str
username: Optional[str]
mandateId: str
featureInstanceId: Optional[str]
featureCode: Optional[str]
instanceLabel: Optional[str]
aiProvider: str # z.B. "azure-openai", "anthropic"
aiModel: str # z.B. "gpt-4o", "claude-3.5-sonnet"
operationType: str # z.B. "chat", "embedding", "image", "tts"
tokensInput: Optional[int]
tokensOutput: Optional[int]
processingTimeMs: Optional[int]
priceCHF: Optional[float]
neutralizationActive: bool = False
neutralizationMappingsCount: Optional[int]
contentStored: bool = False
contentInputHash: Optional[str] # SHA-256 des Inputs
contentInputPreview: Optional[str] # Erste 200 Zeichen (immer)
contentOutputPreview: Optional[str] # Erste 200 Zeichen (immer)
# Full content nur wenn Mandant opt-in hat
contentInputFull: Optional[str]
contentOutputFull: Optional[str]
success: bool = True
errorMessage: Optional[str]
```
- [x] **`aiAuditLogger.py`** (neu) — Service zum Schreiben von AI-Audit-Einträgen
- `logAiCall(...)` — schreibt einen Eintrag
- `getAiAuditLogs(mandateId, filters)` — liest Einträge mit Pagination
- `getAiAuditStats(mandateId, timeRange, groupBy)` — Aggregationen für Tab C
- [x] **DB-Tabelle** `ai_audit_log` — Auto-Init via `_ensureTableExists(AiAuditLogEntry)` im DatabaseConnector-Pattern
### Phase 3: Backend — AI-Audit in AI-Pipeline integrieren
- [x] **`mainServiceAi.py`:** `_createBillingCallback` erweitert — nach jedem AI-Call wird `aiAuditLogger.logAiCall()` aufgerufen
- Provider, Model, Tokens, Processing-Time aus `AiCallResponse`
- Content-Output-Preview (erste 500 Zeichen) wird immer gespeichert
- Non-critical: try/except — Audit-Fehler brechen AI-Calls nicht ab
- [x] **`mainServiceAgent.py`:** Agent-Calls werden über serviceAi geloggt (delegiert an _createBillingCallback)
- [x] **Neutralisierungs-Integration:** Felder `neutralizationActive` + `neutralizationMappingsCount` im Datenmodell vorbereitet
### Phase 4: Backend — API-Endpoints
- [x] **`routeAudit.py`** (neu) — API-Endpoints:
- `GET /api/audit/ai-log` — AI-Datenfluss-Log (Tab A)
- Query-Params: `userId`, `featureInstanceId`, `aiModel`, `dateFrom`, `dateTo`, `limit`, `offset`
- RBAC: SysAdmin, Mandate-Admin oder `ui.system.complianceAudit` view
- `GET /api/audit/ai-log/{entryId}/content` — Full Content Download (Tab A Detail)
- RBAC: wie oben
- `GET /api/audit/log` — Security/GDPR Audit-Log (Tab B)
- Query-Params: `userId`, `category`, `action`, `dateFrom`, `dateTo`, `limit`
- RBAC: wie oben
- `GET /api/audit/stats` — Audit-Statistiken (Tab C)
- Query-Params: `timeRange` (1365 Tage), `groupBy` (model/user/feature/day)
- RBAC: wie oben
- [x] **`app.py`:** Router registriert (`auditRouter`)
### Phase 5: Frontend — Compliance & Audit Page
- [x] **`ComplianceAuditPage.tsx`** (neu) — Hauptseite mit 3 Tabs:
**Tab A: AI-Datenfluss-Log**
- Tabelle: Zeitpunkt, User, Feature/Instanz, AI-Modell, Typ, Tokens (↑/↓), Kosten (CHF), Neutralisierung (✓/), Status
- Sortierung: nach Zeitpunkt (neueste zuerst, Backend ORDER BY)
- Pagination (50er-Schritte)
**Tab B: Audit-Log**
- Tabelle: Zeitpunkt, User, Kategorie (farbcodiert), Aktion, Ressource, Details, Status (✓/✗), IP
- Farbcodierung: security (rot), gdpr (violett), permission (orange), access (blau), key (grün)
**Tab C: Audit-Statistik**
- Zeitraum-Selektor: 7 / 30 / 90 Tage
- KPI-Karten: AI-Aufrufe, Neutralisierungsquote, Genutzte Modelle, Gesamtkosten
- Charts (via recharts): AI-Calls/Tag (Line), Kosten-Verlauf (Line), nach Modell (Pie), nach Feature (Bar), Top-Nutzer (horizontal Bar)
- [x] **API-Aufrufe** direkt über `useApiRequest` Hook (kein separates `auditApi.ts`/`useAudit.ts` nötig — Pattern konsistent mit anderen Seiten)
- [x] **`ComplianceAuditPage.module.css`** — CSS Module mit Dark-Mode-Support via CSS-Variablen, responsive Chart-Grid
### Querschnitt-Checks
- [x] API-Endpunkte: 4 neue Endpoints unter `/api/audit/`
- [x] DB-Schema / Migration: `AiAuditLogEntry` — Auto-Init via `_ensureTableExists`
- [x] Frontend-Komponenten: `ComplianceAuditPage` (neu), Navigation-Anpassung
- [x] RBAC / Permissions: SysAdmin + Mandate-Admin + `ui.system.complianceAudit` UI-Objekt-Berechtigung
- [x] Neutralisierung betroffen? Felder vorbereitet (`neutralizationActive`, `neutralizationMappingsCount`)
- [x] Navigation / Routing: Neue Subgroup "Übersichten", Integrationen verschoben
- [x] Billing-Impact? Nein (ergänzend zu Billing, nicht ersetzend)
- [x] i18n: Alle Frontend-Labels mit `t()`, Backend-Labels mit `apiRouteContext`, Pydantic-Labels mit `@i18nModel` + `json_schema_extra["label"]`
---
## Akzeptanzkriterien
| # | Kriterium (Given-When-Then) | Prio |
|---|---------------------------|------|
| 1 | Given Navigation "Meine Sicht", When User die Sidebar öffnet, Then gibt es eine Subgroup "Übersichten" mit "Integrationen" und "Compliance & Audit" | must |
| 2 | Given Compliance-Seite Tab A, When ein Compliance-Manager die Seite öffnet, Then sieht er eine Tabelle aller AI-Calls seines Mandanten mit: Zeitpunkt, User, Instanz, Modell, Tokens, Kosten, Neutralisierungs-Status | must |
| 3 | Given AI-Audit-Log-Eintrag mit gespeichertem Content, When der User auf "Download" klickt, Then erhält er den vollständigen Input/Output des AI-Calls | must |
| 4 | Given Compliance-Seite Tab B, When der User den Audit-Log öffnet, Then sieht er alle Security/GDPR/Permission-Events seines Mandanten als Tabelle | must |
| 5 | Given Compliance-Seite Tab C, When der User "Letzte 30 Tage" wählt, Then sieht er grafische Auswertungen: AI-Calls/Tag, Calls nach Modell, Kosten-Verlauf | must |
| 6 | Given ein User ohne Compliance-Rolle, When er `/compliance-audit` aufruft, Then sieht er die Seite nicht in der Navigation und erhält 403 beim API-Call | must |
| 7 | Given Neutralisierung aktiv bei einem AI-Call, When der Call im AI-Audit-Log erscheint, Then ist `neutralizationActive=true` und die Mapping-Anzahl sichtbar | should |
| 8 | Given AI-Audit-Log mit 10.000+ Einträgen, When der User die Seite öffnet, Then lädt die Tabelle in <2s (Pagination, keine Full-Load) | should |
## Testplan
| ID | AC | Art | Automatisiert | Repo-Pfad | Status |
|----|----|-----|--------------|-----------|--------|
| T1 | 1 | e2e | nein | Manuell: Navigation prüfen | pending |
| T2 | 2, 3 | api | ja | gateway/tests/audit/test_ai_audit_log.py | pending |
| T3 | 4 | api | ja | gateway/tests/audit/test_audit_log_api.py | pending |
| T4 | 5 | e2e | nein | Manuell: Charts prüfen | pending |
| T5 | 6 | api | ja | gateway/tests/audit/test_audit_rbac.py | pending |
| T6 | 7 | integration | ja | gateway/tests/audit/test_ai_audit_neutralization.py | pending |
| T7 | 8 | performance | nein | Manuell: Load-Test mit >10k Einträgen | pending |
## Links
- Bestehendes Audit-System: `gateway/modules/shared/auditLogger.py`
- Audit-Datenmodell: `gateway/modules/datamodels/datamodelAudit.py`
- AI-Datenmodell: `gateway/modules/datamodels/datamodelAi.py`
- Billing-Service: `gateway/modules/serviceCenter/services/serviceBilling/mainServiceBilling.py`
- AI-Service: `gateway/modules/serviceCenter/services/serviceAi/mainServiceAi.py`
- Navigation: `gateway/modules/system/mainSystem.py`
- Integrationsseite: `frontend_nyla/src/pages/IntegrationsOverviewPage.tsx`
- Navigation-Rendering: `frontend_nyla/src/components/Navigation/MandateNavigation.tsx`
## Abschluss
- [x] b-reference/ aktualisiert (`b-reference/platform/audit.md` — neu angelegt)
- [x] TOPICS.md aktualisiert (neues Thema "Compliance & Audit")
- [x] Dieses Dokument → c-work/4-done/ verschoben