# Plugin-System: Zusammenfassung der Implementierung ## Executive Summary Das implementierte Plugin-System ermöglicht die Installation und Verwaltung von optionalen, lizenzierbaren Modulen in myCRM. Module sind vollständig unabhängige Composer-Packages, die ohne Änderungen am Core nachträglich installiert werden können und nur mit gültiger Lizenz funktionieren. ## Kernmerkmale ### ✅ Anforderung: Leicht nachträglich installierbar **Gelöst durch:** - Composer-basierte Installation (`composer require mycrm/modul-name`) - Symfony Flex Auto-Configuration für Bundle-Registrierung - Automatische Service-Discovery über Tagged Iterators - Keine manuelle Code-Änderung im Core erforderlich ### ✅ Anforderung: Keine Core-Abhängigkeiten **Gelöst durch:** - Interface-basierte Architektur (`ModulePluginInterface`, `LicenseValidatorInterface`) - Core kennt nur Interfaces, keine konkreten Module - Module registrieren sich selbst via Dependency Injection - Loose Coupling durch Event-System und Service-Tags ### ✅ Anforderung: Lizenzvalidierung erforderlich **Gelöst durch:** - REST-API basierte Lizenzprüfung gegen externen Server - JWT-Token Format für Lizenzschlüssel - Caching mit 24h TTL + 7 Tage Grace Period - Offline-Betrieb möglich (gecachte Validierung) - Module werden nur mit gültiger Lizenz gebootet ## Architektur-Komponenten ### 1. Core-System (Hauptprojekt) **Interfaces:** ``` /src/Plugin/ ├── ModulePluginInterface.php # Plugin-Contract └── LicenseValidatorInterface.php # Lizenz-Contract ``` **Implementierungen:** ``` /src/ ├── Plugin/ModuleRegistry.php # Plugin-Verwaltung ├── Service/LicenseValidator.php # Lizenzprüfung ├── EventListener/ModuleBootListener.php # Auto-Boot ├── Command/ │ ├── ModuleListCommand.php # CLI: Liste │ └── ModuleLicenseCommand.php # CLI: Lizenz-Verwaltung └── Controller/Api/ModuleManagementController.php # REST-API ``` **Frontend:** ``` /assets/js/views/ └── ModuleManagement.vue # Admin-UI ``` ### 2. Modul-Package (externes Repository) ``` mycrm-modulname/ ├── composer.json # Symfony Bundle Type ├── src/ │ ├── ModulnameModulePlugin.php # Implements ModulePluginInterface │ ├── ModulnameBundle.php # Symfony Bundle │ ├── DependencyInjection/ # Container Extension │ ├── Entity/ # Doctrine Entities │ ├── Controller/ # API Controllers │ ├── Security/Voter/ # Permissions │ └── Service/ # Business Logic ├── config/ │ ├── services.yaml # Service-Tag: app.module_plugin │ └── routes.yaml └── migrations/ # Doctrine Migrations ``` ## Workflow ### Installation eines Moduls ```mermaid graph TD A[composer require mycrm/modul] --> B[Composer installiert Package] B --> C[Symfony Flex registriert Bundle] C --> D[DI Container lädt Services] D --> E[ModuleRegistry erkennt Plugin via Tag] E --> F[Admin registriert Lizenz] F --> G[LicenseValidator prüft gegen Server] G --> H{Lizenz gültig?} H -->|Ja| I[ModuleBootListener bootet Modul] H -->|Nein| J[Modul bleibt inaktiv] I --> K[Modul verfügbar] ``` ### Lizenzvalidierung ```mermaid sequenceDiagram participant App as myCRM participant Cache as Cache participant Validator as LicenseValidator participant Server as Lizenzserver App->>Validator: validate("billing") Validator->>Cache: getCached("billing") alt Cache Hit & Grace Period aktiv Cache-->>Validator: Gecachte Lizenz Validator-->>App: Valid (cached) else Cache Miss oder abgelaufen Validator->>Server: POST /api/validate alt Server erreichbar Server-->>Validator: {valid: true, ...} Validator->>Cache: speichern (24h TTL) Validator-->>App: Valid else Server nicht erreichbar alt Gecachte Lizenz in Grace Period Validator-->>App: Valid (offline) else Keine Grace Period Validator-->>App: Invalid end end end ``` ## API-Übersicht ### REST-API Endpunkte ``` GET /api/modules # Alle Module auflisten GET /api/modules/{id} # Modul-Details POST /api/modules/{id}/license # Lizenz registrieren DELETE /api/modules/{id}/license # Lizenz widerrufen POST /api/modules/{id}/validate # Lizenz validieren GET /api/modules/licenses # Alle Lizenzen ``` ### CLI-Commands ```bash app:module:list # Module auflisten app:module:license [key] # Lizenz verwalten --revoke # Lizenz widerrufen --validate # Lizenz prüfen ``` ## Integration mit bestehendem System ### Permission-System Module können eigene Permission-Module registrieren: ```php public function getPermissionModules(): array { return ['billing', 'invoices', 'payments']; } ``` Diese werden automatisch im Role-Permission-System verfügbar und können über die bestehenden Voter geprüft werden: ```php $this->denyAccessUnlessGranted('VIEW', 'billing'); ``` ### API Platform Integration Modul-Entities implementieren `ModuleAwareInterface`: ```php class Invoice implements ModuleAwareInterface { public function getModuleName(): string { return 'billing'; } } #[ApiResource( security: "is_granted('VIEW', 'billing')" )] ``` ### Vue.js Frontend Module können eigene Vue-Komponenten bereitstellen: ```javascript // Modul-Package: assets/js/index.js export default { components: { InvoiceManagement }, routes: [/* ... */] } // Haupt-App: Bedingte Integration if (window.myCRM.modules.billing?.active) { app.use(BillingModule) } ``` ## Sicherheits-Features ### 1. Lizenzschlüssel-Speicherung - Environment-Variablen (`.env.local`) - Nicht im Git-Repository (`.env.local` in `.gitignore`) - Optional: Verschlüsselte DB-Speicherung ### 2. API-Zugriff - Alle Management-Endpunkte: `#[IsGranted('ROLE_ADMIN')]` - Lizenzschlüssel werden nie im Frontend exponiert - CSRF-Protection via Symfony ### 3. Offline-Schutz - Grace Period verhindert Dauerbetrieb ohne Validierung - Cache-TTL: 24 Stunden - Grace Period: 7 Tage nach letzter Validierung ### 4. Modul-Isolation - Module können Core nicht modifizieren - Eigene Doctrine Entity-Manager möglich - Eigene Namespaces, keine Konflikte ## Performance-Optimierung ### Caching-Strategie ``` Lizenzvalidierung: ├── Online-Check: Nur alle 24h ├── Cache-Hit: < 1ms └── Offline-Mode: Grace Period 7 Tage ``` ### Lazy-Loading - Module booten nur beim ersten Request - Frontend-Komponenten lazy-loaded - Doctrine-Mappings on-demand ### Service-Tagging - Automatische Plugin-Discovery - Kein manuelles Service-Scanning - Symfony DI Container optimiert ## Testing-Strategie ### Unit-Tests ```php class MyModulePluginTest extends TestCase { public function testIsLicensedWithValidLicense(): void { $validator = $this->createMock(LicenseValidatorInterface::class); $validator->method('validate')->willReturn(['valid' => true]); $plugin = new MyModulePlugin($validator); $this->assertTrue($plugin->isLicensed()); } } ``` ### Integration-Tests ```php class LicenseValidatorTest extends KernelTestCase { public function testValidateFetchesFromServer(): void { $client = $this->createMock(HttpClientInterface::class); // Mock HTTP-Response $validator = new LicenseValidator($client, ...); $result = $validator->validate('billing'); $this->assertTrue($result['valid']); } } ``` ### Functional-Tests ```php class ModuleManagementControllerTest extends WebTestCase { public function testListModulesRequiresAdmin(): void { $client = static::createClient(); $client->request('GET', '/api/modules'); $this->assertResponseStatusCodeSame(401); } } ``` ## Deployment-Checklist ### Erstinstallation - [ ] Core-System: `services_plugin.yaml` importieren - [ ] Environment: `LICENSE_SERVER_URL` setzen - [ ] Environment: `INSTANCE_ID` generieren - [ ] Cache-Clear: `php bin/console cache:clear` ### Modul-Installation - [ ] Composer: `composer require mycrm/modul-name` - [ ] Bundle: Automatisch registriert oder manuell in `bundles.php` - [ ] Migrations: `php bin/console doctrine:migrations:migrate` - [ ] Lizenz: `php bin/console app:module:license modul-name` - [ ] Cache: `php bin/console cache:clear` - [ ] Test: `php bin/console app:module:list` ### Produktion - [ ] `.env.local` mit Lizenzen auf Server deployen - [ ] Lizenzserver-Firewall: Zugriff erlauben - [ ] Monitoring: Lizenz-Ablaufdaten überwachen - [ ] Backup: `.env.local` in Backup einschließen ## Erweiterungsmöglichkeiten ### Bereits implementiert ✅ Interface-basierte Architektur ✅ Lizenzvalidierung mit Online/Offline-Modus ✅ CLI-Commands für Verwaltung ✅ REST-API für Admin-UI ✅ Vue.js Admin-Interface ✅ Integration mit Permission-System ✅ Caching mit Grace Period ✅ Composer-basierte Installation ### Zukünftige Features (optional) - 🔮 Multi-Tenancy-Support (mehrere Instanzen, eine Lizenz) - 🔮 Offline-Lizenzierung (Air-Gapped Systeme) - 🔮 Automatische Update-Benachrichtigungen - 🔮 Modul-Marketplace Integration - 🔮 Feature-Flags innerhalb von Modulen - 🔮 Modul-Dependencies (Modul A benötigt Modul B) - 🔮 Rollback-Mechanismus bei Installation ## Technologie-Stack ### Backend - PHP 8.3+ - Symfony 7.1 LTS - Doctrine ORM - API Platform - PSR-6 Cache (Symfony Cache) - PSR-3 Logger (Monolog) ### Frontend - Vue.js 3 (Composition API) - PrimeVue (UI-Komponenten) - Tailwind CSS ### DevOps - Composer (Package Management) - Symfony Flex (Auto-Configuration) - Doctrine Migrations ## Code-Statistik ``` Core-System (neu): ├── Interfaces: 2 Dateien ├── Services: 2 Dateien ├── Commands: 2 Dateien ├── Controller: 1 Datei ├── EventListener: 1 Datei └── Vue-Komponenten: 1 Datei Beispiel-Modul: ├── Plugin-Klasse: 1 Datei ├── Bundle: 1 Datei ├── DependencyInjection: 2 Dateien ├── Entity: 1 Datei (Beispiel) └── Konfiguration: 1 Datei Dokumentation: ├── PLUGIN_SYSTEM.md: Vollständige Anleitung ├── PLUGIN_SYSTEM_SUMMARY.md: Diese Datei ├── EXAMPLE_MODULE_STRUCTURE.md: Modul-Template └── example-module/: Code-Beispiele ``` ## Kosten-Nutzen-Analyse ### Vorteile ✅ **Modularität**: Kunden zahlen nur für benötigte Features ✅ **Wartbarkeit**: Module unabhängig updatebar ✅ **Skalierbarkeit**: Beliebig viele Module möglich ✅ **Lizenzierung**: Automatische Kontrolle über Funktionen ✅ **Entwicklung**: Parallele Modul-Entwicklung möglich ✅ **Testing**: Module isoliert testbar ✅ **Deployment**: Schrittweise Einführung möglich ### Aufwand ⚠️ **Initial**: ~2-3 Tage für Core-System (bereits implementiert) ⚠️ **Pro Modul**: ~1-2 Tage zusätzlich für Plugin-Setup ⚠️ **Lizenzserver**: Separater Service erforderlich ⚠️ **Dokumentation**: Pro Modul individuell ### ROI Mit diesem System können Sie: - Module einzeln lizenzieren und verkaufen - Upselling durch Feature-Module - Trial-Lizenzen mit Ablaufdatum - Pay-per-Feature-Modelle - White-Label-Lösungen mit unterschiedlichen Modulen ## Kontakt und Support Diese Implementierung wurde mit Claude Code entwickelt und basiert auf Symfony Best Practices. **Nächste Schritte:** 1. Lizenzserver implementieren (externe Komponente) 2. Erstes Produktiv-Modul entwickeln (z.B. Billing) 3. Testing und Monitoring in Produktion 4. Dokumentation für Modul-Entwickler erweitern