# 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.mana.how | | Contacts | 5184 | contacts.mana.how | | Todo | 5188 | todo.mana.how | | Chat | 5174 | chat.mana.how | | Clock | 5187 | clock.mana.how | | Picture | 5185 | picture.mana.how | 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