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)