This commit is contained in:
ValueOn AG 2026-01-20 08:39:25 +01:00
parent 5690e64dba
commit b0ffd52556

View file

@ -0,0 +1,846 @@
# Multi-Tenant Implementation Analysis - Frontend Nyla
**Version:** 1.1
**Datum:** 20. Januar 2026
**Basis:** `mandate_implementation_ui_myla.md` (Konzept) & `mandate_implementation_gateway.md` (Backend)
---
## 1. Zusammenfassung
Dieses Dokument analysiert den Implementierungsstand des Multi-Tenant-Systems im Frontend Nyla und vergleicht es mit dem Konzeptdokument. Es enthält:
- Was implementiert ist ✅
- Was teilweise implementiert ist ⚠️
- Was noch fehlt ❌
- Strukturempfehlungen für die Integration
---
## 2. Implementierungsstand - Übersicht
| Komponente | Status | Details |
|------------|--------|---------|
| **Core Types** | ✅ Implementiert | `types/mandate.ts` - vollständig |
| **Feature Store** | ✅ Implementiert | `stores/featureStore.tsx` - React Context-basiert |
| **useCurrentInstance Hook** | ✅ Implementiert | URL-basierte Instanz-Auflösung |
| **Instance Permission Hooks** | ✅ Implementiert | `useInstancePermissions.tsx` |
| **Permission Gate Component** | ✅ Implementiert | Conditional Rendering |
| **Mandate Navigation** | ✅ Implementiert | Hierarchische Tree-Navigation |
| **Features API** | ✅ Implementiert | `featuresApi.ts` mit `/api/features/my` |
| **URL-Struktur** | ✅ Implementiert | `/mandates/:mandateId/:featureCode/:instanceId/*` |
| **Invitation Flow** | ✅ Implementiert | `InvitePage.tsx` + `useInvitations.ts` |
| **Admin: Mandates** | ✅ Implementiert | `AdminMandatesPage.tsx` |
| **Admin: Users** | ✅ Implementiert | `AdminUsersPage.tsx` |
| **Admin: Roles** | ✅ Implementiert | `AdminRolesPage.tsx` |
| **Admin: Mandate Roles** | ✅ Implementiert | `AdminMandateRolesPage.tsx` |
| **Admin: Invitations** | ✅ Implementiert | `AdminInvitationsPage.tsx` |
| **Admin: Feature Access** | ✅ Implementiert | `AdminFeatureAccessPage.tsx` |
| **Admin: User Mandates** | ✅ Implementiert | `AdminUserMandatesPage.tsx` |
| **AccessRules Editor** | ✅ Implementiert | `components/AccessRules/AccessRulesEditor.tsx` |
| **RBAC Export/Import** | ✅ Implementiert | `components/RbacExportImport/RbacExportImport.tsx` |
| **Mandate-Admin Section per Mandate** | ⚠️ Teilweise | Nur global, nicht pro Mandant |
---
## 3. Detaillierte Analyse
### 3.1 Core Architecture ✅
#### Types (`src/types/mandate.ts`)
**Status: Vollständig implementiert**
```typescript
// Implementiert gemäss Konzept:
- I18nLabel
- AccessLevel ('n' | 'm' | 'g' | 'a')
- TablePermission
- FieldPermission
- InstancePermissions
- FeatureInstance
- MandateFeature
- Mandate
- FeaturesMyResponse
- User (ohne mandateId!)
- FEATURE_REGISTRY
```
**Korrekte Umsetzung der Konzept-Prinzipien:**
- User hat KEINE `mandateId` mehr
- Permissions sind summarisch pro Instanz
- Hierarchie: `Mandate → Feature → Instance → Views`
---
### 3.2 Feature Store ✅
**Datei:** `src/stores/featureStore.tsx`
**Status: Vollständig implementiert als React Context**
| Konzept-Anforderung | Implementiert |
|---------------------|---------------|
| `loadFeatures()` | ✅ Lädt von `/api/features/my` |
| `setFeatures()` | ✅ Direktes Setzen nach Login |
| `getMandateById()` | ✅ |
| `getFeatureByCode()` | ✅ |
| `getInstanceById()` | ✅ Mit Cache-Map für Performance |
| `getAllInstances()` | ✅ |
| `hasAnyInstance()` | ✅ |
| `reset()` | ✅ Für Logout |
**Abweichung vom Konzept:**
- Konzept: Zustand-basiert (Zustand Library)
- Implementiert: React Context + useState + useRef für Cache
**Bewertung:** Funktional äquivalent, React Context ist für die Anwendungsgrösse angemessen.
---
### 3.3 useCurrentInstance Hook ✅
**Datei:** `src/hooks/useCurrentInstance.ts`
**Status: Vollständig implementiert**
```typescript
// Exportierte Hooks:
- useCurrentInstance() // Vollständiger Kontext
- useInstance() // Nur Instanz
- useInstanceId() // Nur ID
- useFeatureCode() // Nur Feature-Code
- useMandateId() // Nur Mandate-ID
- useIsInFeatureContext() // Boolean Check
```
**Korrekte Umsetzung:**
- Liest Parameter aus URL (`useParams`)
- Validiert Konsistenz (Instanz gehört zu Mandate/Feature)
- Keine Speicherung im globalen State
---
### 3.4 Permission System ✅
**Dateien:**
- `src/hooks/useInstancePermissions.tsx`
- `src/hooks/usePermissions.ts`
#### Instance-basierte Permissions ✅
| Hook | Status | Verwendung |
|------|--------|------------|
| `useTablePermission(tableName)` | ✅ | CRUD-Checks auf Tabellen |
| `useCanViewTable(tableName)` | ✅ | View-Check |
| `useCanViewFeatureView(viewCode)` | ✅ | Navigation-Filterung |
| `useViewPermissions(viewCodes[])` | ✅ | Bulk View-Checks |
| `useFieldPermission(table, field)` | ✅ | Feld-Level Checks |
| `useInstancePermissions()` | ✅ | Raw Permissions-Objekt |
| `useCanEditRecord()` | ✅ | Record-basierte Prüfung |
| `useCanDeleteRecord()` | ✅ | Record-basierte Prüfung |
#### PermissionGate Component ✅
```tsx
<PermissionGate table="TrusteeContract" action="create">
<Button>Neuer Vertrag</Button>
</PermissionGate>
<PermissionGate view="trustee-admin" fallback={<AccessDenied />}>
<AdminPanel />
</PermissionGate>
```
**Implementiert gemäss Konzept** - Conditional Rendering basierend auf Permissions.
---
### 3.5 Navigation ✅
**Datei:** `src/components/Navigation/MandateNavigation.tsx`
**Status: Vollständig implementiert**
**Struktur wie im Konzept:**
```
SYSTEM (immer)
○ Übersicht
○ Einstellungen
▼ Mandant: Soha Treuhand
├─▼ Feature: Trustee
│ ├─▼ Instanz: PamoCreate AG (mit Views)
│ └─▼ Instanz: ValueOn AG (mit Views)
└─▼ Feature: Workflow
└─▼ Instanz: Beratung Dynamic
─────────────────────────────
ADMINISTRATION (nur SysAdmin)
○ Mandanten
○ Benutzer
○ Globale Rollen
...
```
**Implementierte Features:**
- Hierarchische Tree-Navigation (`TreeNavigation`)
- Dynamische Icon-Zuordnung pro Feature
- Automatisches Filtern von Views basierend auf Permissions
- Admin-Sektion nur für `isSysAdmin`
- Empty State wenn keine Instanzen
---
### 3.6 URL-Struktur ✅
**Datei:** `src/App.tsx`
**Implementierte Routen:**
```
/ → Dashboard
/settings → Benutzer-Einstellungen
/mandates/:mandateId/:featureCode/:instanceId → Feature Layout
/dashboard → Feature Dashboard
/contracts → Verträge
/documents → Dokumente
/positions → Positionen
/organisations → Organisationen
/roles → Rollen
/access → Zugriffe
/runs → Workflow Runs
/files → Dateien
/conversations → Chat
/admin/mandates → Admin: Mandanten
/admin/users → Admin: Benutzer
/admin/roles → Admin: Globale Rollen
/admin/user-mandates → Admin: Mandanten-Mitglieder
/admin/feature-instances → Admin: Feature-Instanzen
/admin/invitations → Admin: Einladungen
/admin/mandate-roles → Admin: Mandanten-Rollen
/invite/:token → Einladungs-Annahme
/login, /register, /password-reset-request, /reset → Auth
```
**Korrekte Umsetzung der Konzept-URL-Struktur.**
---
### 3.7 Invitation Flow ✅
**Dateien:**
- `src/pages/InvitePage.tsx`
- `src/hooks/useInvitations.ts`
**Implementierte Funktionen:**
| Feature | Status |
|---------|--------|
| Token-Validierung | ✅ `validateInvitation(token)` |
| Einladung annehmen (auth) | ✅ `acceptInvitation(token)` |
| Registrieren + Annehmen | ✅ `registerAndAccept(data)` |
| Einladungen erstellen | ✅ `createInvitation()` |
| Einladungen widerrufen | ✅ `revokeInvitation()` |
| Einladungen auflisten | ✅ `fetchInvitations()` |
**InvitePage Features:**
- Token-Validierung beim Mount
- Unterscheidung: Eingeloggt vs. Nicht eingeloggt
- Registrierungsformular für neue User
- Login-Redirect für bestehende User
- Fehlerbehandlung für ungültige/abgelaufene Tokens
---
### 3.8 Admin Pages ✅
**Alle Admin-Seiten verwenden `FormGeneratorTable` und `FormGeneratorForm`.**
| Seite | Status | Funktionen |
|-------|--------|------------|
| `AdminMandatesPage` | ✅ | CRUD Mandanten, Table mit Pagination |
| `AdminUsersPage` | ✅ | CRUD Benutzer |
| `AdminRolesPage` | ✅ | CRUD Globale Rollen |
| `AdminMandateRolesPage` | ✅ | Rollen pro Mandant, Filter (global/mandate) |
| `AdminUserMandatesPage` | ✅ | User-Mandate-Zuordnungen |
| `AdminFeatureAccessPage` | ✅ | Feature-Instanz-Zugriffe |
| `AdminInvitationsPage` | ✅ | Einladungsverwaltung |
---
## 4. Neu Implementierte RBAC-Komponenten ✅
### 4.1 AccessRules Editor ✅
**Datei:** `src/components/AccessRules/AccessRulesEditor.tsx`
**Status: Vollständig implementiert**
Die Komponente ermöglicht die Bearbeitung von RBAC-Regeln pro Rolle mit Tabs für verschiedene Regel-Kontexte.
#### Komponenten-Struktur
```
src/components/AccessRules/
├── AccessRulesEditor.tsx // Hauptkomponente mit Tabs
├── AccessRules.module.css // Styles
├── AccessLevelSelect.tsx // Dropdown für n/m/g/a
└── index.ts
```
#### Verwendung
```tsx
import { AccessRulesEditor } from '../components/AccessRules';
// In einer Admin-Seite:
<AccessRulesEditor
roleId={selectedRole.id}
roleName={selectedRole.roleLabel}
isTemplate={true} // Optional: Template-Badge anzeigen
readOnly={false} // Optional: Nur-Lesen-Modus
onSave={() => refetchRoles()} // Optional: Callback nach Speichern
/>
```
#### Features
| Feature | Status |
|---------|--------|
| Tabs: DATA, UI, RESOURCE, JSON | ✅ |
| AccessLevel Dropdown (n/m/g/a) | ✅ |
| Regel hinzufügen | ✅ |
| Regel löschen | ✅ |
| Permissions-Grid (view, read, create, update, delete) | ✅ |
| JSON-Editor für Raw-Bearbeitung | ✅ |
| Speichern & Zurücksetzen | ✅ |
| Änderungstracking | ✅ |
| Read-Only Modus | ✅ |
#### API-Hook
```typescript
import { useAccessRules } from '../hooks/useAccessRules';
const {
rules, // Alle Regeln für die Rolle
loading, // Lade-Status
saving, // Speicher-Status
error, // Fehler-Nachricht
fetchRules, // Regeln laden
saveRules, // Regeln speichern (Bulk)
createRule, // Einzelne Regel erstellen
updateRule, // Einzelne Regel aktualisieren
deleteRule, // Einzelne Regel löschen
getGroupedRules, // Regeln nach Kontext gruppiert
} = useAccessRules(roleId);
```
---
### 4.2 RBAC Export/Import ✅
**Datei:** `src/components/RbacExportImport/RbacExportImport.tsx`
**Status: Vollständig implementiert**
Die Komponente ermöglicht Export und Import von RBAC-Konfigurationen.
#### Komponenten-Struktur
```
src/components/RbacExportImport/
├── RbacExportImport.tsx // Hauptkomponente
├── RbacExportImport.module.css // Styles
└── index.ts
```
#### Verwendung
```tsx
import { RbacExportImport } from '../components/RbacExportImport';
// Für Mandant:
<RbacExportImport
mandateId="mand-123"
mandateName="Soha Treuhand"
featureCode="trustee" // Optional: Nur für Feature
/>
// Für globale Templates (SysAdmin):
<RbacExportImport
isGlobal={true}
featureCode="trustee" // Optional
/>
```
#### Features
| Feature | Status |
|---------|--------|
| Export als JSON-Download | ✅ |
| Import via File-Upload | ✅ |
| Import-Modi: merge, replace, add_only | ✅ |
| Datei-Vorschau vor Import | ✅ |
| Import-Ergebnis-Anzeige | ✅ |
| Warnung bei Replace-Modus | ✅ |
| Fehlerbehandlung | ✅ |
#### Import-Modi
| Modus | Beschreibung |
|-------|--------------|
| `merge` | Bestehende aktualisieren, neue hinzufügen |
| `add_only` | Nur neue hinzufügen, bestehende unverändert |
| `replace` | Alle bestehenden löschen und ersetzen |
#### API-Hook
```typescript
import { useRbacExportImport } from '../hooks/useRbacExportImport';
const {
exporting, // Export läuft
importing, // Import läuft
error, // Fehler-Nachricht
lastExport, // Letzter Export
lastImportResult, // Letztes Import-Ergebnis
exportMandateRbac, // Export für Mandant
exportGlobalRbac, // Export für Templates
importMandateRbac, // Import in Mandant
importGlobalRbac, // Import in Templates
downloadExport, // JSON-Download auslösen
parseImportFile, // Datei parsen
} = useRbacExportImport();
```
---
### 4.3 Mandate-Admin Section pro Mandant ⚠️
**Konzept:**
```
▼ Mandant: Soha Treuhand
├─▼ Feature: Trustee
│ └─▼ Instanzen...
└─▼ ADMINISTRATION (nur Mandate-Admin)
○ Benutzer
○ Rollen
○ Berechtigungen
○ Feature-Instanzen
○ Einladungen
○ RBAC Export/Import
```
**Aktueller Stand:**
- Admin-Sektion existiert nur global unter `/admin/*`
- Kein Mandate-spezifischer Admin-Bereich in der Navigation
**Empfehlung:**
Die Navigation sollte pro Mandant einen Admin-Bereich anzeigen wenn der User `Mandate-Admin` Rolle hat.
---
## 5. FormGenerator Komponenten (statt GenericForm)
> **Hinweis:** Es gibt keine `GenericForm` Komponente im Codebase. Die generische Form-Funktionalität wird durch die **FormGenerator**-Komponenten bereitgestellt.
### 5.1 Verfügbare Komponenten
| Komponente | Pfad | Verwendung |
|------------|------|------------|
| `FormGeneratorForm` | `components/FormGenerator/FormGeneratorForm/` | Backend-driven Forms |
| `FormGeneratorTable` | `components/FormGenerator/FormGeneratorTable/` | Data Tables mit CRUD |
| `FormGeneratorList` | `components/FormGenerator/FormGeneratorList/` | Listen-Ansichten |
| `FormGeneratorControls` | `components/FormGenerator/FormGeneratorControls/` | Filter/Search UI |
### 5.2 FormGeneratorForm - Verwendung
```tsx
import { FormGeneratorForm, type AttributeDefinition } from '../components/FormGenerator/FormGeneratorForm';
// 1. Mit expliziten Attributen
const fields: AttributeDefinition[] = [
{ name: 'name', label: 'Name', type: 'string', required: true },
{ name: 'description', label: 'Beschreibung', type: 'textarea' },
{ name: 'enabled', label: 'Aktiv', type: 'boolean' },
{ name: 'role', label: 'Rolle', type: 'enum', options: [...] },
];
<FormGeneratorForm
attributes={fields}
data={initialData} // Optional: Für Edit-Mode
mode="create" // 'create' | 'edit' | 'display'
onSubmit={handleSubmit}
onCancel={handleCancel}
submitButtonText="Erstellen"
cancelButtonText="Abbrechen"
/>
// 2. Mit Backend-getriebenen Attributen (fetcht von /api/attributes/{entityType})
<FormGeneratorForm
entityType="TrusteeContract"
data={contract}
mode="edit"
onSubmit={handleUpdate}
/>
```
### 5.3 FormGeneratorTable - Verwendung
```tsx
import { FormGeneratorTable } from '../components/FormGenerator/FormGeneratorTable';
<FormGeneratorTable
data={contracts}
columns={[
{ key: 'name', label: 'Name', type: 'string', sortable: true },
{ key: 'status', label: 'Status', type: 'enum' },
]}
loading={isLoading}
pagination={true}
pageSize={25}
searchable={true}
filterable={true}
sortable={true}
actionButtons={[
{ type: 'edit', onAction: handleEdit },
{ type: 'delete', title: 'Löschen' },
]}
onDelete={handleDelete}
hookData={{
refetch,
permissions,
handleInlineUpdate,
}}
/>
```
### 5.4 Unterstützte Feld-Typen
| Type | Beschreibung | Input |
|------|--------------|-------|
| `string` | Text | `<input type="text">` |
| `textarea` | Mehrzeiliger Text | `<textarea>` |
| `integer` | Ganzzahl | `<input type="number">` |
| `float` | Dezimalzahl | `<input type="number">` |
| `boolean` | Ja/Nein | `<input type="checkbox">` |
| `enum` | Auswahl | `<select>` |
| `multiselect` | Mehrfachauswahl | Checkboxes |
| `date` | Datum | `<input type="date">` |
| `datetime` | Datum+Zeit | `<input type="datetime-local">` |
| `email` | E-Mail | `<input type="email">` |
| `url` | URL | `<input type="url">` |
| `file` | Datei | `<input type="file">` |
| `textmultilingual` | Mehrsprachig | Inputs pro Sprache |
---
## 6. Integrations-Empfehlungen
### 6.1 Neue Feature-View hinzufügen
**Schritt 1:** View-Komponente erstellen
```tsx
// src/pages/views/trustee/TrusteeNewView.tsx
import React from 'react';
import { useCurrentInstance } from '../../../hooks/useCurrentInstance';
import { useTablePermission } from '../../../hooks/useInstancePermissions';
import { FormGeneratorTable } from '../../../components/FormGenerator/FormGeneratorTable';
export const TrusteeNewView: React.FC = () => {
const { instance } = useCurrentInstance();
const { canCreate, canUpdate, canDelete } = useTablePermission('TrusteeNewTable');
// Daten laden...
return (
<div>
<h2>Neue View</h2>
<FormGeneratorTable ... />
</div>
);
};
```
**Schritt 2:** In `FEATURE_REGISTRY` registrieren
```typescript
// src/types/mandate.ts
export const FEATURE_REGISTRY: Record<string, FeatureConfig> = {
trustee: {
// ...
views: [
// Bestehende Views...
{ code: 'newview', label: { de: 'Neue View', en: 'New View' }, path: 'newview' },
]
},
};
```
**Schritt 3:** In `VIEW_COMPONENTS` registrieren
```tsx
// src/pages/FeatureView.tsx
import { TrusteeNewView } from './views/trustee/TrusteeNewView';
const VIEW_COMPONENTS: Record<string, Record<string, ViewComponent>> = {
trustee: {
// Bestehende Views...
newview: TrusteeNewView,
},
};
```
**Schritt 4:** Route hinzufügen
```tsx
// src/App.tsx
<Route path="newview" element={<FeatureViewPage view="newview" />} />
```
---
### 6.2 AccessRulesEditor in Admin-Seiten integrieren
**Beispiel: Integration in AdminRolesPage**
```tsx
// src/pages/admin/AdminRolesPage.tsx
import { useState } from 'react';
import { AccessRulesEditor } from '../../components/AccessRules';
export const AdminRolesPage: React.FC = () => {
const [selectedRole, setSelectedRole] = useState<Role | null>(null);
return (
<div className={styles.twoColumnLayout}>
{/* Linke Spalte: Rollen-Liste */}
<div className={styles.roleList}>
<FormGeneratorTable
data={roles}
columns={columns}
actionButtons={[
{ type: 'view', onAction: setSelectedRole },
]}
/>
</div>
{/* Rechte Spalte: AccessRules Editor */}
{selectedRole && (
<AccessRulesEditor
roleId={selectedRole.id}
roleName={selectedRole.roleLabel}
isTemplate={!selectedRole.mandateId}
onSave={() => refetch()}
/>
)}
</div>
);
};
```
---
### 6.3 RBAC Export/Import in Admin-Seiten integrieren
**Beispiel: Standalone-Seite oder Modal**
```tsx
// src/pages/admin/AdminRbacExportImportPage.tsx
import { RbacExportImport } from '../../components/RbacExportImport';
export const AdminRbacExportImportPage: React.FC = () => {
const [selectedMandateId, setSelectedMandateId] = useState<string>('');
const { user } = useCurrentUser();
return (
<div className={styles.adminPage}>
<h1>RBAC Export/Import</h1>
{/* Mandant-Auswahl */}
<select
value={selectedMandateId}
onChange={(e) => setSelectedMandateId(e.target.value)}
>
<option value="">-- Mandant wählen --</option>
{mandates.map(m => (
<option key={m.id} value={m.id}>{m.name}</option>
))}
</select>
{/* Export/Import für gewählten Mandant */}
{selectedMandateId && (
<RbacExportImport
mandateId={selectedMandateId}
mandateName={mandates.find(m => m.id === selectedMandateId)?.name}
/>
)}
{/* Globale Templates (nur SysAdmin) */}
{user?.isSysAdmin && (
<div style={{ marginTop: '2rem' }}>
<h2>Globale Templates</h2>
<RbacExportImport isGlobal={true} />
</div>
)}
</div>
);
};
```
---
### 6.4 Mandate-Admin Navigation hinzufügen (Empfehlung)
**In `MandateNavigation.tsx` erweitern:**
```tsx
// Nach den Feature-Nodes pro Mandant:
function mandateToTreeNode(mandate: Mandate, userId: string): TreeNodeItem | null {
// ... bestehender Code ...
// Admin-Sektion für Mandate-Admins hinzufügen
const isMandateAdmin = checkMandateAdminRole(userId, mandate.id);
if (isMandateAdmin) {
children.push({
id: `${mandate.id}-admin`,
label: 'Administration',
icon: <FaCog />,
children: [
{ id: `${mandate.id}-admin-users`, label: 'Benutzer', path: `/mandates/${mandate.id}/admin/users` },
{ id: `${mandate.id}-admin-roles`, label: 'Rollen', path: `/mandates/${mandate.id}/admin/roles` },
{ id: `${mandate.id}-admin-instances`, label: 'Feature-Instanzen', path: `/mandates/${mandate.id}/admin/instances` },
{ id: `${mandate.id}-admin-rbac`, label: 'RBAC Export/Import', path: `/mandates/${mandate.id}/admin/rbac` },
],
});
}
return { /* ... */ };
}
```
---
## 7. API-Anbindung
### 7.1 Implementierte Endpoints
| Endpoint | Frontend-Verwendung |
|----------|---------------------|
| `GET /api/features/my` | `featuresApi.fetchMyFeatures()` |
| `GET /api/features/available` | `featuresApi.fetchAvailableFeatures()` |
| `GET /api/invitations/validate/:token` | `useInvitations().validateInvitation()` |
| `POST /api/invitations/accept/:token` | `useInvitations().acceptInvitation()` |
| `POST /api/invitations/register-and-accept` | `useInvitations().registerAndAccept()` |
| `GET /api/invitations/` | `useInvitations().fetchInvitations()` |
| `POST /api/invitations/` | `useInvitations().createInvitation()` |
| `DELETE /api/invitations/:id` | `useInvitations().revokeInvitation()` |
### 7.2 Neu implementierte Endpoint-Anbindungen
| Endpoint | UI-Komponente | Hook |
|----------|---------------|------|
| `GET /api/rbac/roles/:id/rules` | `AccessRulesEditor` | `useAccessRules` |
| `PUT /api/rbac/roles/:id/rules` | `AccessRulesEditor` | `useAccessRules` |
| `POST /api/rbac/roles/:id/rules` | `AccessRulesEditor` | `useAccessRules` |
| `PATCH /api/rbac/rules/:id` | `AccessRulesEditor` | `useAccessRules` |
| `DELETE /api/rbac/rules/:id` | `AccessRulesEditor` | `useAccessRules` |
| `GET /api/mandates/:id/rbac/export` | `RbacExportImport` | `useRbacExportImport` |
| `POST /api/mandates/:id/rbac/import` | `RbacExportImport` | `useRbacExportImport` |
| `GET /api/admin/rbac/global/export` | `RbacExportImport` | `useRbacExportImport` |
| `POST /api/admin/rbac/global/import` | `RbacExportImport` | `useRbacExportImport` |
| `GET /api/features/instances/:id/rbac/export` | `RbacExportImport` | `useRbacExportImport` |
### 7.3 Noch zu implementieren
| Endpoint | Fehlende UI-Komponente |
|----------|------------------------|
| `POST /api/features/instances/:id/sync-roles` | Sync-Button in Admin |
---
## 8. Zusammenfassung der Empfehlungen
### ✅ Abgeschlossen
1. **AccessRulesEditor** - Vollständig implementiert
2. **RBAC Export/Import UI** - Vollständig implementiert
### Priorität 1 (Hoch)
1. **Mandate-Admin Navigation** - Pro Mandant Admin-Bereich für Mandate-Admins
2. **Integration der neuen Komponenten** in bestehende Admin-Seiten
### Priorität 2 (Mittel)
3. **Template-Sync UI** - Button für Rollen-Synchronisation von Templates
4. **Admin-Route für RBAC Export/Import** hinzufügen
### Priorität 3 (Niedrig)
5. **Chatworkflow Views** - Aktuell nur Placeholder
6. **Chatbot Views** - Aktuell nur Placeholder
---
## 9. Checkliste für Feature-Entwickler
### 9.1 Beim Hinzufügen neuer Features
- [ ] Types in `types/mandate.ts` ergänzen
- [ ] View in `FEATURE_REGISTRY` registrieren
- [ ] Komponente in `VIEW_COMPONENTS` registrieren
- [ ] Route in `App.tsx` hinzufügen
- [ ] Permissions im Backend definieren (`trustee-newview`)
- [ ] API-Hook erstellen wenn nötig
- [ ] `FormGeneratorForm` für CRUD-Formulare nutzen
- [ ] `FormGeneratorTable` für Listen nutzen
- [ ] `PermissionGate` für bedingte UI-Elemente
- [ ] `useTablePermission` für Record-basierte Checks
### 9.2 Beim Arbeiten mit RBAC
- [ ] `AccessRulesEditor` für Rollen-Berechtigungen nutzen
- [ ] `RbacExportImport` für Backup/Migration nutzen
- [ ] `useAccessRules` Hook für programmatische RBAC-Verwaltung
- [ ] `useRbacExportImport` Hook für Export/Import-Logik
---
## 10. Neue Komponenten - Dateiübersicht
### 10.1 AccessRules
```
src/
├── hooks/
│ └── useAccessRules.ts // RBAC-Regeln Hook
└── components/
└── AccessRules/
├── AccessRulesEditor.tsx // Hauptkomponente
├── AccessLevelSelect.tsx // Dropdown für n/m/g/a
├── AccessRules.module.css // Styles
└── index.ts // Exports
```
### 10.2 RBAC Export/Import
```
src/
├── hooks/
│ └── useRbacExportImport.ts // Export/Import Hook
└── components/
└── RbacExportImport/
├── RbacExportImport.tsx // Hauptkomponente
├── RbacExportImport.module.css // Styles
└── index.ts // Exports
```