# 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) - [ ] **`mainSystem.py`:** Neue Subgroup `system-overviews` ("Übersichten") unter Section `system` erstellen - [ ] **`mainSystem.py`:** "Integrationen" von Top-Level-Item in die neue Subgroup verschieben - [ ] **`mainSystem.py`:** Neues Item "Compliance & Audit" in Subgroup `system-overviews` hinzufügen - `objectKey: "ui.system.complianceAudit"`, `path: "/compliance-audit"`, `icon: "FaShieldAlt"` - [ ] **`pageRegistry.tsx`:** Icon-Eintrag für `page.system.complianceAudit` - [ ] **`App.tsx`:** Route `/compliance-audit` → `ComplianceAuditPage` - [ ] **Frontend Navigation:** Sicherstellen, dass `MandateNavigation.tsx` Subgroups unter "Meine Sicht" korrekt rendert (bestehendes Pattern: Basisdaten, Nutzung) ### Phase 2: Backend — AI-Audit-Log Datenmodell & Logger - [ ] **`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] ``` - [ ] **`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 - [ ] **DB-Tabelle** `ai_audit_log` anlegen (via DatabaseConnector-Pattern) ### Phase 3: Backend — AI-Audit in AI-Pipeline integrieren - [ ] **`mainServiceAi.py`:** Nach jedem AI-Call `aiAuditLogger.logAiCall()` aufrufen - Provider, Model, Tokens, Processing-Time aus `AiCallResponse` - Content (Input/Output) nur wenn Mandant opt-in - Neutralisierungs-Status aus Call-Context - [ ] **`mainServiceAgent.py`:** Agent-Calls ebenfalls loggen (delegiert an serviceAi) - [ ] **Neutralisierungs-Integration:** Wenn Neutralisierung aktiv, `neutralizationActive=True` + Mapping-Count loggen ### Phase 4: Backend — API-Endpoints - [ ] **`routeAudit.py`** (neu) — API-Endpoints: - `GET /api/audit/ai-log` — AI-Datenfluss-Log (Tab A) - Query-Params: `mandateId`, `userId`, `featureInstanceId`, `aiModel`, `dateFrom`, `dateTo`, `limit`, `offset` - RBAC: Mandate-Admin oder `compliance-viewer` - `GET /api/audit/ai-log/{entryId}/content` — Full Content Download (Tab A Detail) - RBAC: Mandate-Admin oder `compliance-viewer` - `GET /api/audit/log` — Security/GDPR Audit-Log (Tab B) - Query-Params: `mandateId`, `userId`, `category`, `action`, `dateFrom`, `dateTo`, `limit`, `offset` - RBAC: Mandate-Admin oder `compliance-viewer` - `GET /api/audit/stats` — Audit-Statistiken (Tab C) - Query-Params: `mandateId`, `timeRange` (7d/30d/90d/custom), `groupBy` (model/user/feature/day) - RBAC: Mandate-Admin oder `compliance-viewer` ### Phase 5: Frontend — Compliance & Audit Page - [ ] **`ComplianceAuditPage.tsx`** (neu) — Hauptseite mit 3 Tabs: **Tab A: AI-Datenfluss-Log** - Tabelle mit Spalten: Zeitpunkt, User, Instanz (Feature + Label), AI-Modell, Typ, Tokens (In/Out), Kosten, Neutralisierung (Ja/Nein), Preview, Download-Button - Filter: Zeitraum, User, Feature, Modell - Sortierung: nach Zeitpunkt (neueste zuerst) - Pagination - Download-Button pro Eintrag → öffnet Detail-Modal oder lädt Content **Tab B: Audit-Log** - Tabelle mit Spalten: Zeitpunkt, User, Kategorie, Aktion, Ressource, Details, Erfolg, IP - Filter: Zeitraum, User, Kategorie, Aktion - Farbcodierung: Erfolg (grün), Fehler (rot), Warnung (gelb) - Pagination **Tab C: Audit-Statistik** - Zeitraum-Selektor (7 Tage, 30 Tage, 90 Tage, Custom) - Kontext-Filter (Mandant, Feature, User) - Charts: - AI-Calls pro Tag (Liniendiagramm) - AI-Calls nach Modell (Donut/Pie) - AI-Calls nach Feature (Balkendiagramm) - Kosten-Verlauf (Liniendiagramm) - Top-User nach AI-Usage (Balkendiagramm) - Neutralisierungs-Quote (Gauge oder Prozent-Anzeige) - [ ] **`auditApi.ts`** (neu) — API-Funktionen für alle Endpoints - [ ] **`useAudit.ts`** (neu) — Hooks: `useAiAuditLog()`, `useAuditLog()`, `useAuditStats()` - [ ] **CSS/Styling** — konsistent mit bestehenden Admin-Seiten, Dark-Mode-Support ### Querschnitt-Checks - [ ] API-Endpunkte: 4 neue Endpoints unter `/api/audit/` - [ ] DB-Schema / Migration: ja — neue Tabelle `ai_audit_log` - [ ] Frontend-Komponenten: `ComplianceAuditPage` (neu), Navigation-Anpassung - [ ] RBAC / Permissions: Mandate-Admin + neue Rolle `compliance-viewer` - [ ] Neutralisierung betroffen? Ja — Neutralisierungs-Status wird im AI-Audit-Log erfasst - [ ] Navigation / Routing: Neue Subgroup "Übersichten", Integrationen verschoben - [ ] Billing-Impact? Nein (ergänzend zu Billing, nicht ersetzend) - [ ] i18n: Alle Labels mehrsprachig (bestehendes Pattern) --- ## 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 - [ ] b-reference/ aktualisiert (`b-reference/platform/audit.md` — neu anlegen) - [ ] b-reference/gateway/architecture.md aktualisiert (AI-Audit-Logger) - [ ] TOPICS.md aktualisiert (neues Thema "Compliance & Audit") - [ ] Dieses Dokument → z-archive/ verschoben