# 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.