From b1e63d758ef6d6abfba33913a116587f26ef595f Mon Sep 17 00:00:00 2001
From: ValueOn AG
Date: Wed, 21 Jan 2026 15:57:34 +0100
Subject: [PATCH] 4 not 5 admin parts for roles
---
.../admin_ui_concept.md | 255 ++++++++++++++++++
1 file changed, 255 insertions(+)
create mode 100644 implementation/Saas Multi Tenant Mandate/admin_ui_concept.md
diff --git a/implementation/Saas Multi Tenant Mandate/admin_ui_concept.md b/implementation/Saas Multi Tenant Mandate/admin_ui_concept.md
new file mode 100644
index 0000000..134ea9d
--- /dev/null
+++ b/implementation/Saas Multi Tenant Mandate/admin_ui_concept.md
@@ -0,0 +1,255 @@
+# Admin UI Konzept - Rollen- und Benutzerverwaltung
+
+**Version:** 1.0
+**Datum:** 21. Januar 2026
+**Status:** Entwurf
+**Basis:** [mandate_implementation_gateway.md](./mandate_implementation_gateway.md)
+
+---
+
+## Übersicht
+
+Dieses Dokument definiert die Admin-UI-Struktur für die Verwaltung von Rollen, Mandanten und Feature-Zugriffen im Multi-Tenant-System.
+
+### Rollen-Kontexte (4 Ebenen)
+
+| Kontext | mandateId | featureInstanceId | featureCode | isSystemRole | Beispiele |
+|---------|-----------|-------------------|-------------|--------------|-----------|
+| **SYSTEM** | null | null | null | true | admin, user, viewer |
+| **TEMPLATE** | null | null | X (z.B. "trustee") | false | trustee-admin, chatbot-user |
+| **MANDATE** | X | null | null | false | Mandant-spezifische Rollen |
+| **INSTANCE** | X | Y | - | false | Instanz-spezifische Rollen |
+
+**Wichtig:** Der Kontext einer Rolle (mandateId, featureInstanceId, featureCode) ist **IMMUTABLE** nach Erstellung!
+
+---
+
+## Admin-Workflow (4 Schritte)
+
+### Schritt 1: Rollen verwalten
+
+**Seite:** `Rollen`
+**Sicht:** Konsolidierte Liste (System + Global + Mandant-spezifisch)
+**Inhalt:** Alle Rollen die Mandanten-Mitgliedern zugewiesen werden können
+
+| Feld | Beschreibung |
+|------|--------------|
+| roleLabel | Rollen-Name |
+| description | Beschreibung (mehrsprachig) |
+| mandateId | null (global/system) oder Mandant-ID (spezifisch) |
+| Scope | Badge-Anzeige: "System", "Global" oder "Mandant" |
+
+**Rollen-Typen:**
+- **System-Rollen** (admin, user, viewer): `isSystemRole=true` - können nicht gelöscht werden, nur Beschreibung editierbar
+- **Globale Rollen** (mandateId=null, isSystemRole=false): Gelten für alle Mandanten
+- **Mandant-Rollen** (mandateId=xyz): Gelten nur für einen spezifischen Mandanten
+
+**Filter:** `featureCode=null AND featureInstanceId=null`
+
+**Aktionen:**
+- Neue globale Rolle erstellen (Scope: "Global")
+- Neue mandant-spezifische Rolle erstellen (Scope: "Mandant")
+- Rolle bearbeiten (nur Beschreibung) - **nicht für System-Rollen!**
+- Rolle löschen - **nicht für System-Rollen!**
+
+---
+
+**Seite:** `Mandanten-Mitglieder`
+**Sicht:** Pro Mandant (Dropdown-Auswahl)
+**Inhalt:** Benutzer die dem Mandanten zugeordnet sind
+
+| Feld | Beschreibung |
+|------|--------------|
+| Benutzer | Username, E-Mail |
+| Rollen | Zugewiesene Mandate-Rollen |
+| Aktiv | enabled Flag |
+
+**Datenmodell:**
+```
+User ─► UserMandate ─► Mandate
+ │
+ └─► UserMandateRole ─► Role
+```
+
+**Aktionen:**
+- Benutzer zum Mandanten hinzufügen (+ Rollen zuweisen)
+- Rollen eines Mitglieds bearbeiten
+- Mitglied entfernen
+
+---
+
+### Schritt 2: Feature-Template-Rollen bearbeiten
+
+**Seite:** `Feature-Rollen`
+**Sicht:** Pro Feature (Dropdown: Trustee, Chatbot, Workflow, etc.)
+**Inhalt:** Template-Rollen für das ausgewählte Feature
+
+| Feld | Beschreibung |
+|------|--------------|
+| roleLabel | Rollen-Name (z.B. trustee-admin) |
+| description | Beschreibung |
+| featureCode | Feature-Code (readonly) |
+| AccessRules | Verknüpfte Berechtigungen |
+
+**Filter:** `featureCode=X AND mandateId=null AND featureInstanceId=null`
+
+**Beispiel-Rollen pro Feature:**
+
+| Feature | Rollen |
+|---------|--------|
+| trustee | trustee-admin, trustee-accountant, trustee-client |
+| chatbot | chatbot-admin, chatbot-user |
+| chatworkflow | workflow-admin, workflow-editor, workflow-viewer |
+| neutralization | neutralization-admin, neutralization-analyst |
+| realestate | realestate-admin, realestate-manager, realestate-viewer |
+
+**Aktionen:**
+- Neue Feature-Rolle erstellen
+- Beschreibung bearbeiten
+- AccessRules verwalten (welche Tabellen mit welchen Berechtigungen)
+- Rolle löschen
+
+---
+
+### Schritt 3: Feature-Instanzen an Mandanten zuweisen
+
+**Seite:** `Feature-Instanzen`
+**Sicht:** Pro Mandant (Dropdown-Auswahl)
+**Inhalt:** Feature-Instanzen die dem Mandanten zugeordnet sind
+
+| Feld | Beschreibung |
+|------|--------------|
+| Feature | Feature-Typ (Trustee, Chatbot, etc.) |
+| Instanz-Name | Label der Instanz |
+| Erstellt | Erstellungsdatum |
+| Benutzer | Anzahl zugewiesener Benutzer |
+
+**Datenmodell:**
+```
+Mandate ─► FeatureInstance ─► Feature
+```
+
+**Aktionen:**
+- Neue Feature-Instanz für Mandant erstellen
+- Instanz umbenennen
+- Instanz deaktivieren/löschen
+
+---
+
+### Schritt 4: Feature-Instanz Benutzer zuweisen
+
+**Seite:** `Feature-Benutzer`
+**Sicht:** Kombinierte Auswahl (Mandant + Feature-Instanz)
+**UI:** Zwei Dropdowns - Mandant wählen → Feature-Instanz wählen
+**Inhalt:** Benutzer mit Zugriff auf die ausgewählte Feature-Instanz
+
+| Feld | Beschreibung |
+|------|--------------|
+| Benutzer | Username, E-Mail (nur Mandanten-Mitglieder!) |
+| Rollen | Zugewiesene Feature-Rollen |
+| Aktiv | enabled Flag |
+
+**Datenmodell:**
+```
+User ─► FeatureAccess ─► FeatureInstance
+ │
+ └─► FeatureAccessRole ─► Role (Template-Rollen)
+```
+
+**Wichtig:**
+- Nur Benutzer die bereits Mandanten-Mitglieder sind können ausgewählt werden
+- Rollen-Auswahl zeigt nur Feature-spezifische Template-Rollen
+
+**Aktionen:**
+- Benutzer zur Feature-Instanz hinzufügen (+ Rollen zuweisen)
+- Rollen eines Benutzers bearbeiten
+- Benutzer-Zugriff entfernen
+
+---
+
+## Navigation Struktur
+
+```
+ADMINISTRATION
+├── Benutzer (User-CRUD)
+├── Einladungen (Invitation-Management)
+├── Mandanten (Mandate-CRUD)
+├── Rollen (Schritt 1 - System + Global + Mandant)
+├── Mandanten-Mitglieder (Schritt 1 - Benutzer zuweisen)
+├── Feature-Rollen (Schritt 2)
+├── Feature-Instanzen (Schritt 3)
+└── Feature-Benutzer (Schritt 4)
+```
+
+---
+
+## Berechtigungsfluss (Zusammenfassung)
+
+```
+ ┌─────────────────┐
+ │ User-Login │
+ └────────┬────────┘
+ │
+ ┌──────────────┼──────────────┐
+ │ │ │
+ ▼ ▼ ▼
+ ┌──────────┐ ┌──────────┐ ┌──────────┐
+ │ SysAdmin │ │ Mandate │ │ Feature │
+ │ Flag │ │ Member │ │ Access │
+ └────┬─────┘ └────┬─────┘ └────┬─────┘
+ │ │ │
+ │ │ │
+ ▼ ▼ ▼
+ ┌─────────┐ ┌──────────┐ ┌──────────┐
+ │ Alle │ │ Mandate │ │ Feature │
+ │ Rechte │ │ Roles │ │ Roles │
+ └─────────┘ └────┬─────┘ └────┬─────┘
+ │ │
+ └──────┬───────┘
+ │
+ ▼
+ ┌──────────┐
+ │ Access │
+ │ Rules │
+ └──────────┘
+```
+
+---
+
+## Technische Hinweise
+
+### Immutable Kontext-Felder
+
+Die folgenden Felder einer Rolle können nach Erstellung **NICHT** geändert werden:
+- `mandateId`
+- `featureInstanceId`
+- `featureCode`
+
+**Grund:** Diese Felder definieren den Kontext der Rolle. Eine Änderung würde die Semantik der Rolle ändern und könnte zu Sicherheitsproblemen führen.
+
+**UI-Konsequenz:** Diese Felder werden bei Bearbeitung als readonly angezeigt. Um den Kontext zu ändern, muss eine neue Rolle erstellt werden.
+
+### Junction Tables für CASCADE DELETE
+
+```
+UserMandate ──► UserMandateRole ──► Role
+FeatureAccess ──► FeatureAccessRole ──► Role
+```
+
+Beim Löschen einer Rolle werden automatisch alle Junction-Einträge gelöscht (CASCADE).
+
+### API Endpoints (Referenz)
+
+| Aktion | Endpoint |
+|--------|----------|
+| Alle Rollen (für Mandant) | `GET /api/rbac/roles?mandateId={id}&includeTemplates=true` |
+| Feature-Template-Rollen | `GET /api/features/templates/roles?featureCode={code}` |
+| Feature-Instanz-Benutzer | `GET /api/features/instances/{id}/users` |
+
+---
+
+## Änderungshistorie
+
+| Version | Datum | Autor | Änderung |
+|---------|-------|-------|----------|
+| 1.0 | 21.01.2026 | System | Initiale Version |