14 KiB
Architektur-Review: Multi-Mandate Onboarding und Store-Konzept
Gegenstand: Multi-Mandate-Onboarding-und-Store-Konzept.md v3, 2026-03-23
Zweck: Kritischer Review der Zielarchitektur — Idee, Konzept, Modelle, Datenflüsse und Konsistenz. Keine Bewertung von Migrations- oder Implementierungsdetails.
1. Gesamtbewertung
Das Konzept definiert eine kohärente Zielarchitektur mit sechs Entscheidungen, die sich gegenseitig stützen: Mandate-per-Registration schafft die Tenant-Grenze, der Unified Data Layer eliminiert Datensilos, die UDB macht den Data Layer navigierbar, die Neutralisierung sichert den Datenfluss ab, und das RAG mit Scope-Tagging bildet den Plattformkern.
Stärken:
- Die Architektur löst ein reales, messbares Problem (Shared Root, Datensilos, fehlender Upgrade-Pfad).
- Mandate-per-Registration mit explizitem Store-Kontext ist sauber durchdacht und vermeidet implizite Logik.
- Unified Data Layer mit RAG-Scopes ist das richtige Abstraktionsniveau — weder zu granular noch zu grob.
- Die UDB als featureübergreifende Komponente mit Chat-Baum, Drag-and-Drop-Kontext und Inline-Tagging ist ein klarer Differenzierungsfaktor, den kein Wettbewerber in dieser Form bietet.
- Neutralisierung mit Fail-Safe-Regel ("kein Fallback auf Originaldaten") ist die einzig vertretbare Design-Entscheidung für regulierte Branchen.
- Operation Type statt "spezielle LLMs" nutzt das bestehende Modellsystem sauber.
2. Architektur: Mandate-per-Registration
2.1 Stimmigkeit des Mandanten-Modells
Die Dreiteilung system / personal / company ist klar und deckt die Kundenprofile ab. Der Upgrade-Pfad Personal → Company (Team einladen, Label ändern) ist elegant, weil er kein neues Benutzerkonto erfordert.
Offener Punkt: Ist mandateType mutabel (Personal → Company bei Einladung) oder immutabel? Wenn mutabel: Es sollte keine Geschäftslogik hart an personal vs. company gebunden sein. Wenn immutabel: Der "Upgrade" ist fachlich unklar. Empfehlung: Mutabel, rein informativ — keine Feature-Gates auf Basis von mandateType.
2.2 Redundanz isSystem vs. mandateType=system
Beide drücken dasselbe aus. Empfehlung: Eines der beiden Felder eliminieren oder klar trennen — isSystem als operativer Delete-Schutz, mandateType als fachliche Semantik.
2.3 Zwei Registrierungs-Flows: Vollständigkeit
Die zwei Flows (Personal/Trial und Company/Standard) decken die Selbstregistrierung ab. Nicht behandelt:
- OAuth-Registrierung (Google, MSAL): Kein Formular mit "Personal vs. Company". Lösung: Onboarding-Wizard nach erstem OAuth-Login.
- Invitation-Flow: User registriert sich via Einladung. Bekommt er ein eigenes Mandate UND Zugang zum Einladungs-Mandate? Das Konzept sagt ja — sinnvoll, da der User auch ausserhalb des einladenden Mandanten arbeiten können soll.
2.4 Subscription-Timing
Trial-Start ab Registrierung oder ab erstem Login? Bei Magic-Link-Flow vergehen Stunden. Empfehlung: PENDING-Status bei Registrierung, Aktivierung bei erstem Login.
3. Feature Store: Expliziter Kontext und Orphan Control
3.1 Expliziter Mandanten-Kontext
Die Entscheidung "nie implizit, immer explizites mandateId" ist architektonisch sauber und eliminiert eine ganze Klasse von Mehrdeutigkeits-Bugs. Für Solo-Mandant-User (ein Mandat) ist die UX trivial; für Multi-Mandat-User ist die explizite Auswahl notwendig und richtig.
3.2 Orphan Control: Architektonische Bewertung
Das Prinzip "letzter User deaktiviert → Instanz wird gelöscht" ist konsequent und verhindert Kapazitäts-Leaks. Technisch muss die Prüfung atomar sein (Race Condition bei gleichzeitiger Deaktivierung), aber das ist ein Implementierungsdetail, kein Architekturproblem.
3.3 Store-Aktivierung bei existierender Instanz
Wenn zwei Admins desselben Mandanten dasselbe Feature aktivieren — was passiert? Das Konzept muss klären: Maximal eine Instanz pro Feature pro Mandat via Store (dann: zweiter Admin bekommt nur FeatureAccess, keine neue Instanz) oder mehrere Instanzen erlaubt (dann: andere UX-Logik).
3.4 Store-UX für Nicht-Admins
Ein eingeladener User ist kein Admin und kann nichts aktivieren. Sieht er den Store? Empfehlung: Store als read-only Feature-Katalog zeigen oder via Navigation-RBAC ausblenden.
4. Unified Data Layer und RAG
4.1 Architektonische Schlüssigkeit
Die Entscheidung, Datensilos aufzulösen (CommCoach-Voice parallel zu Workspace, doppelte Sprachdefinitionen), ist richtig und überfällig. Der Unified Data Layer als mandantenweite Datenschicht mit Features als "Workflow-Oberflächen" ist das korrekte Zielbild.
Die Beibehaltung von featureInstanceId und _createdBy als Herkunftsreferenzen (Quellenschutz) bei gleichzeitiger mandantenweiter Sichtbarkeit ist eine elegante Lösung: kein Breaking Change auf Datenebene, aber neue Zugriffsmuster via Scope.
4.2 RAG-Scopes: Konzeptionelle Bewertung
Die vier Scopes (personal / featureInstance / mandate / global) bilden eine vollständige Hierarchie:
global ⊃ mandate ⊃ featureInstance ⊃ personal
Dies ist sauber und erlaubt feingranulare Steuerung. Jeder Scope ist klar abgegrenzt, es gibt keine Überlappung.
Kritischer Punkt: Der Scope global ist mächtig — eine falsch getaggte Datenquelle wäre plattformweit sichtbar. Das Konzept adressiert dies nicht explizit. Empfehlung: scope=global nur durch sysadmin setzbar, RBAC-geschützt.
4.3 Datenquellen-Tagging: UX-Bewertung
Das Inline-Tagging in der UDB (Scope-Symbol + Neutralisierungs-Symbol neben jeder Datenquelle) ist elegant gelöst. Kein Dialog, kein Workflow-Bruch. Der Unterschied zwischen "Browse Sources" (Katalog, keine Icons) und "Active Sources" (eingebunden, mit Icons) ist logisch und intuitiv.
Default personal + neutralize=false ist der richtige Default: konservativ für Sichtbarkeit (nur der User), offen für Neutralisierung (User entscheidet bewusst). Der User muss aktiv handeln, um Daten breiter zu teilen — Privacy-by-Default.
4.4 Fehlendes konkretes Datenmodell
Das Konzept beschreibt den Unified Data Layer fachlich, aber nicht als Datenmodell. Offene Fragen:
- Neue Entität
DataSourcemitscope,neutralize,featureInstanceId,createdBy? - Oder Erweiterung bestehender Modelle um
scopeundneutralize? - Wo lebt der RAG-Index physisch? Eigene DB? pgvector in
poweron_app? - Scope-Metadaten im Vektorspeicher: Wie effizient ist die Union-Query über vier Scopes?
Empfehlung: Separates Konzeptdokument für Phase 2 mit konkretem Datenmodell.
4.5 Store vs. Unified Data Layer: Semantische Verschiebung über die Phasen
In Phase 1 erstellt der Store eine FeatureInstance (Instanz = Datengrenze). In Phase 3 sind Features reine Workflow-Oberflächen auf dem Unified Layer — was "erstellt" der Store dann? Die Instanz wird zum UI-Scope statt zum Daten-Scope. Das ist ein fundamentaler Bedeutungswandel von FeatureInstance, der im Phasenplan klarer werden sollte.
5. Unified Data Bar (UDB)
5.1 Architektonische Bewertung
Die UDB als plattformweite, wiederverwendbare Komponente (extrahiert aus dem Workspace) ist die richtige Entscheidung. Sie löst drei Probleme gleichzeitig:
- Datennavigation: Ein Ort für alle Daten, Chats und Quellen.
- Cross-Feature-Kontext: Drag-and-Drop von Chats/Files/Sources in Prompts ermöglicht featureübergreifende Analysen.
- Konsistenz: Alle Features haben dieselbe Datensidebar, keine Duplizierung.
5.2 Chat-Baum: Bewertung
Die hierarchische Chat-Struktur (Feature-Instanzen als Top-Level, Chats darunter, feature-spezifische Substrukturen wie CommCoach → Coaching-Modul → Sessions) ist ein starkes Konzept. Es gibt dem User eine Übersicht, die heute nirgends existiert — weder in ChatGPT (flache Ordner), Langdock (flache Projects), noch in Copilot (pro-App-Silos).
Kritischer Punkt: Bei vielen Feature-Instanzen und Hunderten von Chats kann der Baum unübersichtlich werden. Empfehlung: Suchfunktion im Chats-Tab und optionaler Flat-Mode (chronologische Liste ohne Hierarchie) als Alternative.
5.3 Drag-and-Drop als Kontext-Steuerung
Das Prinzip "jedes UDB-Element kann in den Prompt gezogen werden" ist mächtig und intuitiv. Die Use Cases (Cross-Feature-Analyse, Reporting über Instanzen hinweg, Coaching-Review) demonstrieren den Mehrwert klar.
Offener Punkt: Was passiert mit dem Neutralisierungs-Flag, wenn ein neutralisierter Chat in einen Prompt gezogen wird? Wird der neutralisierte Text übergeben oder der Original-Text? Konsistent mit der Fail-Safe-Regel sollte immer die neutralisierte Version übergeben werden, wenn das Flag gesetzt ist.
5.4 Wettbewerbsanalyse: Einordnung
Die Wettbewerbstabelle ist präzise. PageSpace ist der nächste Vergleich (einheitlicher Baum), aber ohne Mandanten-Modell, RAG-Scopes und Neutralisierung. Die Kombination aus diesen vier Dimensionen (Hierarchischer Chat-Baum + Scope-Tagging + Neutralisierung + Multi-Tenant) ist tatsächlich ein Alleinstellungsmerkmal.
Risiko: PageSpace und ähnliche Startups bewegen sich schnell. Das Fenster für die Differenzierung ist zeitlich begrenzt. Die UDB sollte in Phase 2 Priorität haben, nicht erst in Phase 3.
6. Neutralisierung
6.1 Architektonische Schlüssigkeit
Die Zwei-Flag-Steuerung (Datenquelle + AI-Call) mit OR-Verknüpfung ist einfach und korrekt. Die Fail-Safe-Regel ("Neutralisierung fehlgeschlagen = Dokument nicht weitergeben") ist die einzig vertretbare Entscheidung für den Zielmarkt (regulierte Branchen). Kein Kompromiss hier ist richtig.
6.2 Operation Type statt spezielle LLMs
Die Nutzung des bestehenden Modellsystems (Operation Type neutralization) statt dedizierter "Neutralisierungs-LLMs" ist architektonisch sauber. Es nutzt die vorhandene Modellverwaltung und vermeidet eine parallele Infrastruktur.
6.3 ChatWorkflow-Transparenz
Die Entscheidung, neutralisierte Dokumente im ChatWorkflow-Objekt als sichtbare Dokumente mitzugeben, ist ein starker Trust-Mechanismus. Der User sieht, was rausgeht. Das ist nicht nur ein Feature, sondern ein Verkaufsargument für regulierte Branchen.
6.4 Latenz-Betrachtung
Die Pipeline hat drei Phasen mit unterschiedlicher Latenz-Charakteristik:
| Phase | Zeitpunkt | Latenz-kritisch? |
|---|---|---|
| Datenquellen-Neutralisierung | Beim Einbinden ins RAG | Nein (asynchron, Batch) |
| Prompt-Neutralisierung | Live, bei jedem AI-Call | Ja — User wartet |
| Response-Re-Hydrierung | Post-Processing | Nein (String-Replacement aus Mapping-Tabelle) |
Die Datenquellen-Neutralisierung (Phase 1) ist unkritisch, da sie beim Einbinden geschieht und nur die neutralisierte Version im RAG landet. Die Re-Hydrierung ist ein einfaches String-Replacement.
Kritisch ist die Prompt-Neutralisierung: Wenn der User im Chat einen Kundennamen tippt und requireNeutralization=true gesetzt ist, muss der Prompt live neutralisiert werden. Das erfordert ein schnelles Modell. Empfehlung: Für Prompt-Neutralisierung ein leichtgewichtiges, lokales Modell oder Regex-basierte Vorfilterung evaluieren, um die Latenz unter 500ms zu halten.
6.5 Platzhalter-Konsistenz
Die Mapping-Tabelle muss über AI-Calls hinweg konsistent sein. [PERSON_1] muss immer "Max Müller" bedeuten, nicht einmal "Max Müller" und einmal "Anna Schmidt". Die Empfehlung: Mapping-Einträge persistent pro Datenquelle, nicht session-scoped. Bei AI-Calls wird das aktive Mapping als Kontext mitgegeben.
6.6 Betriebsmodell für Modelle mit Operation Type neutralization
Die Neutralisierung sieht alle sensiblen Daten im Klartext. Das Modell muss mindestens so vertrauenswürdig sein wie der Mandant selbst. Offene Frage: Self-hosted (GPU-Infrastruktur) oder CH-Provider mit DSG-konformem SLA? Das hat Infrastruktur- und Kostenimplikationen und sollte als eigene Entscheidung dokumentiert werden.
7. Konsistenz und offene Architektur-Fragen
| Thema | Frage | Empfehlung |
|---|---|---|
mandateType-Mutabilität |
Personal → Company: Änderung oder neues Mandate? | Mutabel, keine Geschäftslogik daran binden |
| OAuth-Registrierung | Wo wählt ein OAuth-User den Mandant-Typ? | Onboarding-Wizard nach erstem Login |
| Store: Existierende Instanz | Zweiter Admin aktiviert dasselbe Feature | Max. eine Store-Instanz pro Feature/Mandat; zweiter Admin bekommt FeatureAccess |
| Store in Phase 3 | Was "aktiviert" der Store, wenn Features nur UI-Oberflächen sind? | FeatureInstance wird UI-Scope, nicht Daten-Scope — im Phasenplan klären |
Scope global |
Wer darf plattformweite Daten erstellen? | Nur sysadmin, RBAC-geschützt |
| Drag-and-Drop + Neutralisierung | Was wird übergeben: Original oder neutralisierte Version? | Immer neutralisierte Version, wenn Flag gesetzt |
| Billing vs. RAG-Volumen | Wachsende Datenmenge = Infrastrukturkosten | Soft-Limit für RAG-Volumen pro Mandant (kein Billing, aber Kapazitätsparameter) |
| UDB-Skalierung | Hunderte Chats im Baum | Suchfunktion + optionaler Flat-Mode |
| Company-Onboarding | Was sieht ein Firmen-Admin nach Registrierung? | Definieren: autoCreate wie Personal, oder Feature-Auswahl-Wizard |
| Mandanten-Löschung | Kaskade: Instanzen → Daten → RAG → Mappings → Stripe | Im Konzept definieren |
8. Fazit
Die Zielarchitektur ist konzeptionell stark und in sich konsistent. Die sechs Entscheidungen greifen ineinander:
Mandate-per-Registration
→ saubere Tenant-Grenze
→ Own Instance im Store (expliziter Kontext)
→ Unified Data Layer pro Mandant
→ RAG mit Scope-Tagging als Plattformkern
→ UDB als Navigation + Kontext-Steuerung
→ Neutralisierung als Fail-Safe-Pipeline
Die UDB mit hierarchischem Chat-Baum, Drag-and-Drop-Kontext, Scope-Tagging und Neutralisierung ist das architektonische Herzstück und ein belegbares Alleinstellungsmerkmal.
Die Neutralisierungs-Pipeline mit Fail-Safe-Regel und ChatWorkflow-Transparenz ist die richtige Antwort auf den Zielmarkt (regulierte Schweizer Branchen).
Die wichtigsten offenen Architektur-Fragen (Tabelle oben) betreffen Edge Cases und Phasenübergänge, nicht die Kernentscheidungen. Das Fundament stimmt.
Empfehlung für nächste Konzeptdokumente:
- Unified Data Layer: Datenmodell (Phase 2) — Entitäten, Scope-Persistenz, RAG-Index-Architektur
- Neutralisierung: Betriebsmodell — Trusted-Model-Infrastruktur, Latenz-Budget, Platzhalter-Konsistenz
- UDB: Komponentenarchitektur — Extraktion aus Workspace, State Management, Drag-and-Drop-API
Review-Version: 2026-03-23 v2 — Basierend auf Konzeptdokument v3. Fokus: Zielarchitektur, Idee, Konzept und Modelle.