25 KiB
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
// 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
mandateIdmehr - 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
// 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.tsxsrc/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 ✅
<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.tsxsrc/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
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
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
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
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
GenericFormKomponente 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
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
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 |
<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
// 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
// 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
// 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
// src/App.tsx
<Route path="newview" element={<FeatureViewPage view="newview" />} />
6.2 AccessRulesEditor in Admin-Seiten integrieren
Beispiel: Integration in AdminRolesPage
// 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
// 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:
// 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
- AccessRulesEditor - Vollständig implementiert
- RBAC Export/Import UI - Vollständig implementiert
Priorität 1 (Hoch)
- Mandate-Admin Navigation - Pro Mandant Admin-Bereich für Mandate-Admins
- Integration der neuen Komponenten in bestehende Admin-Seiten
Priorität 2 (Mittel)
- Template-Sync UI - Button für Rollen-Synchronisation von Templates
- Admin-Route für RBAC Export/Import hinzufügen
Priorität 3 (Niedrig)
- Chatworkflow Views - Aktuell nur Placeholder
- Chatbot Views - Aktuell nur Placeholder
9. Checkliste für Feature-Entwickler
9.1 Beim Hinzufügen neuer Features
- Types in
types/mandate.tsergänzen - View in
FEATURE_REGISTRYregistrieren - Komponente in
VIEW_COMPONENTSregistrieren - Route in
App.tsxhinzufügen - Permissions im Backend definieren (
trustee-newview) - API-Hook erstellen wenn nötig
FormGeneratorFormfür CRUD-Formulare nutzenFormGeneratorTablefür Listen nutzenPermissionGatefür bedingte UI-ElementeuseTablePermissionfür Record-basierte Checks
9.2 Beim Arbeiten mit RBAC
AccessRulesEditorfür Rollen-Berechtigungen nutzenRbacExportImportfür Backup/Migration nutzenuseAccessRulesHook für programmatische RBAC-VerwaltunguseRbacExportImportHook 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