35 KiB
Umsetzungsplan: Multi-Mandate Onboarding, Store und Unified Data Layer
Grundlage: Multi-Mandate-Onboarding-und-Store-Konzept.md v4
Struktur: Der Plan folgt den drei Phasen aus dem Konzept. Jede Phase ist in konkrete Arbeitspakete (AP) zerlegt. Jedes AP enthält: betroffene Dateien, Abhängigkeiten und Akzeptanzkriterien.
Legende: [BE] = Backend, [FE] = Frontend, [DB] = Datenbank/Migration, [OPS] = Betrieb/Infrastruktur
Phase 1 — Mandate-per-Registration und Own-Instance-Pattern
Ziel: Saubere Mandanten-Grenze, eigene Instanzen pro Mandant, Root nur noch technisch.
FeatureInstance= Datengrenze.
AP 1.1 — [DB] Datenmodell: mandateType Enum auf Mandate
Beschreibung: Neues Feld mandateType auf dem Mandate-Modell. Enum mit Werten system, personal, company. Mutabel und rein informativ — keine Geschäftslogik daran gebunden.
Dateien:
gateway/modules/datamodels/datamodelUam.py— EnumMandateTypehinzufügen, FeldmandateTypeaufMandate
Schritte:
- Enum
MandateTypedefinieren (system,personal,company) - Feld
mandateType: MandateTypeaufMandatemit Defaultcompany - Bestehende Mandanten erhalten via DB-Update Default
company - Root-Mandant explizit auf
systemsetzen (im Bootstrap)
Akzeptanz:
- Alle bestehenden Mandanten haben
mandateType=company - Root-Mandant hat
mandateType=system - Keine Geschäftslogik prüft
mandateTypefür Feature-Gates oder Kapazität
Abhängigkeiten: Keine
AP 1.2 — [BE] Subscription-Timing: PENDING → ACTIVE
Beschreibung: MandateSubscription wird bei Registrierung mit Status PENDING erstellt. Aktivierung auf ACTIVE erfolgt bei erstem Login. Trial-Periode beginnt erst ab Aktivierung.
Dateien:
gateway/modules/datamodels/datamodelSubscription.py— StatusPENDINGin die State Machine aufnehmengateway/modules/routes/routeSecurityLocal.py— Subscription mitPENDINGerstellengateway/modules/routes/routeSecurityGoogle.py— Subscription mitPENDINGerstellen- Login-Logik (Local + OAuth) — bei erstem Login
PENDING→ACTIVETransition auslösen
Schritte:
PENDINGals neuen Status inSubscriptionStatusEnum hinzufügen- State-Machine-Transition
PENDING → ACTIVEdefinieren - Bei Registrierung:
MandateSubscriptionmitstatus=PENDING,trialStartDate=null - Bei erstem Login: Status auf
ACTIVEsetzen,trialStartDate=now() - Bestehende Subscriptions bleiben unverändert (
ACTIVE)
Akzeptanz:
- Neue Registrierungen erhalten
PENDING-Subscription - Erster Login setzt auf
ACTIVEund startet Trial - Kein User verliert Trial-Tage durch Magic-Link-Delay
Abhängigkeiten: AP 1.1
AP 1.3 — [BE] Interne Provisionierungsroutine _provisionMandateForUser
Beschreibung: Zentrale atomare Funktion, die nach createUser ein komplettes Mandate mit Subscription und Feature-Instanzen erstellt. Umgeht RBAC (Root-privilegiert), da der User noch keine Rechte hat.
Dateien:
gateway/modules/interfaces/interfaceDbApp.py— neue Funktion_provisionMandateForUser()
Schritte:
- Funktion
_provisionMandateForUser(userId, mandateType, mandateName, planKey)erstellen - Atomare Transaktion:
a.
createMandate(mitmandateType, ohne RBAC-Check) b. System-Rollen kopieren (_copySystemRolesToMandate) c.createUserMandatemit Admin-Rolle d.MandateSubscriptionerstellen (mitPENDING) e. Für Features mitautoCreateInstance:createFeatureInstance+FeatureAccessmit Admin-Instanzrolle - Rollback bei Fehler in einem Schritt
- Logging aller Aktionen
Akzeptanz:
- Ein Aufruf erstellt alles atomar (Mandate + UserMandate + Subscription + Instanzen)
- Bei Fehler: kein Halbzustand (keine verwaisten Mandate)
- RBAC wird nicht geprüft (interne Routine)
Abhängigkeiten: AP 1.1, AP 1.2
AP 1.4 — [BE] Registrierung Local: Mandate-Provisionierung
Beschreibung: POST /api/local/register erweitern um registrationType und companyName. Nach createUser wird _provisionMandateForUser aufgerufen.
Dateien:
gateway/modules/routes/routeSecurityLocal.py— Register-Endpoint erweitern
Schritte:
- Request-Body erweitern:
registrationType(personal/company),companyName(optional) - Validierung:
companyerfordertcompanyName - Nach
createUser:_provisionMandateForUseraufrufen mit:personal→mandateType=personal,planKey=TRIAL_7D,mandateName=usernamecompany→mandateType=company,planKey=STANDARD_MONTHLY,mandateName=companyName
- Response erweitern um
mandateId
Akzeptanz:
- Registrierung erstellt User + Mandate + Subscription + Instanzen in einem Flow
- Personal → Trial, Company → Standard
- Fehler bei Provisionierung → User wird nicht erstellt (oder cleanup)
Abhängigkeiten: AP 1.3
AP 1.5 — [BE] Registrierung OAuth: Onboarding-Wizard
Beschreibung: Bei OAuth-Registrierung (Google, MSAL) gibt es kein Formular. Stattdessen wird beim allerersten Login erkannt, dass kein Mandate existiert, und ein Onboarding-Wizard-Flag gesetzt.
Dateien:
gateway/modules/routes/routeSecurityGoogle.py— Erkennung „erster Login ohne Mandate"- Analoge Logik für MSAL-Route
Schritte:
- Nach OAuth-Login prüfen: Hat der User mindestens ein Mandate?
- Falls nein: Response-Flag
requiresOnboarding=truesetzen - Frontend zeigt Onboarding-Wizard (siehe AP 1.12)
- Wizard-Submit ruft neuen Endpoint auf:
POST /api/onboarding/provisionmitmandateType+companyName - Endpoint nutzt
_provisionMandateForUser
Akzeptanz:
- OAuth-User ohne Mandate wird erkannt
- Wizard erscheint nur beim allerersten Login
- Nach Wizard-Abschluss hat der User ein vollständiges Mandate
Abhängigkeiten: AP 1.3
AP 1.6 — [BE] Feature Store: Refactoring auf Own Instance Pattern
Beschreibung: Store erstellt eigene FeatureInstance im Ziel-Mandanten statt Shared Instance im Root. Explizites mandateId in allen Store-APIs. Mehrere Instanzen desselben Features sind erlaubt.
Dateien:
gateway/modules/routes/routeStore.py— komplettes Refactoring
Schritte:
POST /api/store/activate:- Body:
featureCode+mandateId(explizit, nie implizit) - Prüfungen: User ist Admin im Ziel-Mandat, Subscription-Kapazität (
maxFeatureInstances) - Neue
FeatureInstanceim Ziel-Mandat erstellen (auch wenn bereits eine gleiche existiert) FeatureAccess+ Admin-Instanzrolle für den User- Stripe-Quantity sync
- Body:
POST /api/store/deactivate:- Body:
featureCode+mandateId+instanceId - Eigenen
FeatureAccessentfernen - Orphan-Check: Keine
FeatureAccess-Records mehr → Instanz löschen + Stripe-Quantity sync
- Body:
GET /api/store/features:- Zeigt verfügbare Features mit Status pro Mandat des Users
- Für jeden Mandanten des Users: Anzahl aktiver Instanzen
- Alte Shared-Instance-Logik entfernen
Akzeptanz:
- Aktivierung erstellt immer eine neue Instanz im expliziten Mandat
- Mehrere Instanzen desselben Features pro Mandat möglich
- Orphan Control: letzte Deaktivierung löscht Instanz
- Kein
mandateId-Guessing, kein implizites Primary-Mandate
Abhängigkeiten: AP 1.1, AP 1.3
AP 1.7 — [BE] Store: Auto-Mandate für User ohne Admin-Mandate
Beschreibung: User, die nur als Mitglieder (nicht Admin) in fremden Mandanten sind, können über den Store ein eigenes Mandate erstellen lassen.
Dateien:
gateway/modules/routes/routeStore.py— Activate-Endpoint erweitern
Schritte:
- Bei
activate: Prüfen ob User mindestens ein Mandate hat, in dem er Admin ist - Falls kein Admin-Mandate vorhanden und
mandateIdnicht angegeben:_provisionMandateForUseraufrufen (personal, TRIAL_7D)- Feature-Instanz im neuen Mandate erstellen
- Response enthält neues
mandateId
- Falls
mandateIdangegeben aber User kein Admin dort: Fehler (403)
Akzeptanz:
- User ohne Admin-Mandate kann Feature im Store aktivieren → Auto-Mandate
- User wird automatisch Admin des neuen Mandanten
- Bestehende Admins nutzen weiterhin den normalen Flow
Abhängigkeiten: AP 1.6, AP 1.3
AP 1.8 — [BE] Subscription: maxDataVolumeMB Parameter
Beschreibung: Neuer Parameter maxDataVolumeMB in der Subscription für Kapazitätsplanung (Soft-Limit).
Dateien:
gateway/modules/datamodels/datamodelSubscription.py—BUILTIN_PLANSerweiterngateway/modules/interfaces/interfaceDbApp.py— Volumen-Berechnung
Schritte:
maxDataVolumeMBals Parameter inSubscriptionPlanhinzufügen- Default-Werte pro Plan definieren (z. B. TRIAL_7D: 500 MB, STANDARD: 10 GB)
- API-Endpoint für aktuelle Nutzung:
GET /api/mandate/{id}/data-usage - Berechnung: Summe aller Dateigrössen im Mandate
Akzeptanz:
- Subscription-Pläne enthalten
maxDataVolumeMB - Aktuelle Nutzung ist abrufbar
- Kein Schreib-Block bei Überschreitung (Soft-Limit)
Abhängigkeiten: AP 1.2
AP 1.9 — [DB] Migrations-Script: Root-Mandant bereinigen
Beschreibung: Separates Script, das alle Endkunden-Daten aus dem Root-Mandate in eigene Mandate migriert. Einmalig im Bootstrap aufgerufen.
Dateien:
gateway/scripts/script_migrate_root_users.py(odergateway/modules/migration/migrateRootUsers.py) — NEUgateway/modules/interfaces/interfaceBootstrap.py— Aufruf einhängen
Schritte:
- Script erstellen mit Dry-Run-Modus
- Schritt 1 — Feature-Daten migrieren:
- Für jeden User mit FeatureAccess auf Root-Instanzen:
- Hat User eigenes Mandate? → Ziel-Mandate setzen
- Kein Mandate? →
_provisionMandateForUser(personal) - Pro FeatureAccess: Neue Instanz im Ziel-Mandat erstellen, Daten umschreiben (
featureInstanceId), FeatureAccess transferieren
- Für jeden User mit FeatureAccess auf Root-Instanzen:
- Schritt 2 — Root bereinigen:
- Alle Feature-Instanzen im Root entfernen
- UserMandate zum Root entfernen (ausser
isSysAdmin=true)
- Root-Mandate:
mandateType=systemsetzen - Flag in DB setzen: Migration abgeschlossen (verhindert Doppelausführung)
- Im Bootstrap einhängen nach
initRootMandateFeatures
Akzeptanz:
- Dry-Run zeigt alle Aktionen ohne Änderungen
- Alle User haben eigene Mandate mit migrierten Daten
- Root enthält nur sysadmin-User, keine Feature-Instanzen
- Script läuft nur einmal (Flag-Check)
Abhängigkeiten: AP 1.1, AP 1.3
AP 1.10 — [BE] Mandanten-Löschung: Kaskade
Beschreibung: Vollständige Lösch-Kaskade für Mandanten mit Soft-Delete und Schutzmechanismen.
Dateien:
gateway/modules/interfaces/interfaceDbApp.py— neue Funktion_deleteMandate()gateway/modules/shared/gdprDeletion.py— erweitern- API-Endpoint:
DELETE /api/mandates/{mandateId}
Schritte:
- Schutzmechanismen:
isSystem=true→ Löschung verweigern- Nur Mandanten-Admin oder sysadmin darf löschen
- Bestätigung via
confirmMandateNameim Request-Body
- Soft-Delete:
deletedAtTimestamp auf Mandate setzen- Alle Zugriffe sofort sperren (RBAC-Check auf
deletedAt) - 30-Tage Retention
- Kaskade (bei endgültiger Löschung):
- FeatureInstances → FeatureAccess → Instanz-Daten (Chats, Dokumente, Extraktionen)
- DataNeutralizerAttributes (Mapping-Tabelle)
- RAG-Index-Einträge mit
mandateId - UserMandate-Zuordnungen (User bleiben bestehen)
- MandateSubscription → Stripe-Subscription kündigen
- Mandate-Konfigurationen (Rollen, Settings)
- Mandate-Record
- Batch-Job für endgültige Löschung nach Retention
Akzeptanz:
- Root-Mandate nicht löschbar
- Soft-Delete mit sofortiger Zugriffssperre
- Vollständige Kaskade ohne verwaiste Daten
- Stripe-Subscription wird gekündigt
Abhängigkeiten: AP 1.1
AP 1.11 — [FE] Register-Seite: Zwei Flows
Beschreibung: Register-Formular unterstützt type=personal und type=company via Query-Parameter.
Dateien:
frontend_nyla/src/pages/Register.tsx—typeQuery-Parameterfrontend_nyla/src/api/authApi.ts—registerApierweitern
Schritte:
- Query-Parameter
typeauslesen (personal/company) - Bei
company: Zusatzfeld „Firmenname" anzeigen - API-Call erweitern:
registrationType+companyNameim Body - Erfolgsseite anpassen: „Dein Mandant wurde erstellt"
- Redirect nach Login auf Dashboard (nicht Store, da Instanzen via autoCreate existieren)
Akzeptanz:
/register?type=personalzeigt Personal-Flow/register?type=companyzeigt Company-Flow mit Firmenname- API-Body enthält neue Felder
Abhängigkeiten: AP 1.4
AP 1.12 — [FE] Login-Seite: Zwei CTAs + OAuth Onboarding-Wizard
Beschreibung: Login/Landing-Seite mit zwei prominenten Call-to-Actions und Onboarding-Wizard für OAuth-Erstregistrierungen.
Dateien:
frontend_nyla/src/pages/Login.tsx— CTAs hinzufügenfrontend_nyla/src/components/OnboardingWizard.tsx— NEU
Schritte:
- Login-Seite: Zwei CTAs
- „Kostenlos testen" →
/register?type=personal - „Für Unternehmen" →
/register?type=company
- „Kostenlos testen" →
- Onboarding-Wizard Komponente:
- Schritt 1: „Wie möchtest du PowerON nutzen?" (Personal / Unternehmen)
- Schritt 2: Bei Company → Firmenname eingeben
- Submit →
POST /api/onboarding/provision
- Nach OAuth-Login: Prüfen ob
requiresOnboarding=truein Response → Wizard anzeigen
Akzeptanz:
- Zwei CTAs sichtbar auf Login-Seite
- OAuth-User ohne Mandate sieht Wizard
- Wizard erstellt Mandate und leitet zum Dashboard
Abhängigkeiten: AP 1.5
AP 1.13 — [FE] Store-Seite: Mandanten-Auswahl
Beschreibung: Store zeigt explizite Mandanten-Auswahl bei Aktivierung. Alle User sehen den Store.
Dateien:
frontend_nyla/src/pages/Store.tsx— Refactoring
Schritte:
- Store für alle User zugänglich machen (kein Admin-Gate)
- Pro Feature: Mandanten-Auswahl anzeigen (Dropdown bei Multi-Mandate, auto-select bei Solo)
- „Aktivieren für [Mandantenname]" statt nur „Aktivieren"
- Bei User ohne Admin-Mandate: „Eigenen Mandanten erstellen und Feature aktivieren" als Option
- Deaktivierung: Pro Instanz mit Orphan-Warnung („Du bist der letzte User — Instanz wird gelöscht")
- Anzeige aktiver Instanzen pro Mandate mit Instanz-Anzahl
Akzeptanz:
- Mandanten-Auswahl bei jeder Aktivierung
- Auto-Mandate-Option für User ohne eigenes Mandate
- Orphan-Warnung bei letzter Deaktivierung
Abhängigkeiten: AP 1.6, AP 1.7
AP 1.14 — [FE] Subscription-Datenvolumen: UI-Hinweis
Beschreibung: Anzeige der Datenvolumen-Nutzung im Billing-Bereich.
Dateien:
frontend_nyla/src/pages/billing/BillingDataView.tsx— Datenvolumen-Anzeige
Schritte:
- API-Aufruf:
GET /api/mandate/{id}/data-usage - Fortschrittsbalken: genutzt / maximal (z. B. „3.2 GB / 10 GB")
- Warnung bei > 80%: „Du näherst dich dem Datenvolumen-Limit"
- Upgrade-Link bei hoher Nutzung
Akzeptanz:
- Datenvolumen sichtbar im Billing-Bereich
- Warnung bei > 80%
- Kein Block, nur Hinweis
Abhängigkeiten: AP 1.8
AP 1.15 — [BE] Bootstrap: Root-Mandant mandateType=system setzen
Beschreibung: Im Bootstrap den Root-Mandanten explizit auf mandateType=system setzen.
Dateien:
gateway/modules/interfaces/interfaceBootstrap.py—initRootMandate()erweitern
Schritte:
- In
initRootMandate():mandateType=systemsetzen initRootMandateFeatures()bleibt für System-Instanzen (aber keine Endkunden-Instanzen mehr nach Migration)
Akzeptanz:
- Root-Mandant hat
mandateType=systemnach Bootstrap - Keine Endkunden-Feature-Instanzen im Root (nach Migration)
Abhängigkeiten: AP 1.1, AP 1.9
Phase 2 — UDB + Shared Data Scope
Ziel: UDB als plattformweite Komponente, mandantenweiter Datenzugriff via Scopes.
FeatureInstance= Datengrenze + mandantenweiter Zugriff.
Voraussetzung: Phase 1 vollständig abgeschlossen.
AP 2.1 — [BE] Datenmodell: Scope- und Neutralisierungs-Felder auf DataSources
Beschreibung: Bestehende Datenquellen-Modelle um scope und neutralize Felder erweitern. RAG-Index um Scope-Metadaten erweitern.
Dateien:
- Bestehende Datenmodelle (Dokumente, Extraktionen, Konnektoren) —
scope+neutralizeFelder - RAG-Index-Konfiguration — Filterbare Metadaten
Schritte:
- Enum
DataScopedefinieren:personal,featureInstance,mandate,global - Felder hinzufügen:
scope: DataScope(defaultpersonal),neutralize: bool(defaultfalse),neutralizationStatus: str - Bestehende Daten: Default
scope=featureInstance(bestehendes Verhalten) - RAG-Index-Metadaten erweitern:
mandateId,scope,featureInstanceId,userId,isNeutralized - Bestehende RAG-Einträge: Backfill mit Scope-Metadaten
Akzeptanz:
- Alle DataSources haben
scopeundneutralize - RAG-Index filtert korrekt nach Scope
- Bestehende Daten haben konsistente Defaults
Abhängigkeiten: Phase 1 abgeschlossen
AP 2.2 — [BE] RAG-Query: Scope-basierte Filterung
Beschreibung: RAG-Queries filtern Ergebnisse basierend auf dem effektiven Scope des anfragenden Users.
Dateien:
- RAG-Query-Logik — Scope-Filter aufbauen
Schritte:
- Scope-Kontext aufbauen pro Query:
personal(userId) ∪ featureInstance(instanceId) ∪ mandate(mandateId) ∪ global() - Union-Query über vier Scopes implementieren
scope=globalnur sysadmin-setzbar (RBAC-Check beim Tagging)- Performance-Tests mit grossen Datenmengen
Akzeptanz:
- User sieht nur Daten seiner Scopes
- Global-Scope RBAC-geschützt
- Query-Performance akzeptabel (< 500ms)
Abhängigkeiten: AP 2.1
AP 2.3 — [BE] Datenquellen-Tagging API
Beschreibung: API-Endpoints für Scope- und Neutralisierungs-Tagging auf Datenquellen.
Dateien:
- Neue oder erweiterte Routes — Tagging-Endpoints
Schritte:
PATCH /api/datasources/{id}/scope— Scope ändern (personal → featureInstance → mandate; global nur sysadmin)PATCH /api/datasources/{id}/neutralize— Neutralisierungs-Flag togglen- Bei Scope-Änderung: RAG-Index re-indizieren (async)
- Bei Neutralisierungs-Änderung: Re-Neutralisierung oder De-Neutralisierung triggern (async)
- Defaults bei Upload:
scope=personal,neutralize=false
Akzeptanz:
- Scope-Änderung löst Re-Indizierung aus
- Neutralisierungs-Änderung löst Re-Verarbeitung aus
- RBAC:
globalnur für sysadmin
Abhängigkeiten: AP 2.1, AP 2.2
AP 2.4 — [FE] UDB: Extraktion aus Workspace
Beschreibung: Die bestehende Sidebar im AI Workspace (Chats, Files, Sources) wird als wiederverwendbare Plattformkomponente extrahiert.
Dateien:
frontend_nyla/src/pages/workspace/— Sidebar-Logik identifizieren und extrahierenfrontend_nyla/src/components/UnifiedDataBar/— NEU: UDB-Komponente
Schritte:
- Bestehende Sidebar-Komponenten im Workspace identifizieren (Chats-Liste, Files-Liste, Sources-Liste)
- Gemeinsame UDB-Komponente erstellen mit drei Tabs: Chats, Files, Sources
- Props:
mandateId,featureInstanceId,userIdfür Kontext - Workspace refactoren: UDB einbinden statt eigener Sidebar
- Verifizieren: Workspace funktioniert identisch mit UDB-Komponente
Akzeptanz:
- UDB ist eine eigenständige Komponente in
src/components/ - Workspace nutzt UDB und funktioniert wie zuvor
- Keine Duplizierung von Sidebar-Logik
Abhängigkeiten: Phase 1 abgeschlossen
AP 2.5 — [FE] UDB: Chats-Tab mit Baumstruktur
Beschreibung: Chat-Verläufe als hierarchischer Baum, gruppiert nach Feature-Instanzen mit Suchfunktion und Flat Mode.
Dateien:
frontend_nyla/src/components/UnifiedDataBar/ChatsTab.tsx— NEU
Schritte:
- API: Chats über alle Feature-Instanzen des Users laden (gruppiert)
- Baumstruktur: Feature-Instanzen als Top-Level-Knoten, Chats darunter
- Feature-spezifische Substrukturen (z. B. CommCoach → Coaching-Modul → Sessions)
- Aktuelle Feature-Instanz: hervorgehoben und expandiert
- Klick auf Chat: Navigation in den Chat (ggf. Feature-Kontext wechseln)
- Suchfunktion: Volltextsuche über Chat-Titel, filtert Baum auf Treffer
- Flat Mode: Toggle im Tab-Header, chronologische Liste sortiert nach letzter Aktivität
Akzeptanz:
- Alle Chats über alle Feature-Instanzen sichtbar in einem Baum
- Suche filtert korrekt
- Flat Mode zeigt chronologische Liste
- Klick navigiert zum Chat
Abhängigkeiten: AP 2.4
AP 2.6 — [FE] UDB: Files-Tab mit Scope- und Neutralisierungs-Symbolen
Beschreibung: Dateien mit Inline-Scope-Symbolen und Neutralisierungs-Icons.
Dateien:
frontend_nyla/src/components/UnifiedDataBar/FilesTab.tsx— NEU
Schritte:
- Dateien pro Mandat laden (alle Scopes, die der User sehen darf)
- Pro Datei: Scope-Symbol (👤 personal, 👥 instanz, 🏢 mandant) + Neutralisierungs-Symbol (🔒)
- Klick auf Scope-Symbol: Zyklisch wechseln oder Popover
- Klick auf Neutralisierungs-Symbol: Toggle on/off
- Default bei Upload:
personal+ kein 🔒 - Legende am Tab-Footer
Akzeptanz:
- Alle Dateien mit korrekten Scope-Symbolen
- Scope- und Neutralisierungs-Toggle funktionieren mit API-Calls
- Visuell klar und unkompliziert
Abhängigkeiten: AP 2.3, AP 2.4
AP 2.7 — [FE] UDB: Sources-Tab mit Active/Browse
Beschreibung: Datenquellen-Tab mit Trennung zwischen Active Sources (mit Icons) und Browse Sources (Katalog ohne Icons).
Dateien:
frontend_nyla/src/components/UnifiedDataBar/SourcesTab.tsx— NEU
Schritte:
- Active Sources: Eingebundene Quellen mit Scope- und Neutralisierungs-Symbolen
- Browse Sources: Verfügbare Quellen als Katalog (keine Symbole)
- Feature Data: Daten pro Feature-Instanz (Tabellen-Übersicht)
- Aktivierung: Drag aus Browse in Active oder Klick → Default-Scope setzen
- Deaktivierung:
x-Button bei Active Sources
Akzeptanz:
- Klare Trennung Active vs. Browse
- Symbole nur bei Active Sources
- Aktivierung setzt Defaults korrekt
Abhängigkeiten: AP 2.3, AP 2.4
AP 2.8 — [FE] UDB: Drag-and-Drop in Prompt
Beschreibung: Alle UDB-Elemente (Chats, Files, Sources) können per Drag-and-Drop in den Prompt gezogen werden. Bei Chats werden die RAG-Daten des Chats abgefragt, nicht der Chat-Inhalt.
Dateien:
frontend_nyla/src/components/UnifiedDataBar/— DnD-Logik- Prompt-Eingabe-Komponente — Drop-Zone
Schritte:
- Drag-Source auf allen UDB-Elementen (Chats, Files, Sources)
- Drop-Zone im Prompt-Bereich
- Chats: Bei Drop → RAG-Query nach Daten, die dem Chat zugeordnet sind (nicht Chat-Inhalt selbst)
- Files: Bei Drop → Datei als Kontext-Dokument anhängen
- Sources: Bei Drop → Datenquelle als aktiven Kontext setzen
- Visuelles Feedback: Drag-Preview, Drop-Highlight, Kontext-Badge im Prompt
Akzeptanz:
- Drag-and-Drop funktioniert für alle drei Tabs
- Chats liefern RAG-Daten, nicht Chat-Inhalt
- Visuelles Feedback bei Drag und Drop
Abhängigkeiten: AP 2.5, AP 2.6, AP 2.7
AP 2.9 — [FE] UDB: Integration in alle Feature-Instanzen
Beschreibung: UDB in alle bestehenden Features einbinden (Workspace, CommCoach, Trustee, Automation).
Dateien:
- Feature-Seiten: Workspace, CommCoach, Trustee, Automation — UDB einbinden
Schritte:
- Workspace: UDB ersetzt bestehende Sidebar (bereits in AP 2.4)
- CommCoach: UDB als Sidebar einbinden
- Trustee: UDB als Sidebar einbinden
- Automation: UDB als Sidebar einbinden
- Pro Feature: Korrekter Kontext (
featureInstanceId) an UDB übergeben - Layout-Anpassungen pro Feature
Akzeptanz:
- Alle Features haben die UDB
- Kontext stimmt pro Feature-Instanz
- Keine Feature-eigenen Sidebar-Duplikate mehr
Abhängigkeiten: AP 2.4 — AP 2.8
AP 2.10 — [BE] Doppelte Strukturen konsolidieren
Beschreibung: Datensilos auflösen: Voice-Definitionen, Dokumentenkontext und Wissensbasis mandantenweit verfügbar machen.
Dateien:
- CommCoach Voice-Datenmodell — Scope-Feld hinzufügen
- Workspace Dokument-Logik — Scope-basierte Queries
Schritte:
- Voice-Definitionen: Von instanz-zentriert auf mandantenweit umstellen (scope=mandate)
- Wissensbasis: Von instanz-zentriert auf scope-basiert (User wählt Scope)
- Dokumenten-Kontext: Mandantenweite Suche mit Scope-Filter
- Feature-spezifische Daten-Tabellen:
scope-Feld wo nötig - Migration bestehender Daten: Default-Scope setzen
Akzeptanz:
- Voice-Definitionen mandantenweit nutzbar
- Keine doppelten Definitionen mehr nötig
- Cross-Feature-Zugriff auf Wissensbasis funktioniert
Abhängigkeiten: AP 2.1, AP 2.2
Phase 3 — Unified Data Layer + Neutralisierung als Kerndisziplin
Ziel: Features sind reine Workflow-Oberflächen. UDL mit Neutralisierung ist der Plattformkern.
FeatureInstance= UI-Scope.
Voraussetzung: Phase 2 vollständig abgeschlossen.
AP 3.1 — [BE] Neutralisierung: Fail-Safe-Logik
Beschreibung: Wenn Neutralisierung fehlschlägt, wird das Dokument nicht weitergegeben. Kein Fallback auf Originaldaten.
Dateien:
gateway/modules/workflows/methods/methodContext/actions/neutralizeData.py— Fail-Safe einbauengateway/modules/features/neutralization/serviceNeutralization/— Error Handling
Schritte:
- Bestehende Error-Handling-Logik ändern: Bei Fehler nicht das Original-Part verwenden
- Stattdessen: Part überspringen + Warning-Flag setzen
- ChatWorkflow: Hinweis „Dokument X konnte aus Datenschutzgründen nicht einbezogen werden"
- AI-Call läuft ohne das fehlgeschlagene Dokument weiter
- Logging: Fehlergrund (Timeout, Modell nicht erreichbar, etc.)
- Beim RAG-Indexing: Neutralisierung fehlgeschlagen → Dokument nicht indizieren,
neutralizationStatus=failed
Akzeptanz:
- Kein Originaldokument geht an externe AI wenn Neutralisierung fehlschlägt
- User sieht Hinweis, welches Dokument fehlt und warum
- AI-Call funktioniert ohne das fehlende Dokument
Abhängigkeiten: Phase 2 abgeschlossen
AP 3.2 — [BE] Neutralisierung: RAG-Integration
Beschreibung: Datenquellen mit neutralize=true werden nur in neutralisierter Form im RAG indiziert.
Dateien:
- RAG-Indexing-Pipeline — Neutralisierungs-Gate
gateway/modules/features/neutralization/— Pipeline-Integration
Schritte:
- Beim Einbinden einer Datenquelle mit
neutralize=true:- Container auflösen (bestehende Extraction-Pipeline)
- Media droppen
- Bilder → neutraler Text via Modell mit
opType=neutralization - Text → neutralisieren via
StringParser+ Modell mitopType=neutralization - Platzhalter-Mapping in
DataNeutralizerAttributespersistieren - Nur neutralisierte Version im RAG indizieren
- Bei
neutralize=false: Direkt indizieren (wie bisher) - Re-Neutralisierung bei Flag-Änderung (async Batch-Job)
Akzeptanz:
- Neutralisierte Datenquellen: nur neutralisierte Version im RAG
- Mapping-Tabelle wird korrekt befüllt
- Re-Neutralisierung bei Flag-Änderung funktioniert
Abhängigkeiten: AP 3.1, AP 2.1
AP 3.3 — [BE] Neutralisierung: AI-Call-Integration + Re-Hydrierung
Beschreibung: Bei AI-Calls mit requireNeutralization=true: Prompt live neutralisieren und Response re-hydrieren.
Dateien:
- Workflow-Manager / Chat-Pipeline — Pre-/Post-Processing
gateway/modules/workflows/workflowManager.py
Schritte:
- Pre-Processing: Wenn
requireNeutralization=true:- User-Prompt durch Neutralisierungs-Pipeline
- RAG-Kontext-Dokumente: bereits neutralisiert (aus RAG-Index)
- Prompt-Mapping in temporärer Tabelle
- AI-Call mit neutralisiertem Prompt + neutralisierten Dokumenten
- Post-Processing: AI-Response re-hydrieren
- Platzhalter via Mapping-Tabelle durch Originale ersetzen
- Konsistenz:
[PERSON_1]= immer derselbe Originalwert (persistent pro Datenquelle)
- Re-hydrierte Response an User ausliefern
Akzeptanz:
- Live-Neutralisierung von User-Prompts funktioniert
- Re-Hydrierung ersetzt Platzhalter korrekt
- Platzhalter-Konsistenz über Calls hinweg
Abhängigkeiten: AP 3.1, AP 3.2
AP 3.4 — [FE] ChatWorkflow-Transparenz: „Gesendete Daten"
Beschreibung: Im Chat-UI: aufklappbarer Bereich, der die neutralisierten Dokumente zeigt, die an das AI-Modell gesendet werden.
Dateien:
- Chat-UI-Komponente — Neue Sektion „Gesendete Daten (neutralisiert)"
Schritte:
- API liefert
ActionDocument-Liste mitneutralized=trueMetadaten im ChatWorkflow - UI: Aufklappbarer Bereich unter jedem AI-Call
- Anzeige: Dokumentname, Neutralisierungs-Status, Vorschau des neutralisierten Texts
- Hinweis wenn Dokument übersprungen wurde (Fail-Safe)
- Link zur Neutralisierungs-Konfiguration der Datenquelle
Akzeptanz:
- User sieht bei jedem AI-Call, was rausgegangen ist
- Übersprungene Dokumente sind sichtbar mit Grund
- Aufklappbar (nicht standardmässig offen)
Abhängigkeiten: AP 3.3
AP 3.5 — [FE] Neutralisierung: User-Kontrolle
Beschreibung: UI für Einsicht und Verwaltung der neutralisierten Daten und Platzhalter-Mappings.
Dateien:
- Neue Seite oder Sektion im Settings-Bereich
Schritte:
- Übersicht: Alle Datenquellen mit Neutralisierungs-Status
- Pro Datenquelle: Detailansicht der Platzhalter-Mappings (Original ↔ Platzhalter)
- Löschen: Einzelne Mappings oder alle Mappings einer Datenquelle
- Status:
pending,completed,failed,not_required - Re-Trigger: Neutralisierung manuell neu anstossen
Akzeptanz:
- User kann alle Mappings einsehen
- Löschen funktioniert
- Status ist korrekt und aktuell
Abhängigkeiten: AP 3.2
AP 3.6 — [BE] RAG-Scopes: Vollständige Implementierung
Beschreibung: Alle vier Scopes (personal, featureInstance, mandate, global) vollständig implementiert mit korrekter Union-Query und RBAC.
Dateien:
- RAG-Query-Engine — vollständige Scope-Logik
- RBAC-Layer — Scope-Berechtigungen
Schritte:
personal: Nur Daten des anfragenden UsersfeatureInstance: Alle Daten der aktuellen Instanz (alle User mit FeatureAccess)mandate: Alle Daten aller Instanzen im Mandatglobal: Alle plattformweiten Daten (read-only, nur sysadmin setzbar)- Union-Query: Effiziente Kombination aller anwendbaren Scopes
- Caching: Scope-Metadaten cachen für Performance
Akzeptanz:
- Alle Scope-Kombinationen funktionieren korrekt
- User sieht nie Daten ausserhalb seiner Berechtigung
- Performance: Union-Query < 500ms
Abhängigkeiten: AP 2.2, AP 3.2
AP 3.7 — [FE] Onboarding-Assistant
Beschreibung: Kontextsensitiver Onboarding-Begleiter für neue User und leere Zustände.
Dateien:
frontend_nyla/src/components/OnboardingAssistant.tsx— NEU
Schritte:
- Trigger-Bedingungen: Kein Mandate, keine Instanzen, keine Chats, nach Pause
- Schritt 1: Mandant-Typ bestätigen (bei OAuth)
- Schritt 2: Erste Feature-Instanz aktivieren (Empfehlung: Workspace)
- Schritt 3: Erste Datenquelle einbinden (Upload oder Konnektor)
- Schritt 4: Erster AI-Call (geführter Prompt)
- Kontextsensitiv: Erscheint bei neuen Features, nach Pausen, bei leeren Zuständen
- Dismissable: User kann jederzeit überspringen, aber Assistant kommt bei relevantem Trigger zurück
Akzeptanz:
- Neue User durchlaufen den 4-Schritt-Flow
- Assistant erscheint kontextsensitiv
- Kein Nerv-Faktor (smart triggers, nicht bei jedem Login)
Abhängigkeiten: AP 2.9
AP 3.8 — [BE/FE] FeatureInstance als UI-Scope (Semantische Verschiebung)
Beschreibung: Features werden zu reinen Workflow-Oberflächen. Die FeatureInstance definiert den UI-Kontext, nicht mehr die Datengrenze. Der Unified Data Layer ist die Datengrenze.
Dateien:
- Feature-Logik in allen Features — Daten-Queries auf UDL umstellen
- Instanz-Referenzen — von Daten-Ownership auf UI-Scope
Schritte:
- Daten-Queries: Von
WHERE featureInstanceId = Xauf Scope-basierte RAG-Queries umstellen featureInstanceIdbleibt als Herkunftsreferenz (Quellenschutz), steuert aber nicht mehr den Zugriff- Zugriff wird über Scope + RBAC gesteuert
- Feature-Instanz liefert: Workflow-Oberfläche, Feature-spezifische Substrukturen, Default-Scope-Kontext
- Alle Features verifizieren: Datenfluss via UDL statt Instanz-Silo
Akzeptanz:
- Features zeigen Daten aus dem UDL (nicht nur eigene Instanz)
- Cross-Feature-Datennutzung funktioniert
featureInstanceIddient nur noch als Herkunftsinfo
Abhängigkeiten: AP 3.6, AP 2.9, AP 2.10
Zusammenfassung
| Phase | Arbeitspakete | Schwerpunkt |
|---|---|---|
| Phase 1 | AP 1.1 — 1.15 (15 APs) | Mandanten-Grenze, Registrierung, Store, Migration, Löschung |
| Phase 2 | AP 2.1 — 2.10 (10 APs) | UDB, Scope-Tagging, RAG-Filter, Cross-Feature-Zugriff |
| Phase 3 | AP 3.1 — 3.8 (8 APs) | Neutralisierung, RAG-Scopes, Onboarding-Assistant, UI-Scope-Shift |
| Total | 33 Arbeitspakete |
Abhängigkeitsgraph (kritischer Pfad)
Phase 1:
AP 1.1 (mandateType) ──┬── AP 1.2 (Subscription PENDING) ── AP 1.3 (_provision)
│ │
│ ┌──────────────────────────────────────┘
│ │
├── AP 1.4 (Register Local) ── AP 1.11 (FE Register)
│ │
├── AP 1.5 (Register OAuth) ── AP 1.12 (FE Login + Wizard)
│ │
├── AP 1.6 (Store Refactoring) ── AP 1.7 (Auto-Mandate) ── AP 1.13 (FE Store)
│
├── AP 1.8 (Subscription Volume) ── AP 1.14 (FE Volume)
│
├── AP 1.9 (Migration Script) ── AP 1.15 (Bootstrap)
│
└── AP 1.10 (Mandanten-Löschung)
Phase 2: (nach Phase 1)
AP 2.1 (Scope-Felder) ── AP 2.2 (RAG Scope-Filter) ── AP 2.3 (Tagging API)
│
AP 2.4 (UDB Extraktion) ── AP 2.5 (Chats) ─┐ │
AP 2.6 (Files) ──┤── AP 2.8 (DnD) ── AP 2.9 (Integration)
AP 2.7 (Sources)─┘
│
AP 2.10 (Konsolidierung) ─────────────────────────────────────────┘
Phase 3: (nach Phase 2)
AP 3.1 (Fail-Safe) ── AP 3.2 (RAG-Integration) ── AP 3.3 (AI-Call + Rehydrate) ── AP 3.4 (FE Transparenz)
│
└── AP 3.5 (FE User-Kontrolle)
AP 3.6 (RAG-Scopes komplett) ── AP 3.8 (UI-Scope-Shift)
AP 3.7 (Onboarding-Assistant)
Umsetzungsplan-Version: 2026-03-23 v1 — Basierend auf Konzeptdokument v4. 33 Arbeitspakete in 3 Phasen.