diff --git a/implementation/Refactor Nyla UI basic components with new mandate SaaS model/analysis_and_implementation_plan.md b/implementation/Refactor Nyla UI basic components with new mandate SaaS model/analysis_and_implementation_plan.md
new file mode 100644
index 0000000..f3db2f1
--- /dev/null
+++ b/implementation/Refactor Nyla UI basic components with new mandate SaaS model/analysis_and_implementation_plan.md
@@ -0,0 +1,852 @@
+# Refactor Nyla UI - Analyse und Implementation Plan
+
+## Datum: 23. Januar 2026
+
+---
+
+## Executive Summary
+
+Die Seiten **Chat Playground**, **Workflows**, **Automations**, **Prompts**, **Files** und **Connections** im neuen UI (`frontend_nyla`) sind inkomplett implementiert. Sie nutzen:
+- Eigene, vereinfachte Table-Komponenten statt des etablierten `FormGenerator`-Systems
+- Fehlende Dashboard- und Chat-Elemente (PlaygroundPage)
+- Keine RBAC-Berechtigungsprüfung
+- Keine Backend-Pagination/Sorting/Filtering
+- Keine standardisierten CRUD-Modals
+
+### Design-Prinzipien für die Implementation
+
+> **WICHTIG:** Das bestehende Look & Feel von Nyla MUSS beibehalten werden!
+>
+> - Keine neuen Styles oder Design-Patterns einführen
+> - Bestehende CSS-Module und Komponenten-Styles wiederverwenden
+> - Nur **fehlende Logik ergänzen**, nicht das visuelle Design ändern
+> - Neue Komponenten müssen sich nahtlos in das bestehende Design einfügen
+
+---
+
+## 1. IST-Analyse
+
+### 1.1 Chat Playground (PlaygroundPage.tsx)
+
+**Aktueller Zustand:**
+Die PlaygroundPage ist extrem vereinfacht und hat fast alle Funktionen aus dem alten UI (`frontend_agents`) verloren.
+
+**Was FEHLT (Vergleich zu `frontend_agents/public/htmlparts/part_workflow.html`):**
+
+| Element | Alt (frontend_agents) | Neu (frontend_nyla) | Ziel |
+|---------|----------------------|---------------------|------|
+| **Layout** | 70/30 Spalten (Chat/Dashboard) | Single-Column, kein Dashboard | **Resizable Spalten mit Drag-Divider** |
+| **Dashboard** | Hierarchisches Dashboard mit Rounds → Operations → Logs | ❌ Komplett fehlt | Logik portieren, Nyla-Styles |
+| **Progress-Tracking** | Progress-Bars pro Operation | ❌ Komplett fehlt | Logik portieren, Nyla-Styles |
+| **Collapse/Expand** | Für Rounds, Operations, Logs | ❌ Komplett fehlt | Logik portieren |
+| **Prompt-Auswahl** | Dropdown mit Prompts aus API | ❌ Fehlt | Bestehende DropdownSelect nutzen |
+| **Workflow-Modus** | Dropdown mit Enum aus Backend | ❌ Fehlt | Bestehende DropdownSelect nutzen |
+| **Datei-Upload** | Button + Drag & Drop, mehrere Dateien | ❌ Fehlt | Bestehende DragDropOverlay nutzen |
+| **Voice Recording** | Mikrofon-Button mit STT | ❌ Fehlt | Logik portieren, Nyla Button-Styles |
+| **Stop/Reset Buttons** | Stop, Reset, Refresh Tokens | Nur Läuft... Button | Bestehende Button-Komponenten |
+| **Data Statistics** | Sent/Received/Time/Tokens | ❌ Fehlt | Logik portieren, Nyla-Styles |
+| **File Preview Modal** | Vorschau, Download, Copy, TTS | ❌ Fehlt | Bestehende Popup-Komponente nutzen |
+| **Unified Content Area** | Kombinierte Logs + Messages chronologisch | Getrennte Listen | Bestehende Log/Messages nutzen |
+| **Auto-Scroll** | Automatisches Scrollen | ❌ Fehlt | Bestehende AutoScroll nutzen |
+| **Empty State** | Mit Link zur Einführung | Einfacher Text | Nyla-Styles |
+
+**Vorhandene Hooks im `frontend_nyla/src/hooks/playground/`:**
+```
+- useDashboardInputForm.ts
+- useDashboardLogTree.ts
+- useWorkflowLifecycle.ts
+- useWorkflowOperations.ts
+- useWorkflowPolling.ts
+- useWorkflows.ts
+- playgroundUtils.ts
+```
+
+**Problem:** Die Hooks sind vorhanden, aber die UI-Komponenten nutzen sie nicht vollständig!
+
+### 1.2 Workflows, Automations, Prompts, Files, Connections
+
+**Aktueller Zustand:**
+Diese Seiten haben eigene, einfache Table-Implementierungen statt `FormGeneratorTable`.
+
+**Vergleich:**
+
+| Feature | AdminUsersPage (korrekt) | WorkflowsPage (falsch) |
+|---------|--------------------------|------------------------|
+| `FormGeneratorTable` | ✅ Verwendet | ❌ Eigene `
` |
+| `FormGeneratorForm` | ✅ Für Create/Edit Modals | ❌ Keine Modals |
+| `attributes` vom Backend | ✅ Über Hook | ❌ Hardcoded Columns |
+| `columns` aus attributes | ✅ Dynamisch generiert | ❌ Hardcoded |
+| Backend-Pagination | ✅ Via hookData | ❌ Client-seitig |
+| Backend-Sorting | ✅ Via hookData | ❌ Client-seitig |
+| Backend-Filtering | ✅ Via hookData | ❌ Client-seitig |
+| Inline-Editing | ✅ Für Boolean-Felder | ❌ Nicht unterstützt |
+| RBAC Permissions | ✅ `permissions?.create !== 'n'` | ❌ Keine Prüfung |
+| Action Buttons | ✅ Standard + Custom | ❌ Nur Delete |
+| Loading State | ✅ Overlay | ❌ Einfacher Text |
+| Empty State | ✅ Mit Icon und CTA | ❌ Einfacher Text |
+| Error State | ✅ Mit Retry-Button | ❌ Einfacher Text |
+
+---
+
+## 2. Vorhandene Ressourcen im frontend_nyla
+
+### 2.1 FormGenerator-System (vollständig implementiert)
+
+**Komponenten:**
+- `FormGeneratorTable` - Tabelle mit Pagination, Sorting, Filtering
+- `FormGeneratorForm` - Backend-driven Formulare
+- `FormGeneratorList` - Listenansicht
+- `FormGeneratorControls` - Such- und Filter-Controls
+- Action Buttons: Edit, Delete, View, Copy, Custom
+
+**Features:**
+- FK-Resolution (Foreign Keys anzeigen als Labels)
+- TextMultilingual-Support
+- Inline-Editing für Boolean-Felder
+- Column-Resizing mit LocalStorage-Persistenz
+- Multi-Column-Sorting
+
+### 2.2 Vorhandene Hooks
+
+**Workflows:**
+- `useWorkflows.ts` - `useUserWorkflows()`, `useWorkflowOperations()`
+
+**Automations:**
+- `useAutomations.ts` - `useAutomations()`, `useAutomationOperations()`
+
+**Prompts:**
+- `usePrompts.ts` - `usePrompts()`, `usePromptOperations()`
+
+**Files:**
+- `useFiles.ts` - `useUserFiles()`, `useFileOperations()`
+
+**Connections:**
+- `useConnections.ts` - `useConnections()` (vollständig)
+
+**Playground-spezifisch:**
+- `hooks/playground/useDashboardInputForm.ts`
+- `hooks/playground/useDashboardLogTree.ts`
+- `hooks/playground/useWorkflowLifecycle.ts`
+- `hooks/playground/useWorkflowOperations.ts`
+- `hooks/playground/useWorkflowPolling.ts`
+
+### 2.3 Bestehende Nyla UI-Komponenten (WIEDERVERWENDEN!)
+
+> **WICHTIG:** Diese Komponenten definieren das Nyla Look & Feel und sollten
+> bei der Implementation wiederverwendet werden!
+
+**UiComponents (in `components/UiComponents/`):**
+- `Button/` - Standard-Buttons, CreateButton, UploadButton
+- `TextField/` - Input-Felder
+- `DropdownSelect/` - Select-Komponente
+- `DragDropOverlay/` - Für File-Upload mit Drag & Drop
+- `Log/` - Log-Darstellung mit LogMessage
+- `Messages/` - Chat-Nachrichten
+- `Popup/` - Modal-Dialoge
+- `Toast/` - Notifications
+- `Tabs/` - Tab-Navigation
+- `AutoScroll/` - Auto-Scroll-Funktionalität
+
+**Diese Komponenten-Styles übernehmen:**
+- Farben (CSS-Variablen)
+- Typografie
+- Abstände/Padding
+- Border-Radien
+- Hover-/Focus-States
+
+---
+
+## 3. Implementation Plan
+
+### Phase 1: Chat Playground (Priorität HOCH)
+
+#### 3.1.1 Layout-Refactoring
+
+**Datei:** `frontend_nyla/src/pages/workflows/PlaygroundPage.tsx`
+
+**Design-Prinzip:** Bestehendes Nyla Look & Feel beibehalten, nur fehlende Logik ergänzen!
+
+1. **Resizable Spalten-Layout mit Drag-Divider:**
+
+Statt eines fixen 70/30-Layouts wird ein **dynamisch anpassbares Layout** implementiert:
+- Default: 70% Chat / 30% Dashboard
+- Benutzer kann die Trennlinie mit der Maus verschieben
+- Min/Max-Grenzen: Chat min 40%, Dashboard min 20%
+- Spaltenbreite wird in LocalStorage persistiert
+
+```tsx
+import { useResizablePanels } from '../../hooks/useResizablePanels';
+
+const PlaygroundPage: React.FC = () => {
+ // Hook für resizable panels mit LocalStorage-Persistenz
+ const {
+ leftWidth, // in Prozent (default 70)
+ isDragging,
+ handleMouseDown, // Auf Divider anwenden
+ } = useResizablePanels({
+ storageKey: 'playground-panel-width',
+ defaultLeftWidth: 70,
+ minLeftWidth: 40,
+ maxLeftWidth: 80,
+ });
+
+ return (
+
+
+
+ {/* Links - Chat Messages (dynamische Breite) */}
+
+
+
+
+ {/* Resizable Divider */}
+
+
+ {/* Rechts - Dashboard (dynamische Breite) */}
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+```
+
+#### 3.1.1.1 Hook: useResizablePanels
+
+**Zu erstellen:** `frontend_nyla/src/hooks/useResizablePanels.ts`
+
+```typescript
+import { useState, useCallback, useEffect, useRef } from 'react';
+
+interface UseResizablePanelsOptions {
+ storageKey: string;
+ defaultLeftWidth: number; // in %
+ minLeftWidth: number; // in %
+ maxLeftWidth: number; // in %
+}
+
+export const useResizablePanels = ({
+ storageKey,
+ defaultLeftWidth,
+ minLeftWidth,
+ maxLeftWidth,
+}: UseResizablePanelsOptions) => {
+ // Initialer Wert aus LocalStorage oder Default
+ const [leftWidth, setLeftWidth] = useState(() => {
+ const stored = localStorage.getItem(storageKey);
+ if (stored) {
+ const parsed = parseFloat(stored);
+ if (!isNaN(parsed) && parsed >= minLeftWidth && parsed <= maxLeftWidth) {
+ return parsed;
+ }
+ }
+ return defaultLeftWidth;
+ });
+
+ const [isDragging, setIsDragging] = useState(false);
+ const containerRef = useRef(null);
+
+ // Mouse-Event-Handler
+ const handleMouseDown = useCallback((e: React.MouseEvent) => {
+ e.preventDefault();
+ setIsDragging(true);
+ containerRef.current = (e.target as HTMLElement).closest('.chatColumns');
+ }, []);
+
+ useEffect(() => {
+ if (!isDragging) return;
+
+ const handleMouseMove = (e: MouseEvent) => {
+ if (!containerRef.current) return;
+
+ const containerRect = containerRef.current.getBoundingClientRect();
+ const newLeftWidth = ((e.clientX - containerRect.left) / containerRect.width) * 100;
+
+ // Clamp zwischen min und max
+ const clampedWidth = Math.max(minLeftWidth, Math.min(maxLeftWidth, newLeftWidth));
+ setLeftWidth(clampedWidth);
+ };
+
+ const handleMouseUp = () => {
+ setIsDragging(false);
+ // In LocalStorage speichern
+ localStorage.setItem(storageKey, leftWidth.toString());
+ };
+
+ document.addEventListener('mousemove', handleMouseMove);
+ document.addEventListener('mouseup', handleMouseUp);
+
+ return () => {
+ document.removeEventListener('mousemove', handleMouseMove);
+ document.removeEventListener('mouseup', handleMouseUp);
+ };
+ }, [isDragging, leftWidth, storageKey, minLeftWidth, maxLeftWidth]);
+
+ return {
+ leftWidth,
+ isDragging,
+ handleMouseDown,
+ setLeftWidth,
+ };
+};
+```
+
+#### 3.1.1.2 CSS für Resizable Divider
+
+**In `Playground.module.css` hinzufügen:**
+
+```css
+/* Resizable Divider - passend zum Nyla Design */
+.resizeDivider {
+ width: 6px;
+ cursor: col-resize;
+ background-color: transparent;
+ position: relative;
+ flex-shrink: 0;
+ z-index: 10;
+ transition: background-color 0.15s ease;
+}
+
+.resizeDivider:hover,
+.resizeDivider.dragging {
+ background-color: var(--color-border-hover, rgba(255, 255, 255, 0.1));
+}
+
+.dividerHandle {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 4px;
+ height: 40px;
+ border-radius: 2px;
+ background-color: var(--color-text-muted, rgba(255, 255, 255, 0.3));
+ opacity: 0;
+ transition: opacity 0.15s ease;
+}
+
+.resizeDivider:hover .dividerHandle,
+.resizeDivider.dragging .dividerHandle {
+ opacity: 1;
+}
+
+/* Verhindert Text-Selektion während Drag */
+.chatColumns.dragging {
+ user-select: none;
+}
+```
+
+#### 3.1.2 Neue Komponenten erstellen
+
+> **Design-Prinzip:** Alle neuen Komponenten müssen das bestehende Nyla Look & Feel nutzen!
+> - Bestehende CSS-Variablen verwenden (aus `:root` oder Theme)
+> - Vorhandene Button-/Input-Styles wiederverwenden
+> - Keine neuen Farbschemata oder Typografie einführen
+> - Komponenten-Styles in Module-CSS kapseln
+
+**Zu erstellen in `frontend_nyla/src/components/Playground/`:**
+
+| Komponente | Beschreibung | Logik basiert auf | Styles |
+|------------|--------------|-------------------|--------|
+| `WorkflowDashboard.tsx` | Hierarchisches Dashboard | `workflowUiRendererDashboard.js` | Nyla-Styles |
+| `UnifiedContentArea.tsx` | Kombinierte Logs + Messages | `workflowUiRenderer.js` | Nyla-Styles |
+| `UserInputArea.tsx` | Prompt-Auswahl, Input, Buttons | `part_workflow.html` | Bestehende Nyla Input-Styles |
+| `DataStatistics.tsx` | Sent/Received/Time/Tokens | `part_workflow.html` | Nyla-Styles |
+| `FilePreviewModal.tsx` | Datei-Vorschau | Existiert teilweise | Bestehende Modal-Styles |
+| `WorkflowControls.tsx` | Stop, Reset, Start Buttons | `workflowUiControls.js` | Bestehende Button-Styles |
+
+**Wichtig:** Diese Komponenten sollen die **Logik** aus dem alten `frontend_agents` übernehmen,
+aber das **visuelle Design** von Nyla beibehalten. Das heisst:
+- Hooks und State-Management aus `frontend_agents` portieren
+- CSS-Styles aus den bestehenden Nyla-Komponenten verwenden/erweitern
+
+#### 3.1.3 Dashboard Implementation
+
+**State-Struktur:**
+```typescript
+interface DashboardLogTree {
+ rounds: Map;
+ rootOperations: string[];
+ expanded: boolean;
+ isCompleted: boolean;
+ }>;
+ operations: Map;
+ parentId: string | null;
+ expanded: boolean;
+ latestProgress: number | null;
+ latestStatus: string | null;
+ roundNumber: number;
+ }>;
+ logExpandedStates: Map;
+ currentRound: number | null;
+}
+```
+
+**Verwendung von existierendem Hook:**
+```typescript
+import { useDashboardLogTree } from '../../hooks/playground/useDashboardLogTree';
+
+const {
+ dashboardLogTree,
+ processDashboardLogs,
+ toggleRoundExpanded,
+ toggleOperationExpanded,
+ clearDashboard,
+} = useDashboardLogTree();
+```
+
+#### 3.1.4 Input-Bereich Implementation
+
+**Neue Elemente:**
+- Prompt-Dropdown (aus `usePrompts()`)
+- Workflow-Modus-Dropdown (aus `/api/options/workflow.mode`)
+- File-Upload mit Drag & Drop
+- Voice-Recording-Button
+- Stop/Reset/Start-Buttons
+
+### Phase 2-6: Data-Seiten (Workflows, Automations, Prompts, Files, Connections)
+
+> **Design-Prinzip für alle Data-Seiten:**
+> - `FormGeneratorTable` und `FormGeneratorForm` verwenden (bereits Nyla-konform)
+> - Bestehende Page-Header-Styles aus Admin-Seiten übernehmen
+> - Keine neuen Layouts/Designs einführen
+> - Nur fehlende Hooks/Logik ergänzen
+
+### Phase 2: Workflows Page (Priorität HOCH)
+
+#### 3.2.1 Hook erweitern
+
+**Datei:** `frontend_nyla/src/hooks/useWorkflows.ts`
+
+Erweitern um:
+```typescript
+export const useWorkflowsAdmin = () => {
+ const { data, loading, error, refetch } = useApi('/api/workflows/');
+
+ // Attributes vom Backend
+ const { data: attributesResponse } = useApi('/api/attributes/ChatWorkflow');
+
+ return {
+ data: data?.items || [],
+ attributes: attributesResponse?.attributes || [],
+ columns: generateColumns(attributesResponse?.attributes),
+ permissions: data?.permissions,
+ pagination: data?.pagination,
+ loading,
+ error,
+ refetch,
+ // Operations
+ handleDelete: async (id: string) => { /* ... */ },
+ handleInlineUpdate: async (id: string, data: Partial) => { /* ... */ },
+ };
+};
+```
+
+#### 3.2.2 Page umschreiben
+
+**Datei:** `frontend_nyla/src/pages/workflows/WorkflowsPage.tsx`
+
+Nach Pattern von `AdminUsersPage.tsx`:
+
+```tsx
+import { FormGeneratorTable } from '../../components/FormGenerator';
+import { useWorkflowsAdmin } from '../../hooks/useWorkflows';
+
+export const WorkflowsPage: React.FC = () => {
+ const {
+ data: workflows,
+ attributes,
+ columns,
+ permissions,
+ pagination,
+ loading,
+ error,
+ refetch,
+ handleDelete,
+ handleInlineUpdate,
+ } = useWorkflowsAdmin();
+
+ return (
+
+
+
,
+ onClick: handleContinue,
+ title: 'Workflow fortsetzen',
+ }
+ ]}
+ onDelete={handleDelete}
+ hookData={{
+ refetch,
+ permissions,
+ pagination,
+ handleDelete,
+ handleInlineUpdate,
+ }}
+ />
+
+ );
+};
+```
+
+### Phase 3: Automations Page
+
+**Analog zu Workflows Page:**
+1. Hook erweitern: `useAutomationsAdmin()`
+2. Page umschreiben mit `FormGeneratorTable`
+3. Custom Actions: Execute, Toggle Active
+
+### Phase 4: Prompts Page
+
+**Spezifische Anpassungen:**
+1. Hook erweitern: `usePromptsAdmin()`
+2. Page umschreiben mit `FormGeneratorTable`
+3. Create/Edit Modal mit `FormGeneratorForm`
+4. Content-Feld als Textarea
+
+### Phase 5: Files Page
+
+**Spezifische Anpassungen:**
+1. Hook erweitern: `useFilesAdmin()`
+2. Page umschreiben mit `FormGeneratorTable`
+3. Custom Actions: Download, Preview
+4. Upload-Button mit `UploadButton`-Komponente
+
+### Phase 6: Connections Page
+
+**Spezifische Anpassungen:**
+1. Hook erweitern: `useConnectionsAdmin()`
+2. Page umschreiben mit `FormGeneratorTable`
+3. Custom Actions: Connect, Refresh Token
+4. Provider-spezifische Buttons (Google, Microsoft)
+
+---
+
+## 4. Detaillierte Änderungsliste
+
+### 4.1 Zu erstellende Dateien
+
+```
+frontend_nyla/src/
+├── hooks/
+│ └── useResizablePanels.ts # NEU: Hook für resizable panels
+├── components/
+│ └── Playground/
+│ ├── index.ts
+│ ├── Playground.module.css # NEU: Layout-Styles inkl. Divider
+│ ├── WorkflowDashboard/
+│ │ ├── index.ts
+│ │ ├── WorkflowDashboard.tsx # Logik aus workflowUiRendererDashboard.js
+│ │ ├── WorkflowDashboard.module.css
+│ │ ├── DashboardRound.tsx
+│ │ ├── DashboardOperation.tsx
+│ │ └── DashboardProgressBar.tsx
+│ ├── UnifiedContentArea/
+│ │ ├── index.ts
+│ │ ├── UnifiedContentArea.tsx # Logik aus workflowUiRenderer.js
+│ │ ├── UnifiedContentArea.module.css
+│ │ ├── MessageItem.tsx
+│ │ └── LogItem.tsx
+│ ├── UserInputArea/
+│ │ ├── index.ts
+│ │ ├── UserInputArea.tsx # Logik aus workflow.js + part_workflow.html
+│ │ ├── UserInputArea.module.css
+│ │ ├── PromptSelector.tsx
+│ │ ├── WorkflowModeSelector.tsx
+│ │ └── VoiceRecordButton.tsx
+│ ├── WorkflowControls/
+│ │ ├── index.ts
+│ │ ├── WorkflowControls.tsx # Logik aus workflowUiControls.js
+│ │ └── WorkflowControls.module.css
+│ └── DataStatistics/
+│ ├── index.ts
+│ ├── DataStatistics.tsx
+│ └── DataStatistics.module.css
+```
+
+> **Hinweis:** Alle `.module.css` Dateien sollen bestehende Nyla CSS-Variablen nutzen
+> und sich nahtlos ins bestehende Design einfügen!
+
+### 4.2 Zu ändernde Dateien
+
+| Datei | Änderung |
+|-------|----------|
+| `pages/workflows/PlaygroundPage.tsx` | Kompletter Rewrite mit neuen Komponenten |
+| `pages/workflows/WorkflowsPage.tsx` | Umschreiben auf FormGeneratorTable |
+| `pages/workflows/AutomationsPage.tsx` | Umschreiben auf FormGeneratorTable |
+| `pages/basedata/PromptsPage.tsx` | Umschreiben auf FormGeneratorTable |
+| `pages/basedata/FilesPage.tsx` | Umschreiben auf FormGeneratorTable |
+| `pages/basedata/ConnectionsPage.tsx` | Umschreiben auf FormGeneratorTable |
+| `hooks/useWorkflows.ts` | Admin-Hook hinzufügen |
+| `hooks/useAutomations.ts` | Admin-Hook hinzufügen |
+| `hooks/usePrompts.ts` | Admin-Hook hinzufügen |
+| `hooks/useFiles.ts` | Admin-Hook hinzufügen |
+| `hooks/useConnections.ts` | Admin-Hook hinzufügen |
+
+### 4.3 CSS-Anpassungen
+
+**Neue CSS-Module:**
+- `Playground.module.css` - Hauptlayout
+- `WorkflowDashboard.module.css` - Dashboard-Styles
+- `UnifiedContentArea.module.css` - Content-Styles
+
+**Bestehende zu aktualisieren:**
+- `WorkflowPages.module.css` - Für alle Workflow-Seiten
+
+---
+
+## 5. API-Endpunkte (bereits vorhanden)
+
+| Endpunkt | Verwendung |
+|----------|------------|
+| `/api/workflows/` | Liste, CRUD |
+| `/api/workflows/{id}` | Einzelner Workflow |
+| `/api/workflows/{id}/chat-data` | Unified Chat-Daten |
+| `/api/automations/` | Liste, CRUD |
+| `/api/prompts/` | Liste, CRUD |
+| `/api/files/` | Liste, CRUD |
+| `/api/connections/` | Liste, CRUD |
+| `/api/attributes/{EntityType}` | Attribute-Definitionen |
+| `/api/options/workflow.mode` | Workflow-Modus-Enum |
+
+---
+
+## 6. Migrations-Checkliste
+
+### Chat Playground
+- [ ] `useResizablePanels` Hook erstellen
+- [ ] Resizable Spalten-Layout implementieren (mit Drag-Divider)
+- [ ] WorkflowDashboard-Komponente erstellen (Logik aus frontend_agents, Nyla-Styles)
+- [ ] UnifiedContentArea-Komponente erstellen (Logik aus frontend_agents, Nyla-Styles)
+- [ ] UserInputArea mit allen Features erstellen (Nyla Input-Styles)
+- [ ] DataStatistics-Komponente erstellen (Nyla-Styles)
+- [ ] Polling integrieren (bestehende Hooks nutzen)
+- [ ] File-Upload mit Drag & Drop (bestehende DragDropOverlay nutzen)
+- [ ] Voice-Recording integrieren
+- [ ] LocalStorage-Persistenz für Panel-Breite
+
+### Workflows Page
+- [ ] Hook `useWorkflowsAdmin` erstellen
+- [ ] Page auf FormGeneratorTable umstellen
+- [ ] Action Buttons konfigurieren
+- [ ] RBAC-Permissions implementieren
+
+### Automations Page
+- [ ] Hook `useAutomationsAdmin` erstellen
+- [ ] Page auf FormGeneratorTable umstellen
+- [ ] Toggle Active implementieren
+- [ ] Execute-Action implementieren
+
+### Prompts Page
+- [ ] Hook `usePromptsAdmin` erstellen
+- [ ] Page auf FormGeneratorTable umstellen
+- [ ] Create/Edit Modals mit FormGeneratorForm
+- [ ] Content-Textarea korrekt anzeigen
+
+### Files Page
+- [ ] Hook `useFilesAdmin` erstellen
+- [ ] Page auf FormGeneratorTable umstellen
+- [ ] Download/Preview Actions
+- [ ] Upload-Button integrieren
+
+### Connections Page
+- [ ] Hook `useConnectionsAdmin` erstellen
+- [ ] Page auf FormGeneratorTable umstellen
+- [ ] Connect/Refresh Actions
+- [ ] Provider-spezifische Buttons
+
+---
+
+## 7. Schätzung Aufwand
+
+| Phase | Aufwand | Priorität |
+|-------|---------|-----------|
+| Phase 1: Chat Playground | Hoch | KRITISCH |
+| Phase 2: Workflows Page | Mittel | Hoch |
+| Phase 3: Automations Page | Mittel | Hoch |
+| Phase 4: Prompts Page | Niedrig | Mittel |
+| Phase 5: Files Page | Niedrig | Mittel |
+| Phase 6: Connections Page | Niedrig | Mittel |
+
+---
+
+## 8. Anhang: Pattern-Referenz
+
+### Standard-Page-Struktur
+
+```tsx
+import React, { useState, useMemo } from 'react';
+import { FormGeneratorTable, FormGeneratorForm } from '../../components/FormGenerator';
+import { useEntityAdmin, useEntityOperations } from '../../hooks/useEntity';
+import styles from './Page.module.css';
+
+interface Entity {
+ id: string;
+ [key: string]: any;
+}
+
+export const EntityPage: React.FC = () => {
+ // Hooks
+ const {
+ data,
+ attributes,
+ columns,
+ permissions,
+ pagination,
+ loading,
+ error,
+ refetch,
+ fetchById,
+ handleInlineUpdate,
+ updateOptimistically,
+ } = useEntityAdmin();
+
+ const {
+ handleCreate,
+ handleUpdate,
+ handleDelete,
+ } = useEntityOperations();
+
+ // State
+ const [showCreateModal, setShowCreateModal] = useState(false);
+ const [editingItem, setEditingItem] = useState(null);
+
+ // Permissions
+ const canCreate = permissions?.create !== 'n';
+ const canUpdate = permissions?.update !== 'n';
+ const canDelete = permissions?.delete !== 'n';
+
+ // Form Attributes
+ const formAttributes = useMemo(() => {
+ return (attributes || []).filter(attr => !['id'].includes(attr.name));
+ }, [attributes]);
+
+ // Handlers
+ const handleEditClick = async (item: Entity) => {
+ const fullItem = await fetchById(item.id);
+ if (fullItem) setEditingItem(fullItem);
+ };
+
+ const handleCreateSubmit = async (data: Partial) => {
+ const result = await handleCreate(data);
+ if (result.success) {
+ setShowCreateModal(false);
+ refetch();
+ }
+ };
+
+ const handleEditSubmit = async (data: Partial) => {
+ if (!editingItem) return;
+ const result = await handleUpdate(editingItem.id, data);
+ if (result.success) {
+ setEditingItem(null);
+ refetch();
+ }
+ };
+
+ // Render
+ return (
+
+
setShowCreateModal(true) : undefined}
+ />
+
+
+
+ {/* Create Modal */}
+ {showCreateModal && (
+ setShowCreateModal(false)}>
+ setShowCreateModal(false)}
+ />
+
+ )}
+
+ {/* Edit Modal */}
+ {editingItem && (
+ setEditingItem(null)}>
+ setEditingItem(null)}
+ />
+
+ )}
+
+ );
+};
+```
+
+---
+
+## 9. Design-Konsistenz-Checklist
+
+Bei jeder Implementation prüfen:
+
+- [ ] **CSS-Variablen:** Werden bestehende Nyla CSS-Variablen verwendet? (Farben, Abstände, etc.)
+- [ ] **Komponenten:** Werden bestehende UiComponents wiederverwendet wo möglich?
+- [ ] **Styles:** Sind neue Styles konsistent mit bestehendem Nyla-Design?
+- [ ] **Keine Neuerungen:** Wurden keine neuen Design-Patterns eingeführt?
+- [ ] **Dark/Light Mode:** Funktioniert die Komponente in beiden Modi?
+- [ ] **Responsive:** Funktioniert die Komponente auf verschiedenen Bildschirmgrössen?
+
+---
+
+*Dokumentation erstellt am 23. Januar 2026*
+*Aktualisiert: Resizable Panels und Design-Prinzipien hinzugefügt*
diff --git a/implementation/Saas Multi Tenant Mandate/BACKEND_FEATURE_STRUCTURE_ANALYSIS.md b/implementation/Saas Multi Tenant Mandate/BACKEND_FEATURE_STRUCTURE_ANALYSIS.md
deleted file mode 100644
index f24e4e3..0000000
--- a/implementation/Saas Multi Tenant Mandate/BACKEND_FEATURE_STRUCTURE_ANALYSIS.md
+++ /dev/null
@@ -1,367 +0,0 @@
-# Backend Feature-Struktur Analyse
-
-## 1. Übersicht Aktuelle Architektur
-
-### 1.1 Feature-Hierarchie
-
-```
-Mandate (Mandant)
- └── FeatureInstance (Feature-Instanz)
- └── Feature-Datenbank-Tabellen
- └── Datensätze mit mandateId + featureInstanceId
-```
-
-### 1.2 Datenbank-Struktur
-
-| Datenbank | Zweck | Feature |
-|-----------|-------|---------|
-| `poweron_app` | Zentrale App-Daten | System (User, Mandate, Roles, Features) |
-| `poweron_trustee` | Treuhand-Feature | Trustee |
-| `poweron_chat` | Chat-Feature | Chatbot/Workflow |
-| `poweron_realestate` | Immobilien-Feature | RealEstate |
-
----
-
-## 2. Feature-Definitionen
-
-### 2.1 Datenmodelle (`datamodels/`)
-
-| Feature | Datenmodell-Datei | Tabellen |
-|---------|-------------------|----------|
-| **Trustee** | `datamodelTrustee.py` | TrusteeOrganisation, TrusteeRole, TrusteeAccess, TrusteeContract, TrusteeDocument, TrusteePosition, TrusteePositionDocument |
-| **RealEstate** | `datamodelRealEstate.py` | RealEstateProperty, RealEstateUnit, etc. |
-| **Chat/Workflow** | `datamodelChat.py`, `datamodelWorkflow.py` | ChatSession, ChatMessage, WorkflowExecution, etc. |
-| **Files** | `datamodelFiles.py` | StoredFile, FileMetadata |
-| **System** | `datamodelUam.py`, `datamodelMembership.py` | User, Mandate, FeatureAccess |
-| **RBAC** | `datamodelRbac.py` | Role, AccessRule |
-| **Features** | `datamodelFeatures.py` | Feature, FeatureInstance |
-
-### 2.2 Zentrale Feature-Modelle (`datamodelFeatures.py`)
-
-```python
-class Feature:
- code: str # PK: "trustee", "chatbot", "realestate"
- label: dict # I18n: {"de": "Treuhand", "en": "Trustee"}
- icon: str # "mdi-account-group"
-
-class FeatureInstance:
- id: str # UUID
- featureCode: str # FK → Feature.code
- mandateId: str # FK → Mandate.id (CASCADE DELETE)
- label: str # "Buchhaltung 2025"
- enabled: bool # True/False
-```
-
----
-
-## 3. Interface-Schicht (`interfaces/`)
-
-### 3.1 Feature-spezifische Interfaces
-
-| Interface-Datei | Feature | Datenbank |
-|-----------------|---------|-----------|
-| `interfaceDbTrusteeObjects.py` | Trustee | poweron_trustee |
-| `interfaceDbChatObjects.py` | Chatbot | poweron_chat |
-| `interfaceDbRealEstateObjects.py` | RealEstate | poweron_realestate |
-| `interfaceDbAppObjects.py` | System | poweron_app |
-| `interfaceFeatures.py` | Feature-Verwaltung | poweron_app |
-
-### 3.2 Trustee-Interface Beispiel
-
-```python
-class TrusteeObjects:
- def __init__(self, currentUser, mandateId, featureInstanceId):
- # Verbindet sich mit poweron_trustee Datenbank
- self.mandateId = mandateId
- self.featureInstanceId = featureInstanceId
- # Initialisiert RBAC
- self.rbac = RbacClass(...)
-
- # CRUD mit RBAC + Feature-Level Filterung
- def createOrganisation(self, data):
- data["mandateId"] = self.mandateId
- data["featureInstanceId"] = self.featureInstanceId
- ...
-```
-
-### 3.3 Multi-Tenant Isolation
-
-Jedes Interface:
-1. Erhält `mandateId` und `featureInstanceId` aus dem Request-Context
-2. Setzt diese Werte automatisch bei CREATE
-3. Filtert bei READ/UPDATE/DELETE nach diesen Werten
-4. Prüft RBAC-Berechtigungen (System + Feature-Level)
-
----
-
-## 4. Route-Schicht (`routes/`)
-
-### 4.1 Feature-Routes
-
-| Route-Datei | Prefix | Feature |
-|-------------|--------|---------|
-| `routeFeatures.py` | `/api/features` | Feature-Verwaltung |
-| `routeFeatureTrustee.py` | `/api/trustee` | Trustee-CRUD |
-| `routeFeatureChatbot.py` | `/api/chatbot` | Chatbot |
-| `routeFeatureAutomation.py` | `/api/automation` | Workflow |
-| `routeFeatureRealEstate.py` | `/api/realestate` | Immobilien |
-
-### 4.2 Trustee-Routen (mit instanceId im Pfad) ✅
-
-```
-/api/trustee/{instanceId}/organisations GET, POST
-/api/trustee/{instanceId}/organisations/{id} GET, PUT, DELETE
-/api/trustee/{instanceId}/roles GET, POST
-/api/trustee/{instanceId}/roles/{id} GET, PUT, DELETE
-/api/trustee/{instanceId}/access GET, POST
-/api/trustee/{instanceId}/access/{id} GET, PUT, DELETE
-/api/trustee/{instanceId}/contracts GET, POST
-/api/trustee/{instanceId}/contracts/{id} GET, PUT, DELETE
-/api/trustee/{instanceId}/documents GET, POST
-/api/trustee/{instanceId}/documents/{id} GET, PUT, DELETE
-/api/trustee/{instanceId}/positions GET, POST
-/api/trustee/{instanceId}/positions/{id} GET, PUT, DELETE
-/api/trustee/{instanceId}/position-documents GET, POST, DELETE
-```
-
-**Validierung:** Jeder Request validiert automatisch:
-1. Existenz der FeatureInstance
-2. Zugehörigkeit zum Feature "trustee"
-3. User-Zugriff auf die Instance (via FeatureAccess)
-
-### 4.3 Feature-Verwaltungs-Routen
-
-```
-/api/features/ GET, POST (SysAdmin)
-/api/features/{code} GET
-/api/features/instances GET, POST
-/api/features/instances/{id} GET, DELETE
-/api/features/instances/{id}/sync-roles POST
-/api/features/my GET (User's Instanzen)
-/api/features/templates/roles GET, POST (SysAdmin)
-```
-
----
-
-## 5. Status & Verbesserungsbedarf
-
-### 5.1 Erledigte Verbesserungen ✅
-
-| Verbesserung | Status | Beschreibung |
-|--------------|--------|--------------|
-| **URL mit instanceId** | ✅ Erledigt | Trustee Routes haben jetzt `/{instanceId}/` Prefix |
-| **Instance-Validierung** | ✅ Erledigt | Automatische Prüfung von Existenz, Feature-Typ und User-Zugriff |
-| **Frontend API angepasst** | ✅ Erledigt | `trusteeApi.ts` nutzt neue URL-Struktur |
-
-### 5.2 Offene Punkte
-
-| Problem | Beschreibung | Priorität |
-|---------|--------------|-----------|
-| **Andere Features** | Chatbot, Workflow, RealEstate noch ohne instanceId | Mittel |
-| **Keine Feature-Registry** | Feature-Views sind hardcoded | Niedrig |
-
-### 5.3 Aktuelle URL-Struktur (Trustee)
-
-```
-# MIT instanceId im Pfad (implementiert):
-/api/trustee/{instanceId}/organisations
-/api/trustee/{instanceId}/contracts
-/api/trustee/{instanceId}/documents
-/api/trustee/{instanceId}/positions
-...
-```
-
----
-
-## 6. Empfohlene Feature-Struktur
-
-### 6.1 Neue Route-Struktur pro Feature
-
-```
-/api/{featureCode}/{instanceId}/{entity}
-```
-
-Beispiel Trustee:
-```
-/api/trustee/{instanceId}/organisations
-/api/trustee/{instanceId}/contracts
-/api/trustee/{instanceId}/documents
-/api/trustee/{instanceId}/positions
-```
-
-Beispiel Chatbot:
-```
-/api/chatbot/{instanceId}/sessions
-/api/chatbot/{instanceId}/messages
-```
-
-### 6.2 Feature-Definition in DB (poweron_app.Feature)
-
-```sql
-INSERT INTO "Feature" (code, label, icon) VALUES
-('trustee', '{"de": "Treuhand", "en": "Trustee"}', 'mdi-account-group'),
-('chatbot', '{"de": "Chatbot", "en": "Chatbot"}', 'mdi-robot'),
-('workflow', '{"de": "Workflow", "en": "Workflow"}', 'mdi-sitemap'),
-('realestate', '{"de": "Immobilien", "en": "Real Estate"}', 'mdi-home-city');
-```
-
-### 6.3 Feature-Datenbank-Zuordnung
-
-```python
-FEATURE_DATABASES = {
- "trustee": "poweron_trustee",
- "chatbot": "poweron_chat",
- "workflow": "poweron_chat", # Gleiche DB wie chatbot
- "realestate": "poweron_realestate",
-}
-```
-
----
-
-## 7. Bestehende Feature-Tabellen
-
-### 7.1 Trustee (poweron_trustee)
-
-| Tabelle | Beschreibung | Felder |
-|---------|--------------|--------|
-| `TrusteeOrganisation` | Firmen | id, label, enabled, mandateId, featureInstanceId |
-| `TrusteeRole` | Rollen | id, desc, mandateId, featureInstanceId |
-| `TrusteeAccess` | Zugriffe | id, organisationId, roleId, userId, contractId, mandateId, featureInstanceId |
-| `TrusteeContract` | Verträge | id, organisationId, label, enabled, mandateId, featureInstanceId |
-| `TrusteeDocument` | Dokumente | id, organisationId, contractId, documentName, documentData, mandateId, featureInstanceId |
-| `TrusteePosition` | Positionen | id, organisationId, contractId, valuta, bookingAmount, ..., mandateId, featureInstanceId |
-| `TrusteePositionDocument` | Verknüpfung | id, documentId, positionId, mandateId, featureInstanceId |
-
-### 7.2 Chatbot/Workflow (poweron_chat)
-
-| Tabelle | Beschreibung |
-|---------|--------------|
-| `ChatSession` | Chat-Sitzungen |
-| `ChatMessage` | Nachrichten |
-| `WorkflowExecution` | Workflow-Ausführungen |
-| `WorkflowStep` | Workflow-Schritte |
-
-### 7.3 RealEstate (poweron_realestate)
-
-| Tabelle | Beschreibung |
-|---------|--------------|
-| `RealEstateProperty` | Liegenschaften |
-| `RealEstateUnit` | Einheiten |
-| `RealEstateTenant` | Mieter |
-
----
-
-## 8. RBAC-Struktur
-
-### 8.1 System-Level RBAC (poweron_app.Role)
-
-```python
-class Role:
- id: str
- roleLabel: str # "admin", "viewer"
- featureCode: str # "trustee", None für System-Rollen
- mandateId: str # None für globale Templates
- featureInstanceId: str # None für Mandate-Level Rollen
- isSystemRole: bool # True für system-weite Rollen
-```
-
-### 8.2 Access Rules
-
-```python
-class AccessRule:
- roleId: str
- context: str # "DATA", "UI", "RESOURCE"
- item: str # "TrusteeContract", "trustee-contracts"
- view: bool
- read: str # "a" (all), "g" (group), "o" (own), "n" (none)
- create: str
- update: str
- delete: str
-```
-
-### 8.3 Feature-Level RBAC (Trustee-spezifisch)
-
-```python
-# TrusteeAccess definiert Zugriff auf Organisationen
-# Rollen: "admin", "operate", "userreport"
-
-TrusteeAccess:
- userId → User
- organisationId → TrusteeOrganisation
- roleId → TrusteeRole ("admin", "operate", "userreport")
- contractId → TrusteeContract (optional, für Vertrags-Scope)
-```
-
----
-
-## 9. Migration / Nächste Schritte
-
-### 9.1 Backend-Änderungen
-
-1. **Routes mit instanceId**
- - [x] `routeFeatureTrustee.py` erweitern: `/api/trustee/{instanceId}/...` ✅
- - [ ] Andere Features entsprechend anpassen (Chatbot, Workflow, RealEstate)
-
-2. **Feature-Registry**
- - [ ] `FEATURE_REGISTRY` in Backend implementieren
- - [ ] Views und Tabellen pro Feature definieren
-
-3. **Datenbank-Isolation**
- - [x] Trustee-Tabellen haben `featureInstanceId` ✅
- - [ ] Prüfen, dass alle anderen Feature-Tabellen `featureInstanceId` haben
-
-### 9.2 Frontend-Anpassungen (bereits implementiert)
-
-- [x] URL-Struktur: `/mandates/{mandateId}/{featureCode}/{instanceId}/...`
-- [x] `useCurrentInstance()` Hook
-- [x] `FeatureStore` mit `/api/features/my`
-- [x] Permission-Hooks für Tabellen und Views
-- [x] `trusteeApi.ts` mit instanceId im URL-Pfad ✅
-
----
-
-## 10. Zusammenfassung
-
-### Aktuelle Struktur (IST)
-
-```
-Feature → hat eigene Datenbank
-Feature → hat eigene Datenmodelle (datamodel*.py)
-Feature → hat eigene Interface-Klasse (interface*.py)
-Feature → hat eigene Routes (routeFeature*.py)
-FeatureInstance → gehört zu Mandate
-Datensätze → haben mandateId + featureInstanceId
-```
-
-### Empfohlene Struktur (SOLL)
-
-```
-1. Routes mit instanceId im Pfad
-2. Feature-Registry im Backend
-3. Konsistente RBAC-Prüfung in allen Interfaces
-4. View-Definitionen pro Feature
-5. Einheitliche Datenbank-Isolation
-```
-
-### Vorhandene Features
-
-| Feature | Datenbank | Routes | Status |
-|---------|-----------|--------|--------|
-| Trustee | poweron_trustee | `/api/trustee/` | Produktiv |
-| Chatbot | poweron_chat | `/api/chatbot/` | Produktiv |
-| Workflow | poweron_chat | `/api/automation/` | Produktiv |
-| RealEstate | poweron_realestate | `/api/realestate/` | In Entwicklung |
-
----
-
-*Erstellt: 2026-01-17*
-*Aktualisiert: 2026-01-19*
-*Analyse-Basis: poweron/gateway Backend-Code*
-
-## Änderungshistorie
-
-| Datum | Änderung |
-|-------|----------|
-| 2026-01-19 | Trustee Routes auf instanceId im URL-Pfad umgestellt |
-| 2026-01-19 | Instance-Validierung mit Zugriffsprüfung implementiert |
-| 2026-01-17 | Initiale Analyse erstellt |
diff --git a/implementation/Saas Multi Tenant Mandate/FEATURE_NAMING_CONVENTION.md b/implementation/Saas Multi Tenant Mandate/FEATURE_NAMING_CONVENTION.md
deleted file mode 100644
index bffe234..0000000
--- a/implementation/Saas Multi Tenant Mandate/FEATURE_NAMING_CONVENTION.md
+++ /dev/null
@@ -1,122 +0,0 @@
-# Feature Naming Convention - Analyse & Umsetzung
-
-## 1. Naming Convention Standard
-
-Jedes Feature folgt dieser Namenskonvention:
-
-| Komponente | Dateiname | Beispiel (Feature: Trustee) |
-|------------|-----------|----------------------------|
-| Datenmodell | `datamodelXxx.py` | `datamodelTrustee.py` |
-| Interface | `interfaceDbXxx.py` | `interfaceDbTrustee.py` |
-| Route | `routeFeatureXxx.py` | `routeFeatureTrustee.py` |
-
----
-
-## 2. Aktuelle Struktur (IST)
-
-### 2.1 Trustee Feature ✅
-
-| Komponente | Dateiname | Status |
-|------------|-----------|--------|
-| Datenmodell | `datamodelTrustee.py` | ✅ |
-| Interface | `interfaceDbTrustee.py` | ✅ |
-| Route | `routeFeatureTrustee.py` | ✅ |
-
-### 2.2 Chat-basierte Features (Chatbot, ChatDynamic, Workflow) ✅
-
-| Komponente | Dateiname | Beschreibung |
-|------------|-----------|--------------|
-| **Core-Datenmodell** | `datamodelChat.py` | Shared Model für alle Chat-Features |
-| Interface | `interfaceDbChatbot.py` | DB-Interface für Chat-Daten |
-| Route Chatbot | `routeFeatureChatbot.py` | Chatbot-Endpoints |
-| Route ChatDynamic | `routeFeatureChatDynamic.py` | Dynamic Chat-Endpoints |
-| Route Workflow | `routeFeatureWorkflow.py` | Workflow-Endpoints |
-
-### 2.3 RealEstate Feature ✅
-
-| Komponente | Dateiname | Status |
-|------------|-----------|--------|
-| Datenmodell | `datamodelRealEstate.py` | ✅ |
-| Interface | `interfaceDbRealEstate.py` | ✅ |
-| Route | `routeFeatureRealEstate.py` | ✅ |
-
-### 2.4 Workflow Feature ✅
-
-| Komponente | Dateiname | Status |
-|------------|-----------|--------|
-| Datenmodell | `datamodelWorkflow.py` | ✅ |
-| Interface | (Teil von Chatbot DB) | ✅ |
-| Route | `routeFeatureWorkflow.py` | ✅ |
-
----
-
-## 3. Zusammenfassung der Änderungen
-
-### 3.1 Umbenennungen ✅ ERLEDIGT
-
-| Von | Nach | Status |
-|-----|------|--------|
-| `interfaceDbTrusteeObjects.py` | `interfaceDbTrustee.py` | ✅ |
-| `interfaceDbChatObjects.py` | `interfaceDbChatbot.py` | ✅ |
-| `interfaceDbRealEstateObjects.py` | `interfaceDbRealEstate.py` | ✅ |
-| `routeFeatureAutomation.py` | `routeFeatureWorkflow.py` | ✅ |
-
-> **Hinweis:** `datamodelChat.py` wurde **NICHT** umbenannt, da es ein Core-Datenmodell ist,
-> das von mehreren Features verwendet wird (Chatbot, ChatDynamic, Workflow).
-
-### 3.2 Betroffene Import-Stellen
-
-Nach jeder Umbenennung müssen Imports aktualisiert werden in:
-- `app.py` (Router-Registrierung)
-- Andere Route-Dateien (Cross-Imports)
-- Interface-Dateien (Model-Imports)
-- Feature-Module (Interface-Imports)
-
----
-
-## 4. Feature-Übersicht nach Umbenennung
-
-| Feature | Datenmodell | Interface | Route | Datenbank |
-|---------|-------------|-----------|-------|-----------|
-| **Trustee** | `datamodelTrustee.py` | `interfaceDbTrustee.py` | `routeFeatureTrustee.py` | `poweron_trustee` |
-| **Chatbot** | `datamodelChat.py` (shared) | `interfaceDbChatbot.py` | `routeFeatureChatbot.py` | `poweron_chat` |
-| **ChatDynamic** | `datamodelChat.py` (shared) | `interfaceDbChatbot.py` | `routeFeatureChatDynamic.py` | `poweron_chat` |
-| **Workflow** | `datamodelChat.py` + `datamodelWorkflow.py` | `interfaceDbChatbot.py` | `routeFeatureWorkflow.py` | `poweron_chat` |
-| **RealEstate** | `datamodelRealEstate.py` | `interfaceDbRealEstate.py` | `routeFeatureRealEstate.py` | `poweron_realestate` |
-
----
-
-## 5. Nicht-Feature Dateien (bleiben unverändert)
-
-Diese Dateien sind **keine Feature-Dateien** und folgen anderen Konventionen:
-
-### Datenmodelle (System/Shared)
-- `datamodelUam.py` - User Access Management
-- `datamodelRbac.py` - Role-Based Access Control
-- `datamodelFeatures.py` - Feature/FeatureInstance Definitionen
-- `datamodelMembership.py` - FeatureAccess
-- `datamodelPagination.py` - Pagination Utilities
-- `datamodelAudit.py` - Audit Logging
-- `datamodelFiles.py` - File Storage
-- `datamodelMessaging.py` - Email/SMS
-- `datamodelInvitation.py` - User Invitations
-
-### Interfaces (System/Shared)
-- `interfaceDbAppObjects.py` - Zentrale App-Datenbank
-- `interfaceFeatures.py` - Feature-Verwaltung
-- `interfaceRbac.py` - RBAC-Operationen
-- `interfaceMessaging.py` - Messaging-Service
-- `interfaceBootstrap.py` - System-Bootstrap
-
-### Routes (System/Admin)
-- `routeDataUsers.py` - User CRUD
-- `routeDataMandates.py` - Mandate CRUD
-- `routeRbac.py` - RBAC-Verwaltung
-- `routeFeatures.py` - Feature-Verwaltung
-- `routeAdmin.py` - Admin-Funktionen
-- `routeSecurity*.py` - Auth-Endpoints
-
----
-
-*Erstellt: 2026-01-19*
-*Status: ✅ Alle Umbenennungen abgeschlossen*
diff --git a/implementation/Saas Multi Tenant Mandate/PROGRESS_TRACKING.md b/implementation/Saas Multi Tenant Mandate/PROGRESS_TRACKING.md
deleted file mode 100644
index 8b6e8df..0000000
--- a/implementation/Saas Multi Tenant Mandate/PROGRESS_TRACKING.md
+++ /dev/null
@@ -1,358 +0,0 @@
-# Multi-Tenant Gateway - Implementation Progress Tracking
-
-**Konzept:** [mandate_implementation_gateway.md](./mandate_implementation_gateway.md)
-**Letzte Aktualisierung:** 2026-01-18
-
----
-
-## Gesamtfortschritt
-
-| Phase | Status | Fortschritt |
-|-------|--------|-------------|
-| Phase 1: Foundation | ✅ Abgeschlossen | 7/7 |
-| Phase 2: RBAC Core | ✅ Abgeschlossen | 4/4 |
-| Phase 3: Auth & Context | ✅ Abgeschlossen | 6/6 |
-| Phase 4: Routes Migration | ✅ Abgeschlossen | 11/11 |
-| Phase 5: Interfaces Migration | ✅ Abgeschlossen | 5/5 |
-| Phase 6: Features Migration | ✅ Abgeschlossen | 7/7 |
-| Phase 7: Cleanup | ✅ Abgeschlossen | 3/3 |
-| Phase 8: Neue Features | ✅ Abgeschlossen | 5/5 |
-
-**Alle Phasen abgeschlossen!**
-
----
-
-## Phase 1: Foundation (Datenmodelle & DB) ✅
-
-**Ziel:** Neue Datenstrukturen ohne Breaking Changes am bestehenden Code.
-
-| Schritt | Datei | Aktion | Status |
-|---------|-------|--------|--------|
-| 1.1 | `datamodelFeatures.py` | NEU: `Feature`, `FeatureInstance` | ✅ |
-| 1.2 | `datamodelMembership.py` | NEU: `UserMandate`, `FeatureAccess`, `UserMandateRole`, `FeatureAccessRole` | ✅ |
-| 1.3 | `datamodelInvitation.py` | NEU: `Invitation` | ✅ |
-| 1.4 | `datamodelRbac.py` | ADD: `Role.mandateId`, `Role.featureInstanceId`, `Role.featureCode`, `AccessRule.roleId` | ✅ |
-| 1.5 | `datamodelUam.py` | ADD: `User.isSysAdmin`, Mandate ohne `language` | ✅ |
-| 1.6 | `datamodelSecurity.py` | Token ohne `mandateId` | ✅ |
-| 1.7 | `interfaceBootstrap.py` | roleId-basiert, erstellt UserMandate + UserMandateRole | ✅ |
-
-**Notizen:**
-- Bootstrap erstellt jetzt Root-Mandate, System-Rollen (sysadmin, admin, user) und verknüpft Initial-User via Junction Tables
-- `isSysAdmin` Feld hat Validator für None → False Konvertierung
-- App startet erfolgreich mit neuer Struktur
-
----
-
-## Phase 2: RBAC Core (Kern-Logik) ✅
-
-**Ziel:** Neues RBAC-System parallel zum alten lauffähig.
-
-| Schritt | Datei | Aktion | Status |
-|---------|-------|--------|--------|
-| 2.1 | `security/rbac.py` | Neue `getRulesForUserBulk()` mit Junction Tables | ✅ |
-| 2.2 | `interfaceRbac.py` | `buildRbacWhereClause()` mit explizitem `mandateId` | ✅ |
-| 2.3 | `interfaceDbAppObjects.py` | Neue Membership-Methoden (parallel zu alten) | ✅ |
-| 2.4 | `interfaceFeatures.py` | NEU: Feature-Instanz-Management | ✅ |
-
-**Notizen:**
-- `getRulesForUserBulk()` implementiert mit optimierten SQL JOINs (3 Queries statt N+1)
-- Membership-Methoden hinzugefügt: `getUserMandate`, `createUserMandate`, `deleteUserMandate`, `getRoleIdsForUserMandate`, etc.
-- Feature-Methoden hinzugefügt: `getFeatureAccess`, `createFeatureAccess`, `getRoleIdsForFeatureAccess`
-- `interfaceFeatures.py` erstellt mit Template-Kopierung und Synchronisation
-
----
-
-## Phase 3: Auth & Context (Authentifizierung) ✅
-
-**Ziel:** Request-Context-System einführen.
-
-| Schritt | Datei | Aktion | Status |
-|---------|-------|--------|--------|
-| 3.1 | `auth/authentication.py` | `RequestContext` + `getRequestContext()` + `requireSysAdmin()` | ✅ |
-| 3.2 | `routeSecurityLocal.py` | Login mit neuem Token (ohne `mandateId`) | ✅ |
-| 3.3 | `routeSecurityMsft.py` | OAuth anpassen (Token ohne `mandateId`) | ✅ |
-| 3.4 | `routeSecurityGoogle.py` | OAuth anpassen (Token ohne `mandateId`) | ✅ |
-| 3.5 | `datamodelSecurity.py` | Token ohne `mandateId` | ✅ (Phase 1) |
-| 3.6 | `auth/tokenRefreshService.py` | Bereits korrekt (OAuth-Token, nicht JWT) | ✅ |
-
-**Notizen:**
-- `RequestContext` Klasse implementiert: User + mandateId + featureInstanceId + roleIds
-- `getRequestContext()` FastAPI Dependency: Liest `X-Mandate-Id` und `X-Instance-Id` Header
-- `requireSysAdmin()` FastAPI Dependency: Prüft `isSysAdmin` Flag mit Audit-Logging
-- JWT-Token enthalten KEIN `mandateId` mehr - Mandant-Kontext kommt per Request-Header
-- Token-Validierung in `_getUserBase()` prüft nur noch `userId`, nicht mehr `mandateId`
-- Audit-Logging für System-Funktionen (Login/Logout) verwendet `mandateId="system"` (kein User-Kontext)
-
----
-
-## Phase 4: Routes Migration ✅
-
-**Ziel:** Alle Routes auf neues Context-System migrieren.
-
-### 4.A - Admin Routes ✅
-
-| Schritt | Datei | Status |
-|---------|-------|--------|
-| 4.A.1 | `routeSecurityAdmin.py` | ✅ |
-| 4.A.2 | `routeAdminRbacRoles.py` | ✅ |
-| 4.A.3 | `routeDataUsers.py` | ✅ |
-| 4.A.4 | `routeDataMandates.py` | ✅ |
-| 4.A.5 | `routeRbac.py` | ✅ |
-
-**Notizen Phase 4.A:**
-- Alle Admin-Routes verwenden jetzt `requireSysAdmin()` Dependency
-- `roleLabels`-basierte Prüfungen durch `isSysAdmin` ersetzt
-- `currentUser.mandateId` durch `RequestContext` ersetzt
-- User-Filterung via `UserMandate` Junction Table
-- Audit-Logging verwendet `context.mandateId` oder "system"
-
-### 4.B - Feature Routes ✅
-
-| Schritt | Datei | Status |
-|---------|-------|--------|
-| 4.B.1 | `routeFeatureTrustee.py` (← routeDataTrustee.py) | ✅ |
-| 4.B.2 | `routeFeatureChatbot.py` (← routeChatbot.py) | ✅ |
-| 4.B.3 | `routeFeatureRealEstate.py` (← routeRealEstate.py) | ✅ |
-| 4.B.4 | `routeFeatureNeutralization.py` (← routeDataNeutralization.py) | ✅ |
-| 4.B.5 | `routeFeatureAutomation.py` (← routeAdminAutomationEvents.py) | ✅ |
-| 4.B.6 | `routeFeatureChatDynamic.py` (← routeChatPlayground.py) | ✅ |
-
-**Notizen Phase 4.B:**
-- Alle Feature-Routes umbenannt mit `routeFeature...` Prefix
-- `getCurrentUser` durch `getRequestContext` ersetzt
-- `currentUser.mandateId` durch `context.mandateId` ersetzt
-- `currentUser.roleLabels` durch `context.roleIds` ersetzt
-- `requireSysAdmin()` für Sysadmin-Endpoints (z.B. Automation Events)
-- Alte Route-Dateien gelöscht, Imports in `app.py` aktualisiert
-
----
-
-## Phase 5: Interfaces Migration ✅
-
-**Ziel:** Alle Interfaces auf Context-System migrieren.
-
-| Schritt | Datei | Status |
-|---------|-------|--------|
-| 5.1 | `interfaceDbTrusteeObjects.py` | ✅ |
-| 5.2 | `interfaceDbChatObjects.py` | ✅ |
-| 5.3 | `interfaceDbRealEstateObjects.py` | ✅ |
-| 5.4 | `interfaceDbComponentObjects.py` | ✅ |
-| 5.5 | `interfaceVoiceObjects.py` | ✅ |
-
-**Notizen Phase 5:**
-- `getInterface(currentUser)` → `getInterface(currentUser, mandateId=...)`
-- `setUserContext(currentUser)` → `setUserContext(currentUser, mandateId=...)`
-- `self.mandateId = currentUser.mandateId` → `self.mandateId = mandateId` (aus Parameter)
-- SysAdmins können ohne `mandateId` arbeiten (cross-mandate Operationen)
-- Singleton-Cache-Keys verwenden jetzt `userId_mandateId` statt `userId_user.mandateId`
-- Feature-Routes aktualisiert: `getInterface(context.user, mandateId=context.mandateId)`
-
----
-
-## Phase 6: Features Migration ✅
-
-**Ziel:** Feature-Module auf Context-System migrieren.
-
-| Schritt | Datei | Status |
-|---------|-------|--------|
-| 6.1 | `features/chatbot/mainChatbot.py` | ✅ |
-| 6.2 | `features/realEstate/mainRealEstate.py` | ✅ |
-| 6.3 | `features/dynamicOptions/mainDynamicOptions.py` | ✅ |
-| 6.4 | `features/neutralizePlayground/mainNeutralizePlayground.py` | ✅ |
-| 6.5 | `workflows/workflowManager.py` | ✅ |
-| 6.6 | `workflows/methods/methodBase.py` | ✅ (keine Änderung nötig) |
-| 6.7 | `services/serviceNeutralization/mainServiceNeutralization.py` | ✅ (verwendet interfaceDbApp.mandateId) |
-
-**Notizen Phase 6:**
-- `Services` Klasse aktualisiert: `mandateId` als expliziter Parameter
-- `getInterface(user, workflow, mandateId)` für alle Services
-- Feature-Funktionen aktualisiert: `mandateId` als Parameter statt `currentUser.mandateId`
-- Route-Aufrufe aktualisiert: `str(context.mandateId)` wird übergeben
-- `workflowManager.py`: Verwendet `self.services.mandateId` für neue Workflows
-- `mainDynamicOptions.py`: Verwendet `services.mandateId` für Benutzer-Lookup
-
----
-
-## Phase 7: Cleanup & Breaking Changes ✅
-
-**Ziel:** Alte Felder entfernen (erst wenn alles migriert ist!)
-
-| Schritt | Datei | Aktion | Status |
-|---------|-------|--------|--------|
-| 7.1 | `datamodelUam.py` | ENTFERNE `User.mandateId`, `User.roleLabels` | ✅ |
-| 7.2 | `interfaceDbAppObjects.py` | Alte Methoden entfernen | ✅ |
-| 7.3 | `interfaceBootstrap.py` | Alte roleLabels-Logik entfernen | ✅ |
-
-**Änderungen Phase 7:**
-- `datamodelUam.py`: `User.mandateId` und `User.roleLabels` Felder entfernt
-- `interfaceDbAppObjects.py`:
- - `createUser()`: `roleLabels` Parameter entfernt, nur noch `isSysAdmin`
- - `updateUser()`: `mandateId` Handling entfernt
- - `deleteRole()`: Prüft jetzt `UserMandateRole` statt `user.roleLabels`
- - `getAccessRules()`: Neuer `roleId` Parameter hinzugefügt
- - `countRoleAssignments()`: Neue Methode für Role-Zählung via `UserMandateRole`
-- `interfaceBootstrap.py`: `mandateId` und `roleLabels` aus Admin/Event User Erstellung entfernt
-- `security/rbac.py`: `user.roleLabels` Fallback entfernt
-- `routeDataUsers.py`: Verwendet `createUserMandate()` für Role-Assignment
-- `routeSecurityLocal.py`: `roleLabels` aus User-Registrierung entfernt
-- `routeRbac.py`: Verwendet `context.roleIds` statt `user.roleLabels`
-- `routeAdminRbacRoles.py`: Komplett auf `UserMandateRole` umgestellt mit Hilfsfunktionen
-
----
-
-## Phase 8: Neue Features ✅
-
-**Ziel:** Neue Funktionalität hinzufügen.
-
-| Schritt | Datei | Status |
-|---------|-------|--------|
-| 8.1 | `routeFeatures.py` (NEU) | ✅ |
-| 8.2 | `routeInvitations.py` (NEU) | ✅ |
-| 8.3 | `routeRbacExport.py` (NEU) | ✅ |
-| 8.4 | `routeGdpr.py` (NEU) | ✅ |
-| 8.5 | `app.py` (Routes registriert) | ✅ |
-
-**Notizen Phase 8:**
-- `routeFeatures.py`: Feature/FeatureInstance CRUD, Template-Rollen-Sync, `/api/features/my` Endpoint
-- `routeInvitations.py`: Token-basierte Einladungen, öffentliche Validierung, Accept-Flow
-- `routeRbacExport.py`: Global und Mandate-scoped Export/Import von RBAC-Regeln
-- `routeGdpr.py`: DSGVO Art. 15 (Datenexport), Art. 17 (Löschrecht), Art. 20 (Datenportabilität)
-- Alle neuen Routes in `app.py` registriert
-
----
-
-## Zusätzliche Änderungen (Nicht in Phasen)
-
-| Datei | Änderung | Status |
-|-------|----------|--------|
-| `connectorDbPostgre.py` | Entfernt Warning bei leerem userId (Bootstrap) | ✅ |
-| `routeSecurityAdmin.py` | DB-Funktionen generisch gemacht (dynamische DB-Discovery) | ✅ |
-| `env_*.env` | Konsolidierte DB-Konfiguration (DB_HOST, DB_USER, etc.) | ✅ |
-| `interfaceDb*Objects.py` | Hardcoded DB-Namen (poweron_app, poweron_chat, etc.) | ✅ |
-| `rootAccess.py` | Bootstrap-Aufruf wenn kein Initial-User | ✅ |
-
----
-
-## Bekannte Probleme / TODOs
-
-- [x] DB-Indizes für Junction Tables erstellen (Performance) → `sql/001_multi_tenant_indexes_triggers_fk.sql`
-- [x] IMMUTABLE Triggers für Role/AccessRule auf DB-Ebene → `sql/001_multi_tenant_indexes_triggers_fk.sql`
-- [x] Foreign Key Constraints für CASCADE DELETE → `sql/001_multi_tenant_indexes_triggers_fk.sql`
-- [x] Add/Remove User from Mandate Endpoints → `routeDataMandates.py`
-- [x] Combined Register + Accept Invitation Endpoint → `routeInvitations.py`
-
----
-
-## Changelog
-
-### 2026-01-17 (Phase 8 - Erweiterungen)
-- **Fehlende Endpoints nachgeliefert:**
- - `routeDataMandates.py`: User-Management innerhalb Mandaten
- - `GET /api/mandates/{mandateId}/users` - Benutzer im Mandant auflisten
- - `POST /api/mandates/{mandateId}/users` - Benutzer zu Mandant hinzufügen
- - `DELETE /api/mandates/{mandateId}/users/{targetUserId}` - Benutzer aus Mandant entfernen
- - `PUT /api/mandates/{mandateId}/users/{targetUserId}/roles` - Benutzer-Rollen aktualisieren
- - SysAdmin Self-Eskalation Prevention: SysAdmin kann sich nicht selbst hinzufügen
- - Orphan Prevention: Letzter Admin kann nicht entfernt werden
- - `routeInvitations.py`: Combined Register + Accept
- - `POST /api/invitations/register-and-accept` - Registrierung + Einladung in einem Schritt (öffentlich)
-- **DB Migration Script erstellt:**
- - `sql/001_multi_tenant_indexes_triggers_fk.sql`
- - Indexes für alle Junction Tables (UserMandate, UserMandateRole, FeatureAccess, etc.)
- - IMMUTABLE Triggers für Role und AccessRule (mandateId/featureInstanceId/roleId)
- - Foreign Key Constraints mit CASCADE DELETE
-
-### 2026-01-17 (Phase 8)
-- **Phase 8 abgeschlossen:**
- - `routeFeatures.py` NEU: Feature-Definitionen (SysAdmin), FeatureInstance CRUD (Mandate-Admin)
- - `GET /api/features/` - Liste aller Features
- - `GET /api/features/{featureCode}` - Feature-Details
- - `POST /api/features/` - Feature erstellen (SysAdmin)
- - `GET /api/features/instances` - Feature-Instanzen im Mandant
- - `POST /api/features/instances` - Feature-Instanz erstellen
- - `DELETE /api/features/instances/{id}` - Feature-Instanz löschen
- - `POST /api/features/instances/{id}/sync-roles` - Rollen synchronisieren
- - `GET /api/features/my` - Eigene Feature-Instanzen (kein Mandant-Kontext nötig)
- - `GET /api/features/templates/roles` - Template-Rollen (SysAdmin)
- - `POST /api/features/templates/roles` - Template-Rolle erstellen (SysAdmin)
- - `routeInvitations.py` NEU: Token-basierte Einladungen für Self-Service Onboarding
- - `POST /api/invitations/` - Einladung erstellen (Mandate-Admin)
- - `GET /api/invitations/` - Einladungen auflisten
- - `DELETE /api/invitations/{id}` - Einladung widerrufen
- - `GET /api/invitations/validate/{token}` - Einladung validieren (öffentlich)
- - `POST /api/invitations/accept/{token}` - Einladung annehmen (authentifiziert)
- - `routeRbacExport.py` NEU: RBAC Export/Import
- - `GET /api/rbac/export/global` - Globale Templates exportieren (SysAdmin)
- - `POST /api/rbac/import/global` - Globale Templates importieren (SysAdmin)
- - `GET /api/rbac/export/mandate` - Mandant-RBAC exportieren (Mandate-Admin)
- - `POST /api/rbac/import/mandate` - Mandant-RBAC importieren (Mandate-Admin)
- - `routeGdpr.py` NEU: DSGVO-Compliance Endpoints
- - `GET /api/user/me/data-export` - Datenexport (Art. 15)
- - `GET /api/user/me/data-portability` - Datenportabilität JSON-LD (Art. 20)
- - `DELETE /api/user/me` - Account löschen (Art. 17)
- - `GET /api/user/me/consent-info` - Datenschutz-Informationen
- - `app.py`: Alle neuen Routes registriert
-
-### 2026-01-18
-- **Phase 6 abgeschlossen:**
- - `services/__init__.py`: `Services` Klasse akzeptiert `mandateId` Parameter
- - `getInterface(user, workflow, mandateId)` übergibt `mandateId` an alle Interface-Aufrufe
- - `mainChatbot.py`: `chatProcess(user, mandateId, ...)` - `mandateId` für Workflow-Erstellung
- - `mainRealEstate.py`: `processNaturalLanguageCommand(user, mandateId, ...)` + alle CREATE-Operationen
- - `mainDynamicOptions.py`: `services.mandateId` statt `currentUser.mandateId`
- - `mainNeutralizePlayground.py`: `NeutralizationPlayground(user, mandateId)` Konstruktor
- - `workflowManager.py`: `self.services.mandateId` für neue Workflows
- - Route-Aufrufe aktualisiert: `str(context.mandateId)` wird übergeben
- - `methodBase.py`: Keine Änderung nötig (verwendet Services)
- - `mainServiceNeutralization.py`: Keine Änderung nötig (verwendet `interfaceDbApp.mandateId`)
-- **Phase 5 abgeschlossen:**
- - `interfaceDbTrusteeObjects.py`: `getInterface(user, mandateId)` + `setUserContext(user, mandateId)`
- - `interfaceDbChatObjects.py`: `getInterface(user, mandateId)` + `setUserContext(user, mandateId)`
- - `interfaceDbRealEstateObjects.py`: `getInterface(user, mandateId)` + `setUserContext(user, mandateId)`
- - `interfaceDbComponentObjects.py`: `getInterface(user, mandateId)` + `setUserContext(user, mandateId)`
- - `interfaceVoiceObjects.py`: `getVoiceInterface(user, mandateId)` + `setUserContext(user, mandateId)`
- - Feature-Routes aktualisiert: `getInterface(context.user, mandateId=context.mandateId)`
-- **Phase 4.B abgeschlossen:**
- - `routeFeatureTrustee.py`: Alle Endpoints auf `getRequestContext()` umgestellt
- - `routeFeatureChatbot.py`: Streaming + RBAC mit `context.user`
- - `routeFeatureRealEstate.py`: `context.mandateId` für Projekt-/Parzellen-Filterung
- - `routeFeatureNeutralization.py`: Config + Processing mit `context.user`
- - `routeFeatureAutomation.py`: `requireSysAdmin()` für alle Endpoints
- - `routeFeatureChatDynamic.py`: Workflow-Start/Stop mit `context.user`
- - Alte Route-Dateien gelöscht (6 Dateien)
- - `app.py` Imports aktualisiert
-- **Phase 5 - GREENFIELD Cleanup:**
- - ALLE Fallbacks auf `currentUser.mandateId` entfernt (GREENFIELD = keine Backwards Compatibility)
- - `interfaceDbAppObjects.py`: `self.mandateId` kommt nur aus Parameter, nicht aus User
- - `interfaceDbTrusteeObjects.py`: Fallback-Logik entfernt
- - `interfaceDbChatObjects.py`: `self.mandateId` statt `self.currentUser.mandateId`
- - `interfaceDbRealEstateObjects.py`: Fallback-Logik entfernt
- - `interfaceDbComponentObjects.py`: `self.mandateId` für alle Record-Erstellungen
- - `interfaceVoiceObjects.py`: Fallback-Logik entfernt
- - `interfaceRbac.py`: Keine Fallbacks mehr, `mandateId` ist explizit erforderlich
- - Modul-Header aktualisiert (keine "Backwards Compatibility" Referenzen mehr)
-
-### 2026-01-17
-- **Phase 3 abgeschlossen:**
- - `RequestContext` Klasse in `auth/authentication.py` implementiert
- - `getRequestContext()` FastAPI Dependency mit `X-Mandate-Id` und `X-Instance-Id` Header-Handling
- - `requireSysAdmin()` FastAPI Dependency für System-Level-Operationen
- - JWT-Token enthalten kein `mandateId` mehr (Local, Microsoft, Google)
- - Token-Validierung prüft nur noch `userId`
- - `auth/__init__.py` exportiert neue Funktionen
-- **Phase 4.A abgeschlossen:**
- - `routeSecurityAdmin.py`: Alle Endpoints auf `requireSysAdmin()` umgestellt
- - `routeAdminRbacRoles.py`: `requireSysAdmin()` + `getRootInterface()`
- - `routeDataUsers.py`: `getRequestContext()` für Mandate-Scope, UserMandate-Filterung
- - `routeDataMandates.py`: `requireSysAdmin()` (Mandates sind System-Ressourcen)
- - `routeRbac.py`: Permissions mit `getRequestContext()`, Rules/Roles mit `requireSysAdmin()`
-
-### 2026-01-16
-- Phase 1 abgeschlossen
-- Startup-Fehler behoben (isSysAdmin Validator, Bootstrap-Aufruf)
-- DB-Konfiguration konsolidiert
-- DB-Admin-Funktionen generisch gemacht
-- **Phase 2 abgeschlossen:**
- - `getRulesForUserBulk()` in `security/rbac.py` implementiert (optimierte Bulk-Queries)
- - Membership-Methoden in `interfaceDbAppObjects.py` hinzugefügt
- - `interfaceFeatures.py` NEU erstellt (Feature-Instanz-Management mit Template-Kopierung)
\ No newline at end of file
diff --git a/implementation/rbac_access_concept_done.md b/implementation/rbac_access_concept_done.md
new file mode 100644
index 0000000..a350218
--- /dev/null
+++ b/implementation/rbac_access_concept_done.md
@@ -0,0 +1,579 @@
+# RBAC Zugriffskonzept (Katalog + Seiten + Endpoints)
+
+## Kontext aus dem Codebestand (aktueller Stand)
+
+- RBAC-Regeln und Rollen existieren bereits mit immutable Kontextfeldern und AccessRule-Unterstuetzung fuer DATA/UI/RESOURCE. Siehe `AccessRuleContext`, `Role`, `AccessRule` in:
+```
+21:116:gateway/modules/datamodels/datamodelRbac.py
+class AccessRuleContext(str, Enum):
+ DATA = "DATA"
+ UI = "UI"
+ RESOURCE = "RESOURCE"
+...
+class AccessRule(BaseModel):
+ roleId: str
+ context: AccessRuleContext
+ item: Optional[str]
+ view: bool
+ read: Optional[AccessLevel]
+ create: Optional[AccessLevel]
+ update: Optional[AccessLevel]
+ delete: Optional[AccessLevel]
+```
+- RBAC-Endpunkte fuer Permissions und Access Rules existieren bereits (Access Rules sind SysAdmin-only):
+```
+35:214:gateway/modules/routes/routeRbac.py
+@router.get("/permissions")
+@router.get("/permissions/all")
+@router.get("/rules")
+```
+- Mandantenzuordnung von Benutzern/Rollen laeuft ueber `/api/mandates/{mandateId}/users` und die Junction-Tabellen `UserMandateRole` (Mandanten-Kontext) und `FeatureAccessRole` (Feature-Instanz-Kontext):
+```
+15:149:gateway/modules/datamodels/datamodelMembership.py
+class UserMandateRole(BaseModel):
+ userMandateId: str
+ roleId: str
+...
+class FeatureAccessRole(BaseModel):
+ featureAccessId: str
+ roleId: str
+```
+- Im Frontend existieren Admin-Seiten fuer Benutzer-Mandant-Mitgliedschaften und Mandanten-Rollen:
+```
+1:120:frontend_nyla/src/pages/admin/AdminUserMandatesPage.tsx
+1:185:frontend_nyla/src/pages/admin/AdminMandateRolesPage.tsx
+```
+
+Damit ist klar:
+- Zugriffregeln existieren bereits (view + CRUD mit none/my/group/all).
+- Fehlend ist ein **Katalog + Editor-UI** fuer Objektregeln (DATA/UI/RESOURCE).
+
+## Entscheidungen / Antworten zu Inputs
+
+1) **Shared Katalog-Location (Gateway):**
+ - Es gibt aktuell keinen gemeinsamen RBAC-Objektkatalog in datamodels. Datamodels definieren nur Schema.
+ - Ziel-Location: `gateway/modules/security/rbacCatalog/` (Service-Layer), nicht `datamodels`.
+ - DATA-Objekte koennen on-the-fly aus Modellen/Attributen abgeleitet werden, ohne Persistenz.
+ - UI- und RESOURCE-Objekte brauchen explizite Registry-Eintraege, persistent in einer Katalog-Tabelle, dann ueber Gateway-Endpunkte abrufbar.
+ - Feature-Initialisierung im Gateway registriert die UI/RESOURCE-Keys. Die Admin-UI zeigt alle persistierten Katalogobjekte (keine Filterung nach Registrierungsstatus).
+ - Persistenz ist Pflicht, um Regeln nicht zu verlieren, wenn Features entfernt oder deaktiviert werden.
+
+2) **Admin-Seite fuer Mandantenverwaltung: gleich wie Rollen-Zuordnung?**
+ - Mandanten-CRUD getrennt von Rollen-Zuordnung.
+ - Heute: Mandanten-CRUD ist SysAdmin-only (`/api/mandates`), Rollen-Zuordnung ist Mandanten-Admin (`/api/mandates/{mandateId}/users`).
+ - Ziel: separate **AdminMandatesPage** (SysAdmin), **AdminUserMandatesPage** fuer Rollen-Zuordnung.
+ - Zusaetzlich: **AdminRbacRulesPage** (Feature-Instanz-Admin) fuer Objektregeln.
+
+3) **Registry-Eigentum und Quellen:**
+ - Feature-Initialisierung im Gateway definiert alle UI/RESOURCE-Objekte der Features.
+ - Frontend registriert keine Feature-UI-Objekte.
+ - System-UI-Objekte werden direkt im Backend definiert (keine UI-Abhaengigkeit).
+
+4) **UI-Permissions:**
+ - UI-Kontext nutzt nur `view`.
+ - Kein create/update/delete fuer UI-Kontext.
+
+5) **Katalog-Scope:**
+ - Der Katalog enthaelt alle Objekte (global + mandate + feature instance).
+
+6) **Bootstrap-Scope (interfaceBootstrap.py):**
+ - Bootstrap laeuft nur, wenn die Datenbank leer ist.
+ - Bootstrap erzeugt nur System-RBAC (Root-Mandant, Admin/Event-User, globale Rollen, Basisregeln).
+ - Bootstrap definiert keine Feature-Rollen oder Feature-Zugriffsregeln.
+ - System-UI-Objekte sind im Backend definiert und koennen im Bootstrap registriert werden.
+
+## Zielarchitektur
+
+### A) RBAC Objektkatalog (shared im Gateway)
+
+**Ziel:** Ein einziger Objektbaum fuer DATA / UI / RESOURCE, mit Mandant + Feature-Instanz-Kontext.
+
+**Quelle je Objekttyp:**
+- **DATA**: abgeleitet aus Model-Metadaten (Tabellen + Felder).
+- **UI**: Registry aus Feature-Initialisierung plus backend-definierte System-UI-Objekte.
+- **RESOURCE**: Registry aus Feature-Initialisierung.
+
+**Persistenz:**
+- Kleine Katalog-Tabelle `RbacObject` (oder aehnlich) fuer UI/RESOURCE.
+- DATA-Objekte nicht speichern; on-demand generieren.
+- Nicht registrierte Objekte bleiben im Katalog und bleiben selektierbar; keine Filterung nach Registrierung.
+
+**Model (gateway/modules/datamodels/datamodelRbacCatalog.py):**
+- `id`
+- `objectKey` (unique, z.B. `ui.feature.trustee.contracts.tab.documents`)
+- `context` (DATA | UI | RESOURCE)
+- `featureCode` (z.B. `trustee`)
+- `featureInstanceId` (nullable)
+- `mandateId` (nullable)
+- `label` (multilingual, optional)
+- `meta` (JSON, optional, z.B. Endpoint-Info oder UI-Hints)
+
+**Registry-Logik (gateway/modules/security/rbacCatalog/catalogService.py):**
+- `getDataCatalog(mandateId, featureInstanceId)` -> aus Modellen ableiten:
+ - `data.table.`
+ - `data.table..`
+- `getUiCatalog(mandateId, featureInstanceId, featureCode)` -> aus `RbacObject` (UI-Kontext)
+- `getResourceCatalog(mandateId, featureInstanceId, featureCode)` -> aus `RbacObject` (RESOURCE-Kontext)
+- `getCatalog(...)` -> zusammenfuehren; alle Objekte (global + mandate + feature instance)
+
+**ObjectKey-Konvention:**
+- DATA:
+ - `data.table.`
+ - `data.table..`
+- UI:
+ - `ui.feature...`
+ - Beispiel: `ui.feature.trustee.contracts.tab.documents`
+- RESOURCE:
+ - `resource.feature..`
+ - Beispiel: `resource.feature.trustee.contracts.create`
+
+### B) RBAC Rules Editor (neue Admin-Seite)
+
+**Seitenname:** `AdminRbacRulesPage`
+**Zielgruppe:** Feature-Instanz-Admin
+**Route:** `/admin/feature-instances/:featureInstanceId/rbac`
+**Navigation:** Feature-Instanz-Seiten “Rollen” + “Zugriffe” ersetzen durch:
+- “Feature-Benutzer” (bestehende User/Rollen-Zuordnung)
+- “Zugriffe (RBAC)” (neue Seite fuer Objektregeln)
+
+**Layout:**
+- Links: Objektbaum (DATA / UI / RESOURCE)
+- Oben: Rollen-Auswahl (Feature-Instanz-Rollen)
+- Rechts: Regel-Grid (view/read/create/update/delete mit Scope)
+ - UI: nur `view`
+ - RESOURCE: view + CRUD mit none/my/group/all
+ - DATA: CRUD mit none/my/group/all
+
+**Verhalten:**
+- Auswahl eines Objekts zeigt Regeln je Rolle.
+- Aenderungen ueber create/update/delete von AccessRule.
+- Nur Rollen der Feature-Instanz sind auswaehlbar.
+
+### C) Backend-Endpunkte (Vorschlag)
+
+#### Katalog-Endpunkte
+```
+GET /api/rbac/catalog?featureInstanceId=...&featureCode=...&include=data,ui,resource
+```
+Response:
+```
+{
+ "data": [{ "objectKey": "data.table.TrusteeContract", "label": "...", "children": [...] }],
+ "ui": [{ "objectKey": "ui.feature.trustee.contracts", "label": "...", "children": [...] }],
+ "resource": [{ "objectKey": "resource.feature.trustee.contracts.create", "label": "..." }]
+}
+```
+
+```
+POST /api/rbac/catalog/ui
+POST /api/rbac/catalog/resource
+```
+Payload:
+```
+{
+ "featureCode": "trustee",
+ "featureInstanceId": "optional",
+ "mandateId": "optional",
+ "objects": [
+ { "objectKey": "ui.feature.trustee.contracts", "label": { "en": "...", "de": "..." }, "meta": {} }
+ ]
+}
+```
+Notes:
+- Endpunkte registrieren/aktualisieren UI/RESOURCE-Katalogeintraege.
+- DATA-Objekte werden nie gepostet.
+- Admin-UI darf alle persistenten Objekte selektieren.
+
+#### AccessRule-Endpunkte (bestehend, aber erweitert)
+```
+GET /api/rbac/rules?roleId=...&context=UI&item=ui.feature.trustee.contracts
+POST /api/rbac/rules
+PUT /api/rbac/rules/{ruleId}
+DELETE /api/rbac/rules/{ruleId}
+```
+Policy:
+- Nur SysAdmin darf Regeln verwalten.
+
+#### Optionale Options-Endpunkte fuer Admin-UI
+```
+GET /api/options/mandate.roles?mandateId=...
+GET /api/options/featureInstance.roles?featureInstanceId=...
+GET /api/options/featureInstances?mandateId=...
+```
+
+### D) Enforcement
+- **DATA:** ueber RBAC in der Daten-Schicht.
+- **UI:** Frontend nutzt `getAllPermissions` und blendet aus via `view`.
+- **RESOURCE:** Gateway prueft am Endpoint-Entry.
+
+## Implementierungsschritte (high level)
+
+1) Katalog-Model + Service im Gateway.
+2) Katalog-Endpunkte in `routeRbacCatalog.py`.
+3) Registry-Producer:
+ - Feature-Initialisierung registriert UI/RESOURCE.
+ - System-UI-Objekte werden im Backend registriert.
+4) Neue Admin-Seite `AdminRbacRulesPage`.
+5) Feature-Instanz-Navigation anpassen.
+
+## Bootstrap-Abgleich (aktuell vs Ziel)
+
+**Aktuell (interfaceBootstrap.py):**
+- Root-Mandant, Admin-User, Event-User.
+- Globale Template-Rollen: `admin`, `user`, `viewer`.
+- AccessRules (nur wenn keine existieren):
+ - Default DATA rules (item=None).
+ - Table-spezifische DATA rules (Mandate, UserInDB, Standard-Tabellen, AuthEvent).
+ - UI rules (context=UI, item=None, view=True).
+ - RESOURCE rules (context=RESOURCE, item=None, view=True).
+- Feature-Initialisierung und Feature-Template-Rollen.
+- AccessRules fuer Feature-Template-Rollen.
+
+**Ziel:**
+- Bootstrap nur System-RBAC, nur bei leerer DB.
+- Feature-Definitionen/Template-Rollen/Feature-Regeln entfernen.
+- Feature-Initialisierung verwaltet Katalog + Feature-Regeln.
+
+### Konkrete Aenderungen in `interfaceBootstrap.py`
+
+**Aus `initBootstrap()` entfernen:**
+- `initFeatures(db)`
+- `_initFeatureTemplateRoleAccessRules(db)`
+
+**Feature-Template-Rollen entfernen:**
+- `_initFeatureTemplateRoles(db)` und alle Aufrufe
+
+**Feature-Regeln entfernen:**
+- `_initFeatureTemplateRoleAccessRules(db)` und alle Aufrufe
+
+**System-RBAC behalten:**
+- `initRoles()` fuer globale Rollen `admin`, `user`, `viewer`
+- `initRbacRules()` fuer:
+ - Default DATA rules
+ - Table-spezifische DATA rules
+ - UI rules (view)
+ - RESOURCE rules (view)
+
+**Bootstrap-Guard:**
+- Nur bei leerer DB.
+- System-UI-Objekte im Backend registrieren (Bootstrap oder Startup).
+
+## Offene Punkte
+
+- Alle Regeln bleiben persistent, bis sie manuell geloescht werden.
+
+## Feature-Containerisierung
+
+### Ziel
+Jedes Feature in einem eigenen Ordner, damit Features durch Ordner-Praesenz aktiv sind. Jeder Container enthaelt:
+- `datamodelFeatureXxx.py`
+- `interfaceFeatureXxx.py`
+- `routeFeatureXxx.py`
+- main module fuer RBAC-Objekte
+- optionale Helpers
+
+### Aktuelle Feature-Dateien
+
+**Routes (gateway/modules/routes):**
+- `routeFeatureTrustee.py`
+- `routeFeatureChatbot.py`
+- `routeFeatureChatDynamic.py` (chatworkflow)
+- `routeFeatureNeutralization.py`
+- `routeFeatureRealEstate.py`
+- `routeFeatureWorkflow.py` (automation events)
+- `routeFeatures.py` (Feature/Instance-Management, kein Feature)
+
+**Interfaces (gateway/modules/interfaces):**
+- `interfaceDbTrustee.py`
+- `interfaceDbChatbot.py` (shared mit workflow)
+- `interfaceDbRealEstate.py`
+- `interfaceFeatures.py` (Feature/Instance-Management, kein Feature)
+
+**Datamodels (gateway/modules/datamodels):**
+- `datamodelTrustee.py`
+- `datamodelChat.py`
+- `datamodelWorkflow.py`
+- `datamodelRealEstate.py`
+- `datamodelNeutralizer.py`
+- `datamodelFeatures.py` (Feature/Instance-Management, kein Feature)
+
+**Feature-Logik (gateway/modules/features):**
+- `chatbot/` (mainChatbot.py, eventManager.py, chatbotConstants.py)
+- `realEstate/` (mainRealEstate.py)
+- `neutralizePlayground/` (mainNeutralizePlayground.py)
+
+**Nicht-Feature Module (aus features heraus):**
+- `gateway/modules/features/featuresLifecycle.py` -> `gateway/modules/workflows/automation/` (Event Scheduler Handling)
+- `gateway/modules/features/workflow/` -> `gateway/modules/workflows/automation/` (zentrale Workflow Execution Engine)
+- `gateway/modules/features/dynamicOptions/` -> entfernen, dynamische Optionen ueber API-Routen
+
+### Zielstruktur pro Feature
+
+**trustee** (neu):
+- Move:
+ - `modules/routes/routeFeatureTrustee.py`
+ - `modules/interfaces/interfaceDbTrustee.py`
+ - `modules/datamodels/datamodelTrustee.py`
+- Add:
+ - `modules/features/trustee/mainTrustee.py` (RBAC UI/RESOURCE-Katalog)
+- Add main module fuer RBAC-Katalog (falls noch nicht vorhanden)
+
+**chatbot**:
+- Move:
+ - `modules/routes/routeFeatureChatbot.py`
+ - `modules/interfaces/interfaceDbChatbot.py`
+ - modules/datamodels/datamodelChatbot.py
+- Keep:
+ - `modules/features/chatbot/mainChatbot.py`, Helpers
+- Add main module fuer RBAC-Katalog (falls noch nicht vorhanden)
+
+**aichat** (chatworkflow):
+- Move:
+ - `modules/routes/routeFeatureChatDynamic.py`
+ - `modules/interfaces/interfaceDbChat.py`
+ - modules/datamodels/datamodelChat.py
+- Add main module fuer RBAC-Katalog (falls noch nicht vorhanden)
+
+**neutralizer** (Rename von neutralizePlayground):
+- Move:
+ - `modules/routes/routeFeatureNeutralization.py`
+ - `modules/datamodels/datamodelNeutralizer.py`
+- Keep:
+ - `modules/features/neutralizePlayground/mainNeutralizePlayground.py` (Rename Ordner zu `neutralizer`)
+- Add main module fuer RBAC-Katalog (falls noch nicht vorhanden)
+
+**realestate**:
+- Move:
+ - `modules/routes/routeFeatureRealEstate.py`
+ - `modules/interfaces/interfaceDbRealEstate.py`
+ - `modules/datamodels/datamodelRealEstate.py`
+- Keep:
+ - `modules/features/realEstate/mainRealEstate.py`
+- Add main module fuer RBAC-Katalog (falls noch nicht vorhanden)
+
+**automation** (neu):
+- Move:
+ - `modules/routes/routeDataAutomation.py`
+ - `modules/interfaces/interfaceDbAutomation.py` <<- new, to put all automation related interfaces here>>
+ - `modules/datamodels/datamodelAutomation.py` <<- new, to put class AutomationDefinition here>>
+- Add main module fuer RBAC-Katalog (falls noch nicht vorhanden)
+
+- Neue datamodel/interface/route/main Module
+
+### App-Routing als Plug-and-Play
+`gateway/app.py` importiert `routeFeature*.py` aus Feature-Containern.
+Pattern:
+- `from modules.features..routeFeature import router as `
+- Nur existierende Ordner werden eingebunden.
+- Feature-Ordner loeschen = Feature deaktivieren.
+
+### Notwendige Referenz-Updates
+- Imports in `app.py` auf neue Pfade.
+- Alle direkten Imports der alten `modules/routes/routeFeature*.py`.
+- `featuresLifecycle.py` und `workflow` nach `gateway/modules/workflows/automation/` verschieben.
+- `dynamicOptions` entfernen und UI/API auf Options-Routen umstellen.
+- Referenzen auf `modules/interfaces/interfaceDb*.py` und `modules/datamodels/datamodel*.py` anpassen.
+
+### Machbarkeit und Bedenken
+- Shared Interfaces/Models (chatbot/workflow) brauchen klare Ownership oder Shared-Modul.
+- Feature-Lifecycle sollte Feature-Registry dynamisch laden.
+- Feature-Registry (`routeFeatures.py`, `interfaceFeatures.py`, `datamodelFeatures.py`) bleibt global.
+
+### Fragen / Klaerungen
+- Bleiben `routeFeatures.py` und `interfaceFeatures.py` global? -> JA
+- Shared chatbot/chat: Shared-Modul oder Duplikation? --> Bereits dupliziert, somit separiert
+- Feature-Discovery dynamisch (scan) oder explizite Imports in `app.py`? -> dynamisch
+
+### Propositionen
+- `routeFeatures.py`, `interfaceFeatures.py`, `datamodelFeatures.py` global behalten (System-Feature-Registry).
+- Explizite Imports in `app.py`, aber zentral ueber Feature-Index. --> Die einzelnen Features benötigen keine zentrale komponente mehr. Echt plug & play
+- Event Scheduler + Workflow Engine in `gateway/modules/workflows/automation/` (kein Feature).
+- `dynamicOptions` entfernen, dynamische Daten per spezialisierte API-Routen (RBAC-Admin Stil).
+
+### Bedenken
+- Feature-Removal muss Cron/Jobs/Hook-Registrierungen entfernen. --> bereits implementiert. die werden dann nicht mehr gefunden
+- Migration erzeugt viele Import-Aenderungen und Test-Anpassungen. --> korrekt. daher schritt für schritt plan machen
+- `dynamicOptions`-Ablösung erfordert UI/API-Umstellung auf neue Options-Routen.
+
+## Services in Feature-Container integrieren
+
+### Ziel
+Services, die eindeutig zu Features gehoeren, sollen in den jeweiligen Feature-Container verschoben werden und plug&play geladen werden (analog zu Routes).
+
+### Zuordnung
+- **aichat**:
+ - `gateway/modules/aicore`
+ - `gateway/modules/services/serviceAi`
+ - `gateway/modules/services/serviceExtraction`
+ - `gateway/modules/services/serviceGeneration`
+ - `gateway/modules/services/serviceWeb`
+- **neutralizer**:
+ - `gateway/modules/services/serviceNeutralization`
+- **Generisch (bleibt shared):**
+ - alle anderen Services bleiben in `gateway/modules/services`
+
+### Plug&Play fuer Services (analog Routes)
+- Feature-Container exportiert Service-Registrierung (z.B. `registerServices()`).
+- Zentrale Service-Registry laedt nur vorhandene Feature-Container.
+- Entfernt man den Feature-Ordner, werden auch Services nicht mehr geladen.
+
+### Umsetzungsschritte (Ergaenzung)
+
+**Schritt S1: aichat-Services verschieben**
+- Move:
+ - `gateway/modules/aicore/` -> `gateway/modules/features/aichat/aicore/`
+- Move:
+ - `gateway/modules/services/serviceAi/` -> `gateway/modules/features/aichat/services/serviceAi/`
+ - `gateway/modules/services/serviceExtraction/` -> `gateway/modules/features/aichat/services/serviceExtraction/`
+ - `gateway/modules/services/serviceGeneration/` -> `gateway/modules/features/aichat/services/serviceGeneration/`
+ - `gateway/modules/services/serviceWeb/` -> `gateway/modules/features/aichat/services/serviceWeb/`
+- Referenzen anpassen:
+ - alle Imports dieser Services auf die neuen Pfade.
+ - Service-Registry in aichat registriert diese Module.
+
+**Schritt S2: neutralizer-Services verschieben**
+- Move:
+ - `gateway/modules/services/serviceNeutralization/` -> `gateway/modules/features/neutralizer/services/serviceNeutralization/`
+- Referenzen anpassen:
+ - alle Imports auf neuen Pfad.
+ - Service-Registry in neutralizer registriert dieses Modul.
+
+**Schritt S3: Service-Discovery**
+- Zentraler Loader (shared) laedt Services pro Feature-Container dynamisch.
+- Shared Services bleiben unveraendert in `gateway/modules/services`.
+
+## Umsetzungskonzept (schrittweise)
+
+### Schritt 0: Bestandsaufnahme und Freeze
+- **Ziel:** saubere Basis, keine parallelen Feature-Refactors.
+- **Aktion:** Branch erstellen, keine Feature-Folder loeschen vor Abschluss.
+
+### Schritt 1: Bootstrap auf System-RBAC reduzieren
+- **Datei:** `gateway/modules/interfaces/interfaceBootstrap.py`
+- **Aenderung:**
+ - In `initBootstrap()` entfernen:
+ - `initFeatures(db)`
+ - `_initFeatureTemplateRoleAccessRules(db)`
+ - Entfernen:
+ - `_initFeatureTemplateRoles(db)` (Funktion + Call-Sites)
+ - `_initFeatureTemplateRoleAccessRules(db)` (Funktion + Call-Sites)
+- **Referenzen:** alle Verweise auf Feature-Template-Rollen und Feature-AccessRules loeschen.
+- **Ergebnis:** Bootstrap erstellt nur System-RBAC bei leerer DB.
+
+### Schritt 2: Feature-Container vorbereiten (Ordnerstruktur)
+- **Ziel:** pro Feature ein Container mit klarer Struktur.
+- **Neuer Ordner pro Feature:**
+ - `gateway/modules/features//`
+ - Pflicht-Module:
+ - `datamodelFeatureXxx.py`
+ - `interfaceFeatureXxx.py`
+ - `routeFeatureXxx.py`
+ - `main.py` (registriert UI/RESOURCE Katalog)
+- **Ergebnis:** leere Container fuer `trustee`, `chatbot`, `aichat`, `neutralizer`, `realestate`, `automation`.
+
+### Schritt 3: Trustee in Container verschieben
+- **Move:**
+ - `gateway/modules/routes/routeFeatureTrustee.py` -> `gateway/modules/features/trustee/routeFeatureTrustee.py`
+ - `gateway/modules/interfaces/interfaceDbTrustee.py` -> `gateway/modules/features/trustee/interfaceFeatureTrustee.py`
+ - `gateway/modules/datamodels/datamodelTrustee.py` -> `gateway/modules/features/trustee/datamodelFeatureTrustee.py`
+- **Neu:**
+ - `gateway/modules/features/trustee/mainTrustee.py` (RBAC UI/RESOURCE Katalogregistrierung)
+- **Referenzen anpassen:**
+ - Alle Imports von `routeFeatureTrustee.py`, `interfaceDbTrustee.py`, `datamodelTrustee.py`
+ - `app.py` Router-Import und Registrierung
+ - Tests, falls vorhanden
+
+### Schritt 4: Chatbot in Container verschieben
+- **Move:**
+ - `gateway/modules/routes/routeFeatureChatbot.py` -> `gateway/modules/features/chatbot/routeFeatureChatbot.py`
+ - `gateway/modules/interfaces/interfaceDbChatbot.py` -> `gateway/modules/features/chatbot/interfaceFeatureChatbot.py`
+ - `gateway/modules/datamodels/datamodelChatbot.py` -> `gateway/modules/features/chatbot/datamodelFeatureChatbot.py`
+- **Keep:**
+ - `gateway/modules/features/chatbot/mainChatbot.py` + Helpers
+- **Neu:**
+ - `gateway/modules/features/chatbot/mainChatbotCatalog.py` (oder in `mainChatbot.py`)
+- **Referenzen anpassen:**
+ - Alle Imports von `routeFeatureChatbot.py`, `interfaceDbChatbot.py`, `datamodelChatbot.py`
+ - `app.py` Router-Import und Registrierung
+
+### Schritt 5: AIChat (chatworkflow) in Container verschieben
+- **Move:**
+ - `gateway/modules/routes/routeFeatureChatDynamic.py` -> `gateway/modules/features/aichat/routeFeatureAiChat.py`
+ - `gateway/modules/interfaces/interfaceDbChat.py` -> `gateway/modules/features/aichat/interfaceFeatureAiChat.py`
+ - `gateway/modules/datamodels/datamodelChat.py` -> `gateway/modules/features/aichat/datamodelFeatureAiChat.py`
+- **Keep:**
+ - `gateway/modules/features/workflow/mainWorkflow.py` (falls nur Workflow-Logik)
+- **Neu:**
+ - `gateway/modules/features/aichat/mainAiChat.py` (RBAC UI/RESOURCE Katalog)
+- **Referenzen anpassen:**
+ - Alle Imports von `routeFeatureChatDynamic.py`, `interfaceDbChat.py`, `datamodelChat.py`
+ - `app.py` Router-Import und Registrierung
+
+### Schritt 6: Neutralizer in Container verschieben und Ordner umbenennen
+- **Rename:**
+ - `gateway/modules/features/neutralizePlayground/` -> `gateway/modules/features/neutralizer/`
+- **Move:**
+ - `gateway/modules/routes/routeFeatureNeutralization.py` -> `gateway/modules/features/neutralizer/routeFeatureNeutralizer.py`
+ - `gateway/modules/datamodels/datamodelNeutralizer.py` -> `gateway/modules/features/neutralizer/datamodelFeatureNeutralizer.py`
+- **Neu:**
+ - `gateway/modules/features/neutralizer/mainNeutralizer.py` (RBAC UI/RESOURCE Katalog)
+- **Referenzen anpassen:**
+ - Alle Imports auf `neutralizePlayground`
+ - `app.py` Router-Import und Registrierung
+
+### Schritt 7: RealEstate in Container verschieben
+- **Move:**
+ - `gateway/modules/routes/routeFeatureRealEstate.py` -> `gateway/modules/features/realestate/routeFeatureRealEstate.py`
+ - `gateway/modules/interfaces/interfaceDbRealEstate.py` -> `gateway/modules/features/realestate/interfaceFeatureRealEstate.py`
+ - `gateway/modules/datamodels/datamodelRealEstate.py` -> `gateway/modules/features/realestate/datamodelFeatureRealEstate.py`
+- **Keep:**
+ - `gateway/modules/features/realEstate/mainRealEstate.py`
+- **Neu:**
+ - `gateway/modules/features/realestate/mainRealEstateCatalog.py` (oder in mainRealEstate)
+- **Referenzen anpassen:**
+ - Alle Imports der alten Pfade
+ - `app.py` Router-Import und Registrierung
+
+### Schritt 8: Automation als Feature-Container
+- **Move:**
+ - `gateway/modules/routes/routeDataAutomation.py` -> `gateway/modules/features/automation/routeFeatureAutomation.py`
+- **Neu:**
+ - `gateway/modules/features/automation/interfaceFeatureAutomation.py`
+ - `gateway/modules/features/automation/datamodelFeatureAutomation.py` (enthaelt `AutomationDefinition`)
+ - `gateway/modules/features/automation/mainAutomation.py` (RBAC UI/RESOURCE Katalog)
+- **Referenzen anpassen:**
+ - Alle Imports von `routeDataAutomation.py`
+ - `app.py` Router-Import und Registrierung
+
+### Schritt 9: App-Routing dynamisch
+- **Datei:** `gateway/app.py`
+- **Aenderung:**
+ - Entferne direkte Imports aus `modules/routes/`.
+ - Importiere Router aus Feature-Containern dynamisch (Feature-Discovery).
+- **Referenzen:** alle Router-Registrierungen auf neue Pfade/Discovery umstellen.
+
+### Schritt 10: featuresLifecycle anpassen
+- **Datei:** `gateway/modules/features/featuresLifecycle.py`
+- **Aenderung:**
+ - Feature-Registry dynamisch laden (Folder-Discovery).
+ - Keine direkten Imports aus alten Pfaden.
+- **Referenzen:** Aufrufe in `app.py` bleiben, aber Lifecycle nutzt Feature-Liste.
+
+### Schritt 11: Referenzen global bereinigen
+- **Ziel:** Import-Pfade konsistent.
+- **Aenderungen:**
+ - Alle Imports von `modules/routes/routeFeature*.py` entfernen.
+ - Alle Imports von `modules/interfaces/interfaceDb*.py` auf `interfaceFeature*.py` umstellen.
+ - Alle Imports von `modules/datamodels/datamodel*.py` auf `datamodelFeature*.py` umstellen.
+
+### Schritt 12: RBAC Katalog Registrierungen pro Feature
+- **Ziel:** jede Feature-Instanz registriert UI/RESOURCE Keys.
+- **Dateien:** `main.py` je Feature-Container
+- **Aenderung:** einheitliche Registrierungs-API verwenden (im Katalog-Service).
+
+### Schritt 13: Tests und Verifikation
+- **Smoke Tests:**
+ - Start Gateway, pruefen dass alle Feature-Routes registriert sind.
+ - Entferne Feature-Ordner testweise -> Route nicht mehr vorhanden.
+ - RBAC Katalog liefert Objekte fuer alle Features.
+ - Bootstrap erzeugt nur System-RBAC bei leerer DB.
diff --git a/implementation/rbac_access_umsetzungskonzept done.md b/implementation/rbac_access_umsetzungskonzept done.md
new file mode 100644
index 0000000..0a4106e
--- /dev/null
+++ b/implementation/rbac_access_umsetzungskonzept done.md
@@ -0,0 +1,463 @@
+# Umsetzungskonzept RBAC Access (separat, schrittweise)
+
+## Ziel
+Das RBAC-Konzept aus `concept_rbac_access_pending.md` technisch umsetzen, inkl.:
+- Feature-Containerisierung (plug&play)
+- Bootstrap auf System-RBAC reduzieren
+- Feature-Services in Container integrieren
+- aicore in aichat integrieren
+- dynamisches Laden von Routes und Services
+- striktes Import-Regelwerk ohne Abhaengigkeiten zwischen Feature-Containern
+
+## Import-Regelwerk (Zielzustand)
+- **Kein Import zwischen Feature-Containern.**
+- **Feature-Container duerfen zentrale Module importieren (`modules/interfaces`, `modules/datamodels`, `modules/services`, `modules/aicore`, `modules/shared`, `modules/connectors`, `modules/security`, `modules/auth`).**
+- **Umgekehrt darf zentraler Code keine Feature-Container importieren.**
+
+## Wichtige konzeptionelle und architektonische Hinweise
+- Jeder Feature-Container ist vollstaendig eigenstaendig (Code, Datamodelle, Interfaces, Routes, Services), darf aber zentrale Module nutzen.
+- Zentrale Pfade bleiben Plattform-Schnittstellen und duerfen von Features genutzt werden; umgekehrt keine Feature-Imports aus zentralem Code.
+- System-RBAC und Feature-RBAC sind strikt getrennt: Bootstrap initialisiert nur System-RBAC, Feature-RBAC entsteht durch Feature-Container.
+- Der RBAC-Katalog fuer UI/RESOURCE liegt in `gateway/modules/security/rbacCatalog/` und ist persistent; Feature-Container muessen nur registrieren, nicht speichern.
+- UI/RESOURCE-Objekte werden rein im Backend definiert und persistiert, keine UI-Abhaengigkeit.
+- Datenobjekte werden dynamisch abgeleitet, sind aber nicht auf Features beschraenkt (System- und Feature-Tabellen sind sichtbar).
+- Strikte Importregel erzeugt harte Grenzen: Shared-Module muessen in den Feature-Container verschoben oder repliziert werden.
+- Zentraler Workflow (geplant unter `gateway/modules/workflows/automation/`) darf aus Features nicht direkt importiert werden; Zugriff nur ueber feature-interne Adapter/Entry-Points oder durch Verlagerung der benoetigten Teile in die Feature-Container.
+
+## Schrittfolge mit Dateiaenderungen und Referenz-Checkliste
+
+### Schritt 1: Bootstrap auf System-RBAC reduzieren
+**Datei:** `gateway/modules/interfaces/interfaceBootstrap.py`
+- Entfernen in `initBootstrap()`:
+ - `initFeatures(db)`
+ - `_initFeatureTemplateRoleAccessRules(db)`
+- Entfernen:
+ - `_initFeatureTemplateRoles(db)` (Funktion + Call-Sites)
+ - `_initFeatureTemplateRoleAccessRules(db)` (Funktion + Call-Sites)
+- **Beibehalten:** `initRoles(db)`, `initRbacRules(db)`
+- **Checkliste Referenzen:**
+ - Keine Feature-Initialisierung in Bootstrap
+ - Keine Feature-Template-Rollen
+ - Keine Feature-Template-AccessRules
+
+### Schritt 2: Feature-Container-Struktur anlegen
+**Neue Ordner:**
+- `gateway/modules/features/trustee/`
+- `gateway/modules/features/chatbot/` (existiert)
+- `gateway/modules/features/aichat/` (neu)
+- `gateway/modules/features/neutralizer/` (rename)
+- `gateway/modules/features/realestate/` (neu)
+- `gateway/modules/features/automation/` (neu)
+
+**Pflichtdateien je Feature:**
+- `datamodelFeatureXxx.py`
+- `interfaceFeatureXxx.py`
+- `routeFeatureXxx.py`
+- `mainXxx.py` (RBAC UI/RESOURCE Registry)
+
+**Struktur-Vorgaben (Soll):**
+- Jeder Container enthaelt alle benoetigten Submodule, inkl. Services und Helfer.
+- Zentrale Module duerfen genutzt werden; keine Feature-zu-Feature-Imports.
+- Service-Subfolder bleiben erhalten, liegen aber direkt im Container (`serviceXxx/`).
+
+**Calling-Referenzen (allgemein):**
+- `gateway/app.py` registriert alle Feature-Router dynamisch.
+- Feature-Container registrieren ihre RBAC-Objekte im Katalog (z.B. via `mainXxx.py` als Entry-Point).
+- Systemcode greift nicht auf Feature-Implementierung zu, sondern nur auf deren registrierte Router/Services.
+
+### Schritt 3: Trustee verschieben
+**Move:**
+- `gateway/modules/routes/routeFeatureTrustee.py`
+ -> `gateway/modules/features/trustee/routeFeatureTrustee.py`
+- `gateway/modules/interfaces/interfaceDbTrustee.py`
+ -> `gateway/modules/features/trustee/interfaceFeatureTrustee.py`
+- `gateway/modules/datamodels/datamodelTrustee.py`
+ -> `gateway/modules/features/trustee/datamodelFeatureTrustee.py`
+**Add:**
+- `gateway/modules/features/trustee/mainTrustee.py` (RBAC Katalog)
+
+**Referenzen anpassen (Checkliste):**
+- Alle Imports auf `routeFeatureTrustee.py` neu
+- Alle Imports auf `interfaceDbTrustee.py` neu
+- Alle Imports auf `datamodelTrustee.py` neu
+- `app.py` Router-Registrierung auf neuen Pfad
+**Calling-Referenzen (Suche):**
+- `rg -n "routeFeatureTrustee|interfaceDbTrustee|datamodelTrustee" gateway/`
+
+### Schritt 4: Chatbot verschieben
+**Move:**
+- `gateway/modules/routes/routeFeatureChatbot.py`
+ -> `gateway/modules/features/chatbot/routeFeatureChatbot.py`
+- `gateway/modules/interfaces/interfaceDbChatbot.py`
+ -> `gateway/modules/features/chatbot/interfaceFeatureChatbot.py`
+- `gateway/modules/datamodels/datamodelChatbot.py`
+ -> `gateway/modules/features/chatbot/datamodelFeatureChatbot.py`
+**Keep:**
+- `gateway/modules/features/chatbot/mainChatbot.py` + Helpers
+**Add:**
+- `gateway/modules/features/chatbot/mainChatbotCatalog.py` (oder in mainChatbot)
+
+**Referenzen anpassen:**
+- Imports fuer `interfaceDbChatbot`/`datamodelChatbot`/`routeFeatureChatbot`
+- `app.py` Router-Registrierung
+**Calling-Referenzen (Suche):**
+- `rg -n "routeFeatureChatbot|interfaceDbChatbot|datamodelChatbot" gateway/`
+
+### Schritt 5: AIChat (chatworkflow) verschieben
+**Move:**
+- `gateway/modules/routes/routeFeatureChatDynamic.py`
+ -> `gateway/modules/features/aichat/routeFeatureAiChat.py`
+- `gateway/modules/interfaces/interfaceDbChat.py`
+ -> `gateway/modules/features/aichat/interfaceFeatureAiChat.py`
+- `gateway/modules/datamodels/datamodelChat.py`
+ -> `gateway/modules/features/aichat/datamodelFeatureAiChat.py`
+**Add:**
+- `gateway/modules/features/aichat/mainAiChat.py` (RBAC Katalog)
+**Keep:**
+- `gateway/modules/features/workflow/mainWorkflow.py` (falls reine Workflow-Logik)
+
+**Referenzen anpassen:**
+- Alle Imports auf `routeFeatureChatDynamic.py`
+- Alle Imports auf `interfaceDbChat.py`
+- Alle Imports auf `datamodelChat.py`
+- `app.py` Router-Registrierung
+**Calling-Referenzen (Suche):**
+- `rg -n "routeFeatureChatDynamic|interfaceDbChat|datamodelChat" gateway/`
+
+### Schritt 6: Neutralizer verschieben und Ordner umbenennen
+**Rename:**
+- `gateway/modules/features/neutralizePlayground/`
+ -> `gateway/modules/features/neutralizer/`
+**Move:**
+- `gateway/modules/routes/routeFeatureNeutralization.py`
+ -> `gateway/modules/features/neutralizer/routeFeatureNeutralizer.py`
+- `gateway/modules/datamodels/datamodelNeutralizer.py`
+ -> `gateway/modules/features/neutralizer/datamodelFeatureNeutralizer.py`
+**Add:**
+- `gateway/modules/features/neutralizer/mainNeutralizer.py` (RBAC Katalog)
+
+**Referenzen anpassen:**
+- Alle Imports auf `neutralizePlayground`
+- Alle Imports auf `routeFeatureNeutralization.py`
+- `app.py` Router-Registrierung
+**Calling-Referenzen (Suche):**
+- `rg -n "neutralizePlayground|routeFeatureNeutralization|datamodelNeutralizer" gateway/`
+
+### Schritt 7: RealEstate verschieben
+**Move:**
+- `gateway/modules/routes/routeFeatureRealEstate.py`
+ -> `gateway/modules/features/realestate/routeFeatureRealEstate.py`
+- `gateway/modules/interfaces/interfaceDbRealestate.py`
+ -> `gateway/modules/features/realestate/interfaceFeatureRealEstate.py`
+- `gateway/modules/datamodels/datamodelRealEstate.py`
+ -> `gateway/modules/features/realestate/datamodelFeatureRealEstate.py`
+**Keep:**
+- `gateway/modules/features/realEstate/mainRealEstate.py`
+**Add:**
+- `gateway/modules/features/realestate/mainRealEstateCatalog.py` (oder in mainRealEstate)
+
+**Referenzen anpassen:**
+- Imports auf `interfaceDbRealestate`, `datamodelRealEstate`, `routeFeatureRealEstate`
+- `app.py` Router-Registrierung
+**Calling-Referenzen (Suche):**
+- `rg -n "routeFeatureRealEstate|interfaceDbRealestate|datamodelRealEstate" gateway/`
+
+### Schritt 8: Automation Feature-Container
+**Move:**
+- `gateway/modules/routes/routeDataAutomation.py`
+ -> `gateway/modules/features/automation/routeFeatureAutomation.py`
+**Add:**
+- `gateway/modules/features/automation/interfaceFeatureAutomation.py`
+- `gateway/modules/features/automation/datamodelFeatureAutomation.py`
+ - enthaelt `AutomationDefinition`
+- `gateway/modules/features/automation/mainAutomation.py` (RBAC Katalog)
+
+**Referenzen anpassen:**
+- Alle Imports von `routeDataAutomation.py`
+- Alle `AutomationDefinition`-Imports auf neuen Pfad
+- `app.py` Router-Registrierung
+**Calling-Referenzen (Suche):**
+- `rg -n "routeDataAutomation|AutomationDefinition" gateway/`
+
+### Schritt 9: Services in Feature-Container
+**aichat:**
+- Move:
+ - `gateway/modules/aicore/` -> `gateway/modules/features/aichat/aicore/`
+ - `gateway/modules/services/serviceAi/` -> `gateway/modules/features/aichat/serviceAi/`
+ - `gateway/modules/services/serviceExtraction/` -> `gateway/modules/features/aichat/serviceExtraction/`
+ - `gateway/modules/services/serviceGeneration/` -> `gateway/modules/features/aichat/serviceGeneration/`
+ - `gateway/modules/services/serviceWeb/` -> `gateway/modules/features/aichat/serviceWeb/`
+**neutralizer:**
+- Move:
+ - `gateway/modules/services/serviceNeutralization/` -> `gateway/modules/features/neutralizer/serviceNeutralization/`
+**Shared Services:**
+- bleiben in `gateway/modules/services`
+
+**Referenzen anpassen:**
+- Alle Imports der o.g. Services auf neue Pfade
+- AI-Services duerfen keine Imports ausserhalb des aichat-Containers haben
+- In Feature-Folders kein Subfolder `services`; Services liegen direkt als `serviceXxx/`
+**Calling-Referenzen (Suche):**
+- `rg -n "modules\\.services\\.service(Ai|Extraction|Generation|Web)|modules\\.aicore" gateway/`
+- `rg -n "serviceNeutralization" gateway/`
+
+**Code-Struktur (Soll):**
+- Feature-Services importieren nur Feature-Datamodelle innerhalb des Containers.
+- `aicore` wird komplett unter `features/aichat/` verschoben und ist nur dort nutzbar.
+
+### Schritt 10: Plug&Play Router Loading
+**Datei:** `gateway/app.py`
+- Ersetze statische Imports aus `modules/routes` durch dynamische Feature-Discovery.
+- Nur existierende Feature-Folder werden registriert.
+
+**Referenzen anpassen:**
+- Alle Router-Registrierungen neu
+- Keine Route-Imports aus `modules/routes`
+
+**Konzept Router-Discovery (Soll):**
+- Scanne `gateway/modules/features/*/` nach `routeFeature*.py`.
+- Pro Datei wird ein `router`-Objekt erwartet und registriert.
+- Fehlende Router in einem Feature duerfen den Start nicht abbrechen (log + skip).
+- Feature-Status markieren: `active`, `degraded` (z.B. Router ok, Service-Load fehlschlaegt).
+
+### Schritt 11: Plug&Play Service Loading
+**Zentraler Loader (shared):**
+- Ein Service-Registry-Modul laedt pro Feature-Container definierte Services.
+- Nur existierende Feature-Folder werden registriert.
+
+**Referenzen anpassen:**
+- Alle Service-Center-Aufrufe auf neuen Loader
+- Kein direkter Import aus `modules/services/serviceAi` etc.
+
+**Konzept Service-Discovery (Soll):**
+- Pro Feature-Container werden vorhandene `service*`-Ordner als Services erkannt.
+- Der Loader scannt `gateway/modules/features//service*/` und registriert diese Services zentral.
+- Services werden nur geladen, wenn der Feature-Container vorhanden ist.
+- Registrierungs-Contract analog `modules/services/__init__.py`:
+ - In jedem `service*`-Ordner existiert `mainService*.py` mit Service-Klasse.
+ - Loader instanziert Service und exponiert ihn via `PublicService(...)`.
+
+### Schritt 12: featuresLifecycle anpassen
+**Datei:** `gateway/modules/features/featuresLifecycle.py`
+- Import der Workflow-Logik aus neuem zentralen Pfad (`gateway/modules/workflows/automation/`)
+- Keine Imports von Feature-Containern
+
+**Bemerkung:**
+- Kein Feature-Discovery notwendig: Modul ist zentraler Scheduler fuer Workflow/Automation.
+- Update der Imports: `modules.features.workflow` -> `modules.workflows.automation` (nach Auslagerung).
+- Workflow-API ist zentral und stabil: Features duerfen nur explizite Entry-Points nutzen (z.B. `syncAutomationEvents`), keine direkten Imports in interne Workflow-Module.
+
+### Schritt 13: Globale Referenzen bereinigen
+**Checkliste:**
+- Keine Imports von `modules/routes/routeFeature*.py` mehr
+- `interfaceDb*.py` und `datamodel*.py` bleiben fuer System-Module bestehen
+- `modules/services/service*` bleiben fuer System-Services bestehen
+- `modules/aicore` wird verschoben (Feature `aichat`), keine zentralen Imports mehr
+
+**Calling-Referenzen (Suche):**
+- `rg -n "modules\\.routes\\.routeFeature" gateway/`
+
+### Schritt 14: Tests
+- Gateway starten, Router-Registrierung pruefen
+- Feature-Folder umbenennen mit z.b. prefix: Route/Service nicht mehr vorhanden
+- RBAC Katalog liefert Feature-Objekte
+- Bootstrap erzeugt nur System-RBAC
+- RBAC Regeln bleiben erhalten, wenn Feature-Ordner entfernt/umbenannt ist (Persistenztest).
+- Service-Discovery registriert Services korrekt und markiert `degraded` bei Teilfehlern.
+
+## Referenz-Checkliste (gesamt)
+- `gateway/app.py` Router
+- `gateway/modules/features/featuresLifecycle.py`
+- alle `routeFeature*.py`
+- alle `interfaceDb*.py`
+- alle `datamodel*.py`
+- alle `main*.py` in Feature-Containern
+- Service-Center/Service-Loader
+- Tests/Fixtures
+ - RBAC-Katalog Modul in `gateway/modules/security/rbacCatalog/`
+ - `gateway/modules/interfaces/interfaceBootstrap.py`
+
+## Import-Analyse (Istzustand, zu verschiebende Module)
+
+### Routes (aktueller Stand)
+- `routeFeatureRealEstate.py`:
+ - imports: `modules.auth`, `modules.datamodels.*`, `modules.interfaces.interfaceDbRealestate`, `modules.features.realEstate.mainRealEstate`, `modules.connectors`, `modules.shared`
+- `routeFeatureTrustee.py`:
+ - imports: `modules.auth`, `modules.interfaces.interfaceDbTrustee`, `modules.interfaces.interfaceDbApp`, `modules.interfaces.interfaceFeatures`, `modules.datamodels.*`
+- `routeFeatureChatDynamic.py`:
+ - imports: `modules.auth`, `modules.interfaces.interfaceDbChat`, `modules.datamodels.datamodelChat`, `modules.features.workflow`
+- `routeFeatureChatbot.py`:
+ - imports: `modules.auth`, `modules.interfaces.interfaceDbChat`, `modules.interfaces.interfaceRbac`, `modules.datamodels.*`, `modules.features.chatbot`, `modules.features.workflow`, `modules.shared`
+- `routeFeatureNeutralization.py`:
+ - imports: `modules.auth`, `modules.datamodels.datamodelNeutralizer`, `modules.features.neutralizePlayground`
+- `routeDataAutomation.py`:
+ - imports: `modules.interfaces.interfaceDbChat`, `modules.auth`, `modules.datamodels.datamodelChat`, `modules.features.workflow`, `modules.shared`
+
+### Interfaces (aktueller Stand)
+- `interfaceDbTrustee.py`:
+ - imports: `modules.connectors`, `modules.shared`, `modules.interfaces.interfaceRbac`, `modules.security`, `modules.datamodels.*`
+- `interfaceDbRealestate.py`:
+ - imports: `modules.datamodels.*`, `modules.connectors`, `modules.shared`, `modules.security`, `modules.interfaces.interfaceRbac`
+- `interfaceDbChat.py` / `interfaceDbChatbot.py`:
+ - imports: `modules.security`, `modules.datamodels.*`, `modules.connectors`, `modules.shared`, `modules.interfaces.interfaceRbac`, `modules.interfaces.interfaceDbManagement`
+
+### Feature-Logik (aktueller Stand)
+- `modules/features/chatbot/mainChatbot.py`:
+ - imports: `modules.datamodels.*`, `modules.shared`, `modules.services`, `modules.workflows`, `modules.connectors`
+- `modules/features/workflow/mainWorkflow.py`:
+ - imports: `modules.datamodels.*`, `modules.shared`, `modules.services`, `modules.workflows`
+- `modules/features/realEstate/mainRealEstate.py`:
+ - imports: `modules.datamodels.*`, `modules.services`, `modules.interfaces.interfaceDbRealestate`, `modules.connectors`, externe libs
+- `modules/features/neutralizePlayground/mainNeutralizePlayground.py`:
+ - imports: `modules.datamodels.*`, `modules.services`
+
+### Services / aicore (aktueller Stand)
+- `modules/services/serviceAi/mainServiceAi.py`:
+ - imports: `modules.datamodels.*`, `modules.services.serviceExtraction`, `modules.interfaces.interfaceAiObjects`, `modules.shared`
+- `modules/services/serviceNeutralization/mainServiceNeutralization.py`:
+ - imports: `modules.datamodels.datamodelNeutralizer`, eigene subProcess-* Module
+- `modules/aicore/*`:
+ - imports: `modules.datamodels.*`, `modules.security`, `modules.connectors`
+
+### Services Submodule-Analyse (Detail)
+
+**serviceAi/**
+- `mainServiceAi.py`
+ - imports: `modules.datamodels.datamodelChat`, `modules.datamodels.datamodelAi`,
+ `modules.datamodels.datamodelExtraction`, `modules.datamodels.datamodelWorkflow`,
+ `modules.datamodels.datamodelDocument`, `modules.interfaces.interfaceAiObjects`,
+ `modules.services.serviceExtraction`, `modules.shared`
+- `subStructureGeneration.py`
+ - imports: `modules.datamodels.datamodelExtraction`, `modules.datamodels.datamodelAi`,
+ `modules.workflows.processing.shared.stateTools`
+- `subStructureFilling.py`
+ - imports: `modules.datamodels.datamodelExtraction`, `modules.datamodels.datamodelAi`,
+ `modules.workflows.processing.shared.stateTools`
+- `subResponseParsing.py`
+ - imports: `modules.shared.jsonUtils`, `modules.services.serviceAi.subJsonResponseHandling`,
+ `modules.datamodels.datamodelAi`
+- `subJsonResponseHandling.py`
+ - imports: `modules.shared.jsonUtils`, `modules.datamodels.datamodelAi`
+- `subJsonMerger.py`
+ - imports: `modules.shared.jsonUtils`
+- `subDocumentIntents.py`
+ - imports: `modules.datamodels.datamodelChat`, `modules.datamodels.datamodelExtraction`,
+ `modules.workflows.processing.shared.stateTools`
+- `subContentExtraction.py`
+ - imports: `modules.datamodels.datamodelChat`, `modules.datamodels.datamodelExtraction`,
+ `modules.workflows.processing.shared.stateTools`
+- `subAiCallLooping.py`
+ - imports: `modules.datamodels.datamodelAi`, `modules.datamodels.datamodelExtraction`,
+ `modules.services.serviceAi.subJsonResponseHandling`,
+ `modules.services.serviceAi.subLoopingUseCases`,
+ `modules.workflows.processing.shared.stateTools`,
+ `modules.shared.jsonContinuation`, `modules.shared.jsonUtils`
+- `subLoopingUseCases.py`, `subJsonResponseHandling.py`, `subJsonMerger.py` (shared utils)
+ - imports: `modules.shared.*` (je nach Datei)
+
+**serviceExtraction/**
+- `mainServiceExtraction.py`
+ - imports: `modules.datamodels.datamodelExtraction`, `modules.datamodels.datamodelChat`,
+ `modules.datamodels.datamodelAi`, `modules.aicore.aicoreModelRegistry`,
+ `modules.aicore.aicoreModelSelector`, `modules.shared.jsonUtils`
+- `merging/*` (mergerText/mergerTable/mergerDefault)
+ - imports: `modules.datamodels.datamodelExtraction`
+- `extractors/*` (Xml/Xlsx/Text/Sql/Pptx/Html/Image/Json/Pdf/Csv/Docx/Binary)
+ - imports: `modules.datamodels.datamodelExtraction` (teilweise ContentExtracted)
+- `chunking/*` (chunkerText/ChunkerTable/ChunkerStructure/ChunkerImage)
+ - imports: `modules.datamodels.datamodelExtraction`
+- `subRegistry.py`
+ - imports: `modules.datamodels.datamodelExtraction`
+- `subPromptBuilderExtraction.py`
+ - imports: `modules.datamodels.datamodelAi`
+- `subPipeline.py`
+ - imports: `modules.datamodels.datamodelExtraction`
+- `subMerger.py`
+ - imports: `modules.datamodels.datamodelExtraction`
+
+**serviceGeneration/**
+- `mainServiceGeneration.py`
+ - imports: `modules.datamodels.datamodelDocument`, `modules.datamodels.datamodelChat`,
+ `modules.services.serviceGeneration.subDocumentUtility`
+- `renderers/*`
+ - imports: `modules.datamodels.datamodelDocument` (alle Renderer)
+ - `documentRendererBaseTemplate.py` imports zusaetzlich:
+ `modules.datamodels.datamodelJson`, `modules.datamodels.datamodelAi`
+- `paths/*`
+ - `imagePath.py`: `modules.datamodels.datamodelWorkflow`, `modules.datamodels.datamodelAi`
+ - `documentPath.py`: `modules.datamodels.datamodelWorkflow`, `modules.datamodels.datamodelExtraction`,
+ `modules.datamodels.datamodelAi`, `modules.datamodels.datamodelDocument`,
+ `modules.workflows.processing.shared.stateTools`
+ - `codePath.py`: `modules.datamodels.datamodelWorkflow`, `modules.datamodels.datamodelExtraction`,
+ `modules.datamodels.datamodelAi`, `modules.shared.jsonUtils`
+- `subStructureGenerator.py` / `subPromptBuilderGeneration.py`
+ - imports: `modules.datamodels.datamodelJson`
+- `subContentGenerator.py`
+ - imports: `modules.services.serviceGeneration.subContentIntegrator`,
+ `modules.workflows.processing.shared.stateTools`
+
+**serviceWeb/**
+- `mainServiceWeb.py`
+ - imports: `modules.datamodels.datamodelAi` (AiCallOptions, OperationTypeEnum, AiCallPrompt*)
+
+**serviceNeutralization/**
+- `mainServiceNeutralization.py`
+ - imports: `modules.datamodels.datamodelNeutralizer`,
+ `modules.services.serviceNeutralization.subProcess*`
+- `subProcessText.py`
+ - imports: `modules.services.serviceNeutralization.subParseString`
+- `subProcessList.py`
+ - imports: `modules.services.serviceNeutralization.subParseString`,
+ `modules.services.serviceNeutralization.subPatterns`
+- `subParseString.py`
+ - imports: `modules.services.serviceNeutralization.subPatterns`
+
+## Compliance-Check gegen Import-Regelwerk (Zielzustand)
+
+**Zielkriterium:**
+- Keine Imports zwischen Feature-Containern.
+- Feature-Container duerfen zentrale Module importieren.
+- Zentrale Module duerfen keine Feature-Container importieren.
+
+**Erwarteter Zustand nach Migration:**
+- Alle `interfaceFeatureXxx.py`, `routeFeatureXxx.py`, `datamodelFeatureXxx.py`, `mainXxx.py` liegen im jeweiligen Feature-Container.
+- Interne Feature-Imports (z.B. `chatbot` -> `chatbot.eventManager`) sind erlaubt.
+- Keine Feature-zu-Feature-Imports mehr (z.B. `chatbot` -> `workflow` entfaellt durch Auslagerung).
+
+**Hinweis zur Validierung:**
+- Compliance-Check erfolgt nach Abschluss der Verschiebungen und Import-Anpassungen.
+- Der Istzustand dient nur als Analysegrundlage und ist nicht compliance-faehig.
+
+## Import-Check (Zielzustand, Soll)
+
+**Erlaubte Imports innerhalb eines Feature-Containers:**
+- Relative Imports innerhalb des Containers (z.B. `.eventManager`, `.subModule`).
+- Absolute Imports innerhalb des eigenen Containers (z.B. `modules.features.chatbot.*` im Container `chatbot`).
+- Standardbibliothek und externe Libraries.
+
+**Nicht erlaubt (muss im Zielzustand eliminiert werden):**
+- Imports aus anderen Feature-Containern (`modules.features..*`).
+- Zentrale Module importieren Feature-Container (`modules.features.*`).
+
+**Soll-Checkliste je Feature-Container:**
+- Keine `modules.features..*` Imports.
+- Keine Feature-zu-Feature-Abhaengigkeiten.
+
+**Pruefroutine (rg-Patterns, Zielzustand):**
+- Finde direkte Cross-Feature-Imports:
+ - `rg -n "modules\\.features\\.(?!\\.)" gateway/modules/features//`
+- Finde verbotene Feature-Imports aus zentralem Code:
+ - `rg -n "modules\\.features\\." gateway/modules/(routes|interfaces|datamodels|services|aicore|shared|connectors|security|auth)/`
+
+## Istzustand (nur Analyse, vor Migration)
+
+**Konflikte (heute):**
+- Alle Routen, Interfaces, Feature-Logiken und Services importieren Module ausserhalb eines Feature-Containers.
+- Es bestehen Imports zwischen Features (z.B. `routeFeatureChatbot` -> `modules.features.workflow`, im Zielzustand entfaellt da `workflow` kein Feature mehr ist).
+
+**Liste der Imports zwischen Features (Istzustand, Analyse):**
+- `gateway/modules/interfaces/interfaceDbChatbot.py` -> `modules.features.chatbot.eventManager`
+
+## Offene Punkte fuer Umsetzung
+- Dynamische Feature-Discovery in `app.py` und Service-Loader designen
+- Schrittweise Migration je Feature mit Tests
diff --git a/implementation/trustee_feature_rbac_architecture.md b/implementation/trustee_feature_rbac_architecture.md
new file mode 100644
index 0000000..983fa2e
--- /dev/null
+++ b/implementation/trustee_feature_rbac_architecture.md
@@ -0,0 +1,687 @@
+# Trustee Feature - RBAC Architektur & Gateway-Readiness
+
+## Übersicht
+
+Dieses Dokument beschreibt die **Zwei-Stufen-RBAC-Architektur** für das Trustee Feature und beantwortet die Frage, ob das Gateway bereit für die UI-Entwicklung ist.
+
+**Erstellungsdatum**: 2026-01-23
+**Status**: Review
+
+---
+
+## 1. Gateway-Status
+
+### 1.1 Ist das Gateway bereit für UI-Arbeit?
+
+**Ja, das Gateway ist vollständig bereit.**
+
+| Komponente | Datei | Status |
+|------------|-------|--------|
+| **Routes** | `routeFeatureTrustee.py` | ✅ Komplett |
+| **Interface** | `interfaceFeatureTrustee.py` | ✅ Komplett |
+| **Datamodel** | `datamodelFeatureTrustee.py` | ✅ Komplett |
+| **Feature-RBAC** | Via `TrusteeAccess` Tabelle | ✅ Implementiert |
+
+### 1.2 Verfügbare API-Endpoints
+
+Alle Endpoints verwenden das URL-Pattern: `/api/trustee/{instanceId}/...`
+
+| Endpoint-Gruppe | Basis-Route | CRUD | Options |
+|-----------------|-------------|------|---------|
+| Organisations | `/api/trustee/{instanceId}/organisations` | ✅ | ✅ |
+| Roles | `/api/trustee/{instanceId}/roles` | ✅ | ✅ |
+| **Access** | `/api/trustee/{instanceId}/access` | ✅ | - |
+| Contracts | `/api/trustee/{instanceId}/contracts` | ✅ | ✅ |
+| Documents | `/api/trustee/{instanceId}/documents` | ✅ | ✅ |
+| Positions | `/api/trustee/{instanceId}/positions` | ✅ | ✅ |
+| Position-Documents | `/api/trustee/{instanceId}/position-documents` | ✅ | - |
+| **User Options** | `/api/users/options` | - | ✅ |
+
+### 1.3 Wichtige Änderung vs. UI-Spezifikation
+
+Die ursprüngliche UI-Spezifikation (`doc_trustee_feature_ui_specification.md`) verwendet URLs wie:
+```
+/api/trustee/organisations/
+```
+
+Die **aktuelle Implementierung** verwendet:
+```
+/api/trustee/{instanceId}/organisations/
+```
+
+**Grund**: Multi-Tenancy - mehrere Treuhandbüros (Feature-Instanzen) pro Mandate möglich.
+
+---
+
+## 2. Architektur: Zwei-Stufen-RBAC für Features
+
+### 2.1 Das Problem
+
+Ein Treuhandbüro (Feature-Instanz) verwaltet mehrere Kunden (Organisationen). Jeder Mitarbeiter soll nur die Kunden sehen, für die er zuständig ist:
+
+- **User A** → Kunde 1, Kunde 2
+- **User B** → Kunde 2, Kunde 3
+- **User C** → Alle Kunden (Admin)
+
+Dies erfordert eine **Feature-interne Isolation**, die über das System-RBAC hinausgeht.
+
+### 2.2 Lösung: Zwei-Stufen-RBAC
+
+```
+┌─────────────────────────────────────────────────────────────────────────┐
+│ STUFE 1: SYSTEM-RBAC │
+│ (Mandate + Feature Instance Zugang) │
+├─────────────────────────────────────────────────────────────────────────┤
+│ │
+│ User ──► UserMandate ──► Mandate │
+│ │ │
+│ └──► FeatureAccess ──► FeatureInstance (Treuhandbüro) │
+│ │ │
+│ └── Rollen: feature-admin, feature-user │
+│ │
+│ Frage: Hat der User überhaupt Zugang zu diesem Feature? │
+│ │
+└─────────────────────────────────────────────────────────────────────────┘
+ │
+ ▼
+┌─────────────────────────────────────────────────────────────────────────┐
+│ STUFE 2: FEATURE-SPEZIFISCHES RBAC │
+│ (Isolation innerhalb des Features) │
+├─────────────────────────────────────────────────────────────────────────┤
+│ │
+│ TrusteeAccess │
+│ ├── userId → Welcher User │
+│ ├── organisationId → Welcher Kunde (Isolationsobjekt) │
+│ ├── roleId → Welche Feature-Rolle (admin, operate, userreport)│
+│ └── contractId → Optional: Einschränkung auf bestimmten Vertrag │
+│ │
+│ Frage: Welche Kunden darf der User sehen? Mit welchen Rechten? │
+│ │
+└─────────────────────────────────────────────────────────────────────────┘
+```
+
+### 2.3 Vergleich: System-RBAC vs. Feature-RBAC
+
+| Aspekt | System-RBAC | Feature-RBAC (Trustee) |
+|--------|-------------|------------------------|
+| **Tabelle** | `AccessRule` | `TrusteeAccess` |
+| **Scope** | Global / Mandate | Feature-Instanz |
+| **Objekte** | Tables, UI-Items, API-Resources | Organisationen, Contracts |
+| **Verwaltung** | SysAdmin | Feature-Admin |
+| **Zweck** | "Was darf der User technisch?" | "Welche Daten darf der User sehen?" |
+
+### 2.4 Feature-spezifische Rollen
+
+Das Trustee-Feature definiert drei Rollen:
+
+| Rolle | Beschreibung | Berechtigungen |
+|-------|--------------|----------------|
+| **admin** | Feature-Administrator | Voller CRUD auf Organisation + alle Contracts |
+| **operate** | Sachbearbeiter | CRUD für Contracts, Documents, Positions |
+| **userreport** | Endbenutzer | Nur eigene erstellte Records (Documents, Positions) |
+
+### 2.5 Contract-Level Isolation (optional)
+
+`TrusteeAccess.contractId` ermöglicht feinere Isolation:
+
+- **Leer/NULL**: Zugriff auf alle Contracts der Organisation
+- **Gesetzt**: Zugriff nur auf diesen spezifischen Contract
+
+```
+Beispiel:
+- User A hat Zugriff auf Organisation "Kunde-X" mit contractId=NULL
+ → Sieht alle Contracts von Kunde-X
+
+- User B hat Zugriff auf Organisation "Kunde-X" mit contractId="contract-123"
+ → Sieht nur Contract "contract-123" von Kunde-X
+```
+
+---
+
+## 3. Implementierung im Gateway
+
+### 3.1 Datenmodell: TrusteeAccess
+
+```python
+class TrusteeAccess(BaseModel):
+ id: str # UUID
+ organisationId: str # FK zu TrusteeOrganisation
+ roleId: str # FK zu TrusteeRole (admin, operate, userreport)
+ userId: str # FK zu User
+ contractId: Optional[str] # Optional: FK zu TrusteeContract
+ mandateId: Optional[str] # System-Kontext
+ featureInstanceId: Optional[str] # Feature-Instanz
+```
+
+### 3.2 Kombinierte Berechtigungsprüfung
+
+Die Methode `checkCombinedPermission()` in `interfaceFeatureTrustee.py` kombiniert beide Stufen:
+
+```python
+def checkCombinedPermission(self, modelClass, operation, organisationId, contractId, recordCreatedBy):
+ """
+ Kombiniert System-RBAC + Feature-Level RBAC.
+
+ 1. Prüft System-RBAC (AccessLevel: ALL, GROUP, MY, NONE)
+ 2. Bei ALL: Bypass Feature-Level (SysAdmin)
+ 3. Sonst: Prüft TrusteeAccess für User + Organisation + Contract
+ """
+
+ # Stufe 1: System-RBAC
+ accessLevel = self.getRbacAccessLevel(modelClass, operation)
+ if accessLevel == AccessLevel.NONE:
+ return False
+ if accessLevel == AccessLevel.ALL:
+ return True # SysAdmin bypass
+
+ # Stufe 2: Feature-RBAC via TrusteeAccess
+ roles = self.getUserTrusteeRoles(self.userId, organisationId, contractId)
+
+ if "admin" in roles:
+ return True
+ if "operate" in roles and modelClass in (TrusteeContract, TrusteeDocument, ...):
+ return True
+ if "userreport" in roles and recordCreatedBy == self.userId:
+ return True
+
+ return False
+```
+
+### 3.3 Automatische Filterung
+
+Die Methode `filterRecordsByTrusteeAccess()` filtert Ergebnisse basierend auf User-Zugriff:
+
+```python
+def filterRecordsByTrusteeAccess(self, records, modelClass):
+ """
+ Filtert Records basierend auf TrusteeAccess des Users.
+
+ - admin: Sieht alle Records der Organisation
+ - operate: Sieht alle Records der Organisation
+ - userreport: Sieht nur eigene Records (_createdBy = userId)
+ """
+```
+
+---
+
+## 4. Generisches Muster für andere Features
+
+### 4.1 Feature-Isolation-Pattern
+
+Jedes Feature kann sein eigenes Isolationsmodell definieren:
+
+```
+{Feature}Access: User → {Isolationsobjekt} → Role [→ Unter-Objekt]
+```
+
+### 4.2 Beispiele für andere Features
+
+| Feature | Access-Tabelle | Isolationsobjekt | Unter-Objekt |
+|---------|----------------|------------------|--------------|
+| **Trustee** | `TrusteeAccess` | Organisation (Kunde) | Contract |
+| **RealEstate** | `RealEstateAccess` | Property (Liegenschaft) | Unit (Wohnung) |
+| **ProjectMgmt** | `ProjectAccess` | Project | - |
+| **Accounting** | `AccountingAccess` | Company | FiscalYear |
+
+### 4.3 Implementierungsvorlage
+
+Für ein neues Feature mit Isolation:
+
+1. **Datamodel**: `{Feature}Access` mit `userId`, `{isolationObject}Id`, `roleId`
+2. **Interface**: `checkCombinedPermission()` und `filterRecordsByAccess()`
+3. **Routes**: CRUD für `{Feature}Access`
+4. **Roles**: Feature-spezifische Rollen definieren
+
+---
+
+## 5. API-Referenz für UI-Entwicklung
+
+### 5.1 Access-Verwaltung (User-Zuweisung zu Kunden)
+
+```
+# Alle Access-Records abrufen
+GET /api/trustee/{instanceId}/access
+
+# Access für bestimmte Organisation
+GET /api/trustee/{instanceId}/access/organisation/{orgId}
+
+# Access für bestimmten User
+GET /api/trustee/{instanceId}/access/user/{userId}
+
+# Neuen Access erstellen (User zu Kunde zuweisen)
+POST /api/trustee/{instanceId}/access
+Body: {
+ "userId": "user-uuid",
+ "organisationId": "kunde-id",
+ "roleId": "operate",
+ "contractId": null // Optional
+}
+
+# Access aktualisieren
+PUT /api/trustee/{instanceId}/access/{accessId}
+
+# Access löschen
+DELETE /api/trustee/{instanceId}/access/{accessId}
+```
+
+### 5.2 Options-Endpoints für Dropdowns
+
+```
+# Organisationen für Dropdown
+GET /api/trustee/{instanceId}/organisations/options
+→ [{ "value": "org-id", "label": "Kunde AG" }, ...]
+
+# Rollen für Dropdown
+GET /api/trustee/{instanceId}/roles/options
+→ [{ "value": "admin", "label": "Administrator" }, ...]
+
+# Contracts für Dropdown (dynamisch nach Organisation)
+GET /api/trustee/{instanceId}/contracts/options
+→ [{ "value": "contract-uuid", "label": "Vertrag 2026" }, ...]
+
+# Users für Dropdown (aus aktuellem Mandate)
+GET /api/users/options
+→ [{ "value": "user-uuid", "label": "Max Muster" }, ...]
+```
+
+---
+
+## 6. UI-Anforderungen
+
+### 6.1 Access-View (User-Verwaltung)
+
+Eine View zur Verwaltung der User-Zuweisungen:
+
+| Spalte | Typ | Quelle |
+|--------|-----|--------|
+| User | Select | `/api/users/options` |
+| Organisation | Select | `/api/trustee/{instanceId}/organisations/options` |
+| Rolle | Select | `/api/trustee/{instanceId}/roles/options` |
+| Contract | Select (optional) | `/api/trustee/{instanceId}/contracts/options` |
+
+**Hinweis**: Das `contractId` Dropdown sollte dynamisch nach Auswahl der Organisation gefiltert werden.
+
+### 6.2 Berechtigungen für Access-View
+
+- **Sichtbar für**: Feature-Admins (`admin` Rolle in mindestens einer Organisation)
+- **Create/Update/Delete**: Nur für Organisationen, in denen User Admin ist
+
+---
+
+## 7. Offene Punkte / Entscheidungen
+
+### 7.1 Geklärt
+
+- [x] Ist das Gateway bereit? → **Ja**
+- [x] Sind Feature-spezifische Rollen gleich wie System-Rollen? → **Nein, bewusst getrennt**
+- [x] Ist zweistufiges RBAC nötig? → **Ja, bereits implementiert**
+- [x] Existiert der Users-Options-Endpoint? → **Ja, `/api/users/options`**
+
+### 7.2 Offen für UI-Review
+
+- [ ] Soll die Access-View eine eigene Seite sein oder Tab in Organisation?
+- [ ] Wie wird Contract-Dropdown bei organisationId-Änderung aktualisiert?
+- [ ] Braucht es eine "Bulk-Zuweisung" (User zu mehreren Orgs gleichzeitig)?
+
+---
+
+## 8. Zusammenfassung
+
+### Das Gateway bietet:
+
+1. **Vollständige CRUD-Routes** für alle Trustee-Entities
+2. **Zwei-Stufen-RBAC** (System + Feature-Level)
+3. **Automatische Filterung** basierend auf User-Access
+4. **Options-Endpoints** für alle Dropdowns
+
+### Das UI muss implementieren:
+
+1. **Access-View** zur Verwaltung von User-Zuweisungen
+2. **Dynamische Dropdowns** mit Abhängigkeiten (Contract nach Organisation)
+3. **instanceId** in allen API-Calls verwenden
+
+### Architektur-Prinzip:
+
+```
+System-RBAC → Zugang zum Feature
+Feature-RBAC → Isolation innerhalb des Features
+```
+
+---
+
+## 9. Implementierungsplan: Fehlende Elemente
+
+### 9.1 Aktueller Stand (Analyse)
+
+| Komponente | Status | Details |
+|------------|--------|---------|
+| **Gateway (Backend)** | ✅ Komplett | Routes, Interface, Datamodel, RBAC |
+| **API Hooks** (`useTrustee.ts`) | ✅ Komplett | CRUD-Hooks für alle Entities |
+| **API Client** (`trusteeApi.ts`) | ✅ Komplett | Alle Endpoints implementiert |
+| **Views (Grundgerüst)** | ⚠️ Teilweise | Tabellen existieren, aber ohne Forms |
+| **Create/Edit Formulare** | ❌ Fehlt | Buttons vorhanden, aber ohne Funktion |
+| **Label-Auflösung** | ❌ Fehlt | Zeigt IDs statt Labels (userId, orgId) |
+| **Dynamische Dropdowns** | ❌ Fehlt | Contract abhängig von Organisation |
+
+### 9.2 Fehlende Implementierungen
+
+#### P1: Create/Edit Formulare für alle Views
+
+**Problem:** Die "Neu erstellen" und "Bearbeiten" Buttons existieren, aber öffnen kein Formular.
+
+**Betroffene Views:**
+- `TrusteeOrganisationsView.tsx`
+- `TrusteeRolesView.tsx`
+- `TrusteeAccessView.tsx`
+- `TrusteeContractsView.tsx`
+- `TrusteeDocumentsView.tsx`
+- `TrusteePositionsView.tsx`
+
+**Lösung:** Pro View ein Modal mit EditForm implementieren, das die automatisch generierten Felder aus `generateEditFieldsFromAttributes()` verwendet.
+
+**Beispiel-Pattern:**
+
+```tsx
+// In TrusteeOrganisationsView.tsx
+const [isModalOpen, setIsModalOpen] = useState(false);
+const [editingItem, setEditingItem] = useState(null);
+const { generateCreateFieldsFromAttributes, generateEditFieldsFromAttributes } = useTrusteeOrganisations();
+const { handleCreate, handleUpdate } = useTrusteeOrganisationOperations();
+
+// Create-Button
+
+
+// Edit-Button
+
+
+// Modal mit EditForm
+ setIsModalOpen(false)}>
+ {
+ if (editingItem) {
+ await handleUpdate(editingItem.id, data);
+ } else {
+ await handleCreate(data);
+ }
+ setIsModalOpen(false);
+ refetch();
+ }}
+ />
+
+```
+
+---
+
+#### P2: Label-Auflösung für Foreign Keys
+
+**Problem:** `TrusteeAccessView` zeigt:
+- `userId: "uuid-123"` statt `"Max Muster"`
+- `organisationId: "org-1"` statt `"Kunde AG"`
+- `roleId: "admin"` statt `"Administrator"`
+
+**Lösung:** Options aus den entsprechenden Endpoints laden und als Lookup-Map verwenden.
+
+**Implementierung:**
+
+```tsx
+// In TrusteeAccessView.tsx
+const [userOptions, setUserOptions] = useState<{value: string, label: string}[]>([]);
+const [orgOptions, setOrgOptions] = useState<{value: string, label: string}[]>([]);
+const [roleOptions, setRoleOptions] = useState<{value: string, label: string}[]>([]);
+
+useEffect(() => {
+ const loadOptions = async () => {
+ const [users, orgs, roles] = await Promise.all([
+ api.get('/api/users/options'),
+ api.get(`/api/trustee/${instanceId}/organisations/options`),
+ api.get(`/api/trustee/${instanceId}/roles/options`)
+ ]);
+ setUserOptions(users.data);
+ setOrgOptions(orgs.data);
+ setRoleOptions(roles.data);
+ };
+ loadOptions();
+}, [instanceId]);
+
+// Lookup-Funktion
+const getLabel = (options: {value: string, label: string}[], value: string) =>
+ options.find(o => o.value === value)?.label || value;
+
+// In der Tabelle
+| {getLabel(userOptions, access.userId)} |
+{getLabel(orgOptions, access.organisationId)} |
+{getLabel(roleOptions, access.roleId)} |
+```
+
+---
+
+#### P3: Dynamische Dropdown-Filterung
+
+**Problem:** Im AccessView/ContractView soll das Contract-Dropdown nur Contracts der ausgewählten Organisation zeigen.
+
+**Lösung:** `dependsOn`-Attribut im Datamodel nutzen + dynamisches Nachladen.
+
+**Implementierung im EditForm:**
+
+```tsx
+// Wenn organisationId geändert wird, Contracts neu laden
+const handleFieldChange = async (fieldKey: string, value: any) => {
+ setFormData(prev => ({ ...prev, [fieldKey]: value }));
+
+ // Dynamische Abhängigkeiten prüfen
+ const dependentFields = fields.filter(f => f.dependsOn === fieldKey);
+ for (const depField of dependentFields) {
+ if (depField.optionsReference?.includes('contracts')) {
+ // Contracts für diese Organisation laden
+ const contracts = await api.get(
+ `/api/trustee/${instanceId}/contracts/options?organisationId=${value}`
+ );
+ // Options aktualisieren...
+ }
+ }
+};
+```
+
+**Backend-Erweiterung nötig:** Der `/contracts/options` Endpoint muss einen `organisationId` Query-Parameter unterstützen.
+
+---
+
+#### P4: Generischer Options-Hook
+
+**Problem:** Options-Laden ist in jeder View dupliziert.
+
+**Lösung:** Zentraler Hook für Trustee-Options.
+
+```tsx
+// hooks/useTrusteeOptions.ts
+export function useTrusteeOptions() {
+ const instanceId = useInstanceId();
+ const [options, setOptions] = useState({});
+
+ const loadOptions = useCallback(async (entity: 'organisations' | 'roles' | 'contracts' | 'users') => {
+ if (entity === 'users') {
+ const res = await api.get('/api/users/options');
+ setOptions(prev => ({ ...prev, users: res.data }));
+ } else {
+ const res = await api.get(`/api/trustee/${instanceId}/${entity}/options`);
+ setOptions(prev => ({ ...prev, [entity]: res.data }));
+ }
+ }, [instanceId]);
+
+ const getLabel = useCallback((entity: string, value: string) => {
+ return options[entity]?.find(o => o.value === value)?.label || value;
+ }, [options]);
+
+ return { options, loadOptions, getLabel };
+}
+```
+
+---
+
+### 9.3 Implementierungsreihenfolge
+
+| Phase | Aufgabe | Aufwand | Priorität |
+|-------|---------|---------|-----------|
+| **1** | `useTrusteeOptions` Hook erstellen | 2h | Hoch |
+| **2** | Label-Auflösung in allen Views | 3h | Hoch |
+| **3** | Create/Edit Modal in `TrusteeOrganisationsView` | 3h | Hoch |
+| **4** | Create/Edit Modal für alle anderen Views kopieren | 4h | Mittel |
+| **5** | Dynamische Contract-Filterung | 2h | Mittel |
+| **6** | Backend: `/contracts/options?organisationId=` | 1h | Mittel |
+| **7** | Position-Document Verknüpfungs-UI | 4h | Niedrig |
+| **8** | Testing & Bugfixes | 4h | Hoch |
+
+**Geschätzter Gesamtaufwand:** ~23h (3-4 Arbeitstage)
+
+---
+
+### 9.4 Detailplan Phase 1-3 (MVP)
+
+#### Schritt 1: `useTrusteeOptions` Hook
+
+**Datei:** `frontend_nyla/src/hooks/useTrusteeOptions.ts`
+
+```typescript
+/**
+ * Hook für Trustee-Options (Dropdowns, Label-Auflösung)
+ */
+import { useState, useCallback, useEffect } from 'react';
+import api from '../api';
+import { useInstanceId } from './useCurrentInstance';
+
+interface Option {
+ value: string;
+ label: string;
+}
+
+interface TrusteeOptions {
+ users: Option[];
+ organisations: Option[];
+ roles: Option[];
+ contracts: Option[];
+ documents: Option[];
+ positions: Option[];
+}
+
+export function useTrusteeOptions(autoLoad: (keyof TrusteeOptions)[] = []) {
+ const instanceId = useInstanceId();
+ const [options, setOptions] = useState>({});
+ const [loading, setLoading] = useState(false);
+
+ const loadOptions = useCallback(async (
+ entities: (keyof TrusteeOptions)[],
+ filters?: { organisationId?: string }
+ ) => {
+ if (!instanceId) return;
+ setLoading(true);
+
+ try {
+ const promises = entities.map(async (entity) => {
+ let url: string;
+ if (entity === 'users') {
+ url = '/api/users/options';
+ } else {
+ url = `/api/trustee/${instanceId}/${entity}/options`;
+ if (filters?.organisationId && entity === 'contracts') {
+ url += `?organisationId=${filters.organisationId}`;
+ }
+ }
+ const res = await api.get(url);
+ return { entity, data: res.data };
+ });
+
+ const results = await Promise.all(promises);
+ const newOptions: Partial = {};
+ results.forEach(({ entity, data }) => {
+ newOptions[entity] = data;
+ });
+ setOptions(prev => ({ ...prev, ...newOptions }));
+ } finally {
+ setLoading(false);
+ }
+ }, [instanceId]);
+
+ const getLabel = useCallback((entity: keyof TrusteeOptions, value: string): string => {
+ return options[entity]?.find(o => o.value === value)?.label || value;
+ }, [options]);
+
+ // Auto-Load bei Mount
+ useEffect(() => {
+ if (autoLoad.length > 0 && instanceId) {
+ loadOptions(autoLoad);
+ }
+ }, [instanceId, autoLoad.join(',')]);
+
+ return { options, loadOptions, getLabel, loading };
+}
+```
+
+#### Schritt 2: TrusteeAccessView mit Labels
+
+**Datei:** `frontend_nyla/src/pages/views/trustee/TrusteeAccessView.tsx`
+
+- Import `useTrusteeOptions`
+- Auto-Load: `['users', 'organisations', 'roles']`
+- Tabelle: `getLabel()` für userId, organisationId, roleId
+
+#### Schritt 3: Create/Edit Modal
+
+**Ansatz:** Bestehende `EditPopup`-Komponente aus anderen Views (z.B. Prompts) wiederverwenden.
+
+**Dateien:**
+- `TrusteeOrganisationsView.tsx` - Modal hinzufügen
+- Nutzt `generateCreateFieldsFromAttributes()` für Feld-Definitionen
+- `handleCreate()` / `handleUpdate()` für API-Calls
+
+---
+
+### 9.5 Backend-Erweiterung (optional)
+
+Für dynamische Contract-Filterung nach Organisation:
+
+**Datei:** `gateway/modules/features/trustee/routeFeatureTrustee.py`
+
+```python
+@router.get("/{instanceId}/contracts/options", response_model=List[Dict[str, Any]])
+async def getContractOptions(
+ request: Request,
+ instanceId: str = Path(...),
+ organisationId: Optional[str] = Query(None), # NEU
+ context: RequestContext = Depends(getRequestContext)
+) -> List[Dict[str, Any]]:
+ """Get contract options, optionally filtered by organisation."""
+ mandateId = await _validateInstanceAccess(instanceId, context)
+ interface = getInterface(context.user, mandateId=mandateId, featureInstanceId=instanceId)
+
+ if organisationId:
+ contracts = interface.getContractsByOrganisation(organisationId)
+ else:
+ result = interface.getAllContracts(None)
+ contracts = result.items if hasattr(result, 'items') else result
+
+ return [{"value": c.id, "label": c.label or c.name or c.id} for c in contracts]
+```
+
+---
+
+### 9.6 Offene Entscheidungen für Review
+
+| # | Frage | Optionen |
+|---|-------|----------|
+| 1 | **Modal vs. Inline-Edit** | A) Modal-Dialog / B) Inline in Tabelle / C) Separate Seite |
+| 2 | **Bulk-Operationen** | A) Ja, Multi-Select + Batch-Aktionen / B) Nein, nur einzeln |
+| 3 | **Position-Document UI** | A) Separate View / B) Inline in Position-View / C) Beides |
+| 4 | **Validierung** | A) Client-only / B) Server-only / C) Beides |
+
+---
+
+**Dokumentversion**: 1.1
+**Letzte Aktualisierung**: 2026-01-23
+**Autor**: Claude (AI-Assistent)
+**Status**: Zur Überprüfung