From c6677a8a1bfb45d0ad7b394e3819c66462f04c9c Mon Sep 17 00:00:00 2001 From: Till-JS <101404291+Till-JS@users.noreply.github.com> Date: Fri, 12 Dec 2025 03:48:11 +0100 Subject: [PATCH] docs(architecture): add Workspace Orchestrator architecture decision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document the architecture decision for a modular multi-app system with: - Split-screen functionality between apps - Cross-app drag & drop support - Flexible deployment configurations - Scalability for 20+ apps Evaluates 5 approaches and explains why Micro-Frontend Orchestrator was chosen over monolith and other alternatives. πŸ€– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- docs/architecture/WORKSPACE_ORCHESTRATOR.md | 507 ++++++++++++++++++++ 1 file changed, 507 insertions(+) create mode 100644 docs/architecture/WORKSPACE_ORCHESTRATOR.md diff --git a/docs/architecture/WORKSPACE_ORCHESTRATOR.md b/docs/architecture/WORKSPACE_ORCHESTRATOR.md new file mode 100644 index 000000000..8c9de17a6 --- /dev/null +++ b/docs/architecture/WORKSPACE_ORCHESTRATOR.md @@ -0,0 +1,507 @@ +# ManaCore Workspace Orchestrator + +> Architektur-Entscheidung fΓΌr modulares Multi-App-System mit Split-Screen und Drag & Drop + +**Status:** Proposal +**Datum:** 2024-12-12 +**Autor:** Till Schneider / Claude + +--- + +## Executive Summary + +Dieses Dokument beschreibt die Architektur des **ManaCore Workspace Orchestrators** - ein modulares System, das es ermΓΆglicht: + +1. Mehrere Apps nebeneinander im Split-Screen anzuzeigen +2. Drag & Drop zwischen Apps zu unterstΓΌtzen +3. Flexible Deployments mit unterschiedlichen App-Kombinationen zu erstellen +4. Die Anzahl der Apps beliebig zu skalieren + +--- + +## Problemstellung + +### Aktuelle Situation + +Das ManaCore-Γ–kosystem besteht aus mehreren unabhΓ€ngigen SvelteKit-Anwendungen: + +| App | Port (Dev) | Domain (Prod) | +|-----|------------|---------------| +| Calendar | 5179 | calendar.manacore.app | +| Contacts | 5184 | contacts.manacore.app | +| Todo | 5188 | todo.manacore.app | +| Chat | 5174 | chat.manacore.app | +| Clock | 5187 | clock.manacore.app | +| Picture | 5185 | picture.manacore.app | + +Jede App ist eine **eigenstΓ€ndige SvelteKit-Instanz** mit: +- Eigenem Dev-Server und Production-Build +- Eigener Domain/Subdomain +- Eigenem Backend (NestJS) +- Geteilter Auth ΓΌber Mana Core Auth (JWT) + +### Anforderungen + +1. **Split-Screen:** Zwei Apps nebeneinander anzeigen +2. **Drag & Drop:** Elemente zwischen Apps verschieben (z.B. Kontakt auf Kalender droppen) +3. **Modulare Deployments:** Kunde A bekommt nur Calendar+Todo, Kunde B bekommt alles +4. **Skalierbarkeit:** System muss mit 20+ Apps funktionieren +5. **Wartbarkeit:** Neue Apps einfach hinzufΓΌgen + +### Warum die aktuelle Architektur nicht ausreicht + +- **Separate Browser-Tabs:** Kein Drag & Drop zwischen Tabs mΓΆglich +- **iFrames:** Drag & Drop ΓΌber iFrame-Grenzen ist technisch problematisch (CORS, Event-Blocking) +- **Keine geteilte State:** Jede App hat eigenen Svelte-Kontext + +--- + +## Evaluierte AnsΓ€tze + +### 1. Build-Time Feature Flags + +**Konzept:** Zur Build-Zeit konfigurieren welche Apps inkludiert werden. + +```bash +ENABLED_APPS=calendar,todo pnpm build +``` + +**Bewertung:** +- βœ… Minimale Bundle-Size +- βœ… Einfaches Konzept +- ❌ Neuer Build pro Konfiguration nΓΆtig +- ❌ Keine dynamische Aktivierung +- ❌ Viele Build-Artefakte zu managen + +**Fazit:** Zu unflexibel fΓΌr unterschiedliche Deployment-Szenarien. + +--- + +### 2. Plugin-Architektur (Runtime Loading) + +**Konzept:** Apps als Plugins zur Laufzeit laden. + +```typescript +// manifest.json +{ + "apps": [ + { "id": "calendar", "enabled": true, "url": "/plugins/calendar.js" } + ] +} +``` + +**Bewertung:** +- βœ… Ein Build, viele Konfigurationen +- βœ… Dynamische Aktivierung mΓΆglich +- ❌ Komplexe Plugin-API +- ❌ Versionierung zwischen Plugins +- ❌ Initiale Ladezeit durch viele Chunks + +**Fazit:** Guter Ansatz, aber zu komplex fΓΌr unsere Anforderungen. + +--- + +### 3. Monorepo mit Conditional Exports + +**Konzept:** Alle Apps als separate Packages, verschiedene Entry-Points pro Deployment. + +``` +packages/ +β”œβ”€β”€ app-calendar/ +β”œβ”€β”€ app-todo/ +└── ... + +deployments/ +β”œβ”€β”€ full/ # Alle Apps +β”œβ”€β”€ productivity/ # Calendar + Todo +└── crm/ # Contacts + Calendar +``` + +**Bewertung:** +- βœ… Klare Package-Grenzen +- βœ… Gutes Dependency-Management +- ❌ Viele Packages zu maintainen +- ❌ Versionskoordination aufwΓ€ndig + +**Fazit:** Solide, aber zu viel Overhead. + +--- + +### 4. Monolith (Alle Apps in einer SvelteKit-Instanz) + +**Konzept:** Alle Apps in eine einzige SvelteKit-App zusammenfΓΌhren. + +``` +src/routes/ +β”œβ”€β”€ calendar/[...rest] +β”œβ”€β”€ todo/[...rest] +└── contacts/[...rest] +``` + +**Bewertung:** +- βœ… Triviales Drag & Drop (alles im selben DOM) +- βœ… Gemeinsamer Svelte-Store +- βœ… Einfache Implementierung +- ❌ **Keine flexiblen Deployments mΓΆglich** +- ❌ Bundle enthΓ€lt immer alle Apps +- ❌ Skaliert schlecht bei 20+ Apps +- ❌ Einzelne Apps nicht unabhΓ€ngig deploybar + +**Fazit:** LΓΆst Drag & Drop, aber widerspricht den ModularitΓ€ts-Anforderungen. + +--- + +### 5. Micro-Frontend Orchestrator (GewΓ€hlt) + +**Konzept:** Kombination aus Shell-Anwendung, App-Registry und Build-Optimierung. + +**Bewertung:** +- βœ… Flexibel: Build-Time ODER Runtime-Konfiguration +- βœ… Skaliert auf viele Apps +- βœ… Klare Contracts zwischen Apps +- βœ… Drag & Drop ist First-Class-Citizen +- βœ… Code-Splitting out of the box +- βœ… Apps kΓΆnnen einzeln oder zusammen deployed werden +- ⚠️ Initialer Setup-Aufwand + +**Fazit:** Bester Trade-off zwischen FlexibilitΓ€t und KomplexitΓ€t. + +--- + +## GewΓ€hlte Architektur: Micro-Frontend Orchestrator + +### Architektur-Übersicht + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ Workspace Shell β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ App Registry β”‚ Drag Context β”‚ Split Router β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ App Manifest β”‚ +β”‚ { "calendar": {...}, "todo": {...}, "contacts": {...} } β”‚ +β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ Calendar β”‚ β”‚ Todo β”‚ β”‚ Contacts β”‚ ... β”‚ +β”‚ β”‚ Module β”‚ β”‚ Module β”‚ β”‚ Module β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ ↑ ↑ ↑ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ Shared Services Layer β”‚ +β”‚ (Auth, Theme, i18n, API Client, Drag/Drop) β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +### Kernkomponenten + +#### 1. Workspace Shell + +Die Γ€ußere HΓΌlle, die immer geladen wird: + +- **Split-Pane Layout:** Rendert 1-2 App-Panels nebeneinander +- **App Registry:** Kennt alle verfΓΌgbaren Apps und ihre Capabilities +- **Drag Context:** Globaler Drag-Layer ΓΌber allen Panels +- **Navigation:** PillNavigation mit App-Switcher fΓΌr Split-Screen + +#### 2. App Module + +Jede App ist ein eigenstΓ€ndiges Modul: + +```typescript +interface ManaAppModule { + // Identifikation + id: string; // 'calendar' + name: string; // 'Kalender' + icon: string; // App-Icon + color: string; // PrimΓ€rfarbe + + // Capabilities + draggable: DragType[]; // Was kann aus dieser App gedraggt werden? + droppable: DropHandler[]; // Was kann diese App empfangen? + + // UI + component: SvelteComponent; // Haupt-Komponente + routes: RouteDefinition[]; // Interne Routes + + // Optional + toolbar?: SvelteComponent; // App-spezifische Toolbar + quickActions?: QuickAction[]; // FΓΌr QuickInputBar +} +``` + +#### 3. Drag & Drop Registry + +Zentrale Koordination fΓΌr Cross-App Drag & Drop: + +```typescript +// Drag-Types die Apps exportieren kΓΆnnen +type DragType = + | 'contact' // Kontakt-Karte + | 'event' // Kalender-Event + | 'task' // Todo-Task + | 'file' // Datei + | 'note'; // Notiz + +// Drop-Handler die Apps registrieren +interface DropHandler { + accepts: DragType[]; + zone: 'panel' | 'specific'; // Ganzes Panel oder spezifische Bereiche + onDrop: (item: DragItem, target: DropTarget) => void; + preview?: (item: DragItem) => SvelteComponent; +} +``` + +#### 4. Deployment-Konfiguration + +```typescript +// manacore.config.ts +export default defineWorkspace({ + // Welche Apps in diesem Build? + apps: ['calendar', 'todo', 'contacts'], + + // Wie werden Apps geladen? + loadStrategy: 'lazy', // 'eager' | 'lazy' | 'on-demand' + + // Feature-Flags pro App + features: { + calendar: { + views: ['week', 'month', 'agenda'], + sharing: true, + recurring: true, + }, + todo: { + projects: true, + labels: true, + recurring: false, + }, + contacts: { + import: true, + export: true, + googleSync: false, + } + }, + + // Erlaubte Drag & Drop Verbindungen + connections: [ + { from: 'contacts.contact', to: 'calendar.attendee' }, + { from: 'contacts.contact', to: 'todo.assignee' }, + { from: 'calendar.event', to: 'todo.task' }, + { from: 'todo.task', to: 'calendar.event' }, + ], + + // Default Split-Screen Konfiguration + defaultLayout: { + primary: 'calendar', + secondary: null, // Kein Split-Screen als Default + } +}); +``` + +### Build-Output + +``` +dist/ +β”œβ”€β”€ shell.js # Workspace Shell (~50KB) +β”œβ”€β”€ shared.js # Shared Services (~100KB) +β”œβ”€β”€ manifest.json # App-Konfiguration +└── apps/ + β”œβ”€β”€ calendar.js # Calendar Module (lazy) + β”œβ”€β”€ calendar.css + β”œβ”€β”€ todo.js # Todo Module (lazy) + β”œβ”€β”€ todo.css + β”œβ”€β”€ contacts.js # Contacts Module (lazy) + └── contacts.css +``` + +### Split-Screen URL-Schema + +``` +/workspace # Single App (Default) +/workspace?app=calendar # Calendar alleine +/workspace?left=calendar&right=todo # Split-Screen +/workspace?left=calendar&right=todo&split=60 # 60/40 Split +``` + +--- + +## Drag & Drop Implementierung + +### Globaler Drag-Layer + +```svelte + +
+ +
+ + {#if rightApp} + + + {/if} +
+ + + +
+``` + +### Drag-Flow + +1. **Drag Start:** App signalisiert Drag mit Type und Payload +2. **Drag Move:** Element wird im globalen Overlay gerendert +3. **Drag Over:** Drop-Zonen in allen Apps highlighten +4. **Drop:** Ziel-App erhΓ€lt Payload und verarbeitet ihn + +### Beispiel: Kontakt auf Kalender droppen + +```typescript +// Contacts App registriert Draggable +ContactsModule.draggable = [{ + type: 'contact', + getData: (contact) => ({ + id: contact.id, + name: contact.displayName, + email: contact.email, + }), + preview: ContactDragPreview, +}]; + +// Calendar App registriert Drop-Handler +CalendarModule.droppable = [{ + accepts: ['contact'], + zone: 'event-form', // Nur in Event-Formularen + onDrop: (item) => { + // Kontakt als Teilnehmer hinzufΓΌgen + addAttendee({ + name: item.data.name, + email: item.data.email, + }); + }, +}]; +``` + +--- + +## Deployment-Szenarien + +### Szenario 1: Vollversion (SaaS) + +```typescript +// manacore.config.ts +apps: ['calendar', 'todo', 'contacts', 'chat', 'files', 'notes', ...] +``` + +Alle Apps verfΓΌgbar, User kann Split-Screen frei konfigurieren. + +### Szenario 2: ProduktivitΓ€ts-Suite + +```typescript +// productivity.config.ts +apps: ['calendar', 'todo', 'notes'] +features: { + calendar: { sharing: false }, // Keine Team-Features +} +``` + +Fokussiertes Bundle fΓΌr Einzelnutzer. + +### Szenario 3: CRM-Paket + +```typescript +// crm.config.ts +apps: ['contacts', 'calendar', 'tasks'] +connections: [ + { from: 'contacts.contact', to: 'calendar.attendee' }, + { from: 'contacts.contact', to: 'tasks.assignee' }, +] +``` + +Kontakt-zentriertes Bundle mit relevanten VerknΓΌpfungen. + +### Szenario 4: Single-App (Legacy-KompatibilitΓ€t) + +```typescript +// calendar-only.config.ts +apps: ['calendar'] +features: { + splitScreen: false, // Kein Split-Screen UI +} +``` + +Einzelne App wie bisher, fΓΌr Migration bestehender User. + +--- + +## Warum nicht Monolith? + +Der Monolith-Ansatz (alle Apps in einer SvelteKit-Instanz) wurde bewusst **nicht gewΓ€hlt**, obwohl er Drag & Drop trivial machen wΓΌrde: + +| Kriterium | Monolith | Orchestrator | +|-----------|----------|--------------| +| Drag & Drop | Trivial | Erfordert Koordination | +| Bundle-Size | Immer alles | Nur aktivierte Apps | +| Flexible Deployments | Nicht mΓΆglich | Beliebig konfigurierbar | +| App-UnabhΓ€ngigkeit | Keine | VollstΓ€ndig | +| Skalierung (20+ Apps) | Problematisch | Kein Problem | +| Build-Zeit | WΓ€chst mit jeder App | Konstant pro App | +| Team-Arbeit | Merge-Konflikte | UnabhΓ€ngige Entwicklung | + +**Kernargument:** Bei wachsender App-Anzahl wird der Monolith unwartbar. Der Orchestrator skaliert linear, der Monolith exponentiell (in KomplexitΓ€t). + +--- + +## Migrations-Strategie + +### Phase 1: Workspace Shell erstellen + +- Neue App: `apps/workspace` +- Implementiert Shell, Registry, Drag-Layer +- Kann bestehende Apps als "Legacy iFrames" einbetten (Fallback) + +### Phase 2: App-Module extrahieren + +- Calendar, Todo, Contacts als Module refactoren +- Gemeinsame Komponenten in Shared Services +- Drag & Drop Contracts definieren + +### Phase 3: Schrittweise Migration + +- Eine App nach der anderen in Orchestrator integrieren +- Parallelbetrieb: Standalone + Workspace +- Alte Standalone-Deployments weiter unterstΓΌtzen + +### Phase 4: Neue Apps als Module + +- Alle neuen Apps direkt als Module entwickeln +- Einheitliche App-Template verwenden + +--- + +## Offene Fragen + +1. **Routing:** Wie verhalten sich Deep-Links im Split-Screen? +2. **State-Sync:** Sollen Apps Γ„nderungen in Echtzeit sehen? +3. **Mobile:** Split-Screen nur Desktop oder auch Tablet? +4. **Keyboard-Navigation:** Wie wechselt Fokus zwischen Panels? +5. **Undo/Redo:** Global oder pro Panel? + +--- + +## NΓ€chste Schritte + +1. [ ] Workspace Shell Proof-of-Concept +2. [ ] Drag & Drop Registry implementieren +3. [ ] Calendar als erstes Modul migrieren +4. [ ] Split-Screen Layout mit Resize +5. [ ] Deployment-Pipeline anpassen + +--- + +## Referenzen + +- [Module Federation](https://webpack.js.org/concepts/module-federation/) +- [Micro Frontends](https://micro-frontends.org/) +- [Svelte Context API](https://svelte.dev/docs#run-time-svelte-setcontext) +- [HTML Drag and Drop API](https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API)