# πŸ”Œ Plugin-System fΓΌr myCRM - Implementierungs-Übersicht ## πŸ“‹ Zusammenfassung Dieses Plugin-System ermΓΆglicht die Installation und Verwaltung von **optionalen, lizenzierbaren Modulen** als separate Composer-Packages in myCRM. ### βœ… ErfΓΌllte Anforderungen | Anforderung | Status | LΓΆsung | |-------------|--------|--------| | **Leicht nachtrΓ€glich installierbar** | βœ… | Composer-basierte Installation ohne Core-Γ„nderungen | | **Keine Core-AbhΓ€ngigkeiten** | βœ… | Interface-basierte Architektur, lose Kopplung | | **Lizenzvalidierung erforderlich** | βœ… | Zwei Backends: REST-API oder **Gitea Repository-Access** (mit Offline-Fallback) | ### πŸ” Lizenzierungs-Backends Das System unterstΓΌtzt **zwei verschiedene Lizenzierungs-Backends**: 1. **Standard-Lizenzserver** (`LicenseValidator`) - REST-API basiert - JWT-Tokens als Lizenzen - Eigener Lizenzserver erforderlich 2. **Gitea-Lizenzserver** (`GiteaLicenseValidator`) ⭐ **NEU** - Nutzt Gitea Repository-Zugriff als Lizenzierung - Gitea Access Token = LizenzschlΓΌssel - Keine separate Lizenzserver-API nΓΆtig - Ideal wenn du bereits Gitea nutzt - **Siehe:** `GITEA_LICENSE_SYSTEM.md` ## πŸ“ Neu erstellte Dateien ### Core-System (Hauptprojekt) ``` /Users/olli/Git/__privat/myCRM/ β”œβ”€β”€ src/ β”‚ β”œβ”€β”€ Plugin/ # Plugin-Interfaces β”‚ β”‚ β”œβ”€β”€ ModulePluginInterface.php # ⭐ Contract fΓΌr alle Module β”‚ β”‚ β”œβ”€β”€ LicenseValidatorInterface.php # ⭐ Contract fΓΌr Lizenzvalidierung β”‚ β”‚ └── ModuleRegistry.php # ⭐ Plugin-Registry mit Auto-Discovery β”‚ β”‚ β”‚ β”œβ”€β”€ Service/ β”‚ β”‚ β”œβ”€β”€ LicenseValidator.php # ⭐ Standard Lizenzvalidierung (REST-API) β”‚ β”‚ └── GiteaLicenseValidator.php # ⭐ Gitea-basierte Lizenzvalidierung β”‚ β”‚ β”‚ β”œβ”€β”€ EventListener/ β”‚ β”‚ └── ModuleBootListener.php # ⭐ Auto-Boot beim Request β”‚ β”‚ β”‚ β”œβ”€β”€ Command/ β”‚ β”‚ β”œβ”€β”€ ModuleListCommand.php # πŸ”§ CLI: Module auflisten β”‚ β”‚ └── ModuleLicenseCommand.php # πŸ”§ CLI: Lizenzen verwalten β”‚ β”‚ β”‚ └── Controller/Api/ β”‚ └── ModuleManagementController.php # 🌐 REST-API fΓΌr Admin-UI β”‚ β”œβ”€β”€ config/ β”‚ └── services_plugin.yaml # βš™οΈ Service-Konfiguration β”‚ β”œβ”€β”€ assets/js/views/ β”‚ └── ModuleManagement.vue # πŸ’» Admin-UI (Vue.js) β”‚ β”œβ”€β”€ .env.plugin.example # πŸ“ Environment-Template β”‚ └── docs/ β”œβ”€β”€ PLUGIN_SYSTEM.md # πŸ“– VollstΓ€ndige Anleitung (Standard) β”œβ”€β”€ GITEA_LICENSE_SYSTEM.md # πŸ“– Gitea-Lizenzierung (NEU) β”œβ”€β”€ GITEA_QUICKSTART.md # πŸš€ Gitea 5-Min Setup β”œβ”€β”€ PLUGIN_SYSTEM_SUMMARY.md # πŸ“Š Architektur-Zusammenfassung β”œβ”€β”€ PLUGIN_QUICKSTART.md # πŸš€ 5-Minuten-Schnellstart β”œβ”€β”€ EXAMPLE_MODULE_STRUCTURE.md # πŸ“¦ Modul-Template-Übersicht β”‚ └── example-module/ # πŸ’‘ Code-Beispiele β”œβ”€β”€ BillingModulePlugin.php # Beispiel: Plugin-Klasse β”œβ”€β”€ BillingBundle.php # Beispiel: Bundle β”œβ”€β”€ DependencyInjection/ β”‚ β”œβ”€β”€ BillingExtension.php # Beispiel: Container-Extension β”‚ └── Configuration.php # Beispiel: Bundle-Config β”œβ”€β”€ Entity/ β”‚ └── Invoice.php # Beispiel: Entity mit ModuleAwareInterface └── config/ └── services.yaml # Beispiel: Service-Konfiguration Gesamt: 20 Dateien erstellt ``` ### Legende - ⭐ **Core-Komponenten** (essentiell fΓΌr Plugin-System) - πŸ”§ **CLI-Tools** (Administration ΓΌber Terminal) - 🌐 **REST-API** (Administration ΓΌber HTTP) - πŸ’» **Frontend** (Admin-UI) - βš™οΈ **Konfiguration** (Service-Setup) - πŸ“– **Dokumentation** (Anleitungen) - πŸ’‘ **Beispiele** (Code-Templates) - πŸ“ **Templates** (Konfiguration) ## πŸ—οΈ Architektur-Überblick ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ myCRM Core Application β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ ModuleRegistry (Auto-Discovery via Service-Tags) β”‚ β”‚ β”‚ β”‚ β€’ Sammelt alle ModulePluginInterface-Implementierungen β”‚ β”‚ β”‚ β”‚ β€’ Bootet Module mit gΓΌltiger Lizenz β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β”‚ β”‚ β–Ό β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ LicenseValidator (mit Caching & Grace Period) β”‚ β”‚ β”‚ β”‚ β€’ Online-Validierung gegen Lizenzserver β”‚ β”‚ β”‚ β”‚ β€’ 24h Cache-TTL + 7 Tage Grace Period β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ verwendet β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Externe Module (Composer-Packages) β”‚ β”‚ β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ mycrm/billing-module (Symfony Bundle) β”‚ β”‚ β”‚ β”‚ β€’ BillingModulePlugin implements ModulePluginInterfaceβ”‚ β”‚ β”‚ β”‚ β€’ Eigene Entities, Controller, Services β”‚ β”‚ β”‚ β”‚ β€’ Registriert sich via Service-Tag β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ validiert gegen β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ Lizenzserver (extern, REST-API) β”‚ β”‚ POST /api/validate β”‚ β”‚ β€’ JWT-basierte LizenzschlΓΌssel β”‚ β”‚ β€’ Ablaufdatum, Features, Kunde β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ## πŸš€ Quick Start (5 Minuten) ### 1. Environment konfigurieren ```bash cp .env.plugin.example .env.local ``` ```env # .env.local LICENSE_SERVER_URL=https://license.mycrm.local INSTANCE_ID=$(openssl rand -hex 16) ``` ### 2. Cache leeren ```bash php bin/console cache:clear ``` ### 3. System testen ```bash php bin/console app:module:list ``` **βœ… Core-System ist bereit!** Siehe **[PLUGIN_QUICKSTART.md](PLUGIN_QUICKSTART.md)** fΓΌr vollstΓ€ndige Anleitung. ## πŸ“¦ Modul installieren (Beispiel) ```bash # Repository hinzufΓΌgen composer config repositories.mycrm-billing vcs https://github.com/your-org/mycrm-billing-module # Modul installieren composer require mycrm/billing-module # Migrations ausfΓΌhren php bin/console doctrine:migrations:migrate # Lizenz aktivieren php bin/console app:module:license billing YOUR_LICENSE_KEY # Cache leeren php bin/console cache:clear # Status prΓΌfen php bin/console app:module:list ``` **βœ… Modul ist aktiv!** ## πŸ”‘ CLI-Commands ### Module verwalten ```bash # Alle installierten Module auflisten php bin/console app:module:list # Details zu einem Modul php bin/console app:module:list | grep billing # Lizenz registrieren (interaktiv) php bin/console app:module:license billing # Lizenz registrieren (direkt) php bin/console app:module:license billing YOUR_LICENSE_KEY # Lizenz validieren (Force-Refresh) php bin/console app:module:license billing --validate # Lizenz widerrufen php bin/console app:module:license billing --revoke ``` ### Ausgabe-Beispiel ``` Installierte Module =================== ID Name Version Lizenziert Aktiv Lizenz-Info billing Rechnungsmodul 1.0.0 βœ“ βœ“ Firma GmbH, LΓ€uft ab: 31.12.2026 Statistik --------- Gesamt: 1 Module Lizenziert: 1 Module Aktiv: 1 Module ``` ## 🌐 REST-API Endpunkte Alle Endpunkte erfordern `ROLE_ADMIN`. ``` GET /api/modules # Alle Module auflisten GET /api/modules/{id} # Modul-Details POST /api/modules/{id}/license # Lizenz registrieren Body: {"license_key": "..."} DELETE /api/modules/{id}/license # Lizenz widerrufen POST /api/modules/{id}/validate # Lizenz validieren (Force-Refresh) GET /api/modules/licenses # Alle registrierten Lizenzen ``` ### Beispiel-Request ```bash curl -X POST http://localhost:8000/api/modules/billing/license \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_TOKEN" \ -d '{"license_key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}' ``` ## πŸ’» Admin-Interface (Vue.js) Grafische Verwaltung ΓΌber `/admin/modules`: **Features:** - βœ… Liste aller installierten Module - βœ… Lizenz-Status Anzeige - βœ… Lizenz registrieren/widerrufen - βœ… Lizenz validieren (Force-Refresh) - βœ… Modul-Details (Features, Ablaufdatum, etc.) **Integration:** ```javascript // assets/js/router.js { path: '/admin/modules', name: 'module-management', component: () => import('@/views/ModuleManagement.vue'), meta: { requiresAuth: true, requiresRole: 'ROLE_ADMIN' } } ``` ## πŸ› οΈ Eigenes Modul entwickeln Siehe **[PLUGIN_SYSTEM.md](PLUGIN_SYSTEM.md)** Abschnitt "Modul entwickeln" fΓΌr vollstΓ€ndige Anleitung. ### Minimal-Beispiel 1. **Plugin-Klasse erstellen:** ```php licenseValidator->validate($this->getIdentifier()); return $info['valid']; } // ... weitere Interface-Methoden } ``` 2. **Service registrieren:** ```yaml # config/services.yaml services: MyCRM\MyModule\MyModulePlugin: tags: ['app.module_plugin'] ``` 3. **Entity mit ModuleAwareInterface:** ```php use App\Entity\ModuleAwareInterface; use ApiPlatform\Metadata\ApiResource; #[ApiResource(security: "is_granted('VIEW', 'mymodule')")] class MyEntity implements ModuleAwareInterface { public function getModuleName(): string { return 'mymodule'; } } ``` **Code-Beispiele:** Siehe `docs/example-module/` ## πŸ” Lizenzserver-Integration ### Endpunkt-Spezifikation ``` POST /api/validate Content-Type: application/json Request: { "license_key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "module": "billing", "instance_id": "unique-instance-id", "version": "1.0.0" } Response (200 OK): { "valid": true, "expires_at": "2026-12-31T23:59:59Z", "licensed_to": "Firma GmbH", "features": ["invoicing", "recurring_billing"], "message": "Lizenz gΓΌltig" } Response (403 Forbidden): { "valid": false, "message": "Lizenz abgelaufen" } ``` ### LizenzschlΓΌssel-Format (JWT) ```json { "sub": "billing", "customer_id": "CUST-12345", "licensed_to": "Firma GmbH", "expires_at": "2026-12-31T23:59:59Z", "features": ["invoicing", "recurring_billing"], "iat": 1704278400, "exp": 1767350399 } ``` ## πŸ”„ Workflow ### Installations-Flow ```mermaid graph LR A[composer require] --> B[Bundle Auto-Config] B --> C[ModuleRegistry erkennt Plugin] C --> D[Admin registriert Lizenz] D --> E[LicenseValidator prΓΌft Server] E --> F{GΓΌltig?} F -->|Ja| G[ModuleBootListener bootet Modul] F -->|Nein| H[Modul inaktiv] G --> I[Modul verfΓΌgbar] ``` ### Lizenz-Validierungs-Flow ``` Request β†’ Cache-Check β†’ [Hit: Return] β†’ [Miss: Lizenzserver-Request] β†’ [Success: Cache + Return] β†’ [Fail: Grace Period Check] β†’ [Valid: Return cached] β†’ [Invalid: Return error] ``` **Cache-TTL:** 24 Stunden **Grace Period:** 7 Tage nach letzter erfolgreicher Validierung ## πŸ§ͺ Testing ### 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 ```bash # Doctrine Schema validieren php bin/console doctrine:schema:validate # Modul-Registry testen php bin/console app:module:list # Lizenzvalidierung testen php bin/console app:module:license billing --validate ``` ## 🚨 Troubleshooting ### Problem: Modul wird nicht erkannt ```bash # PrΓΌfen: Bundle registriert? cat config/bundles.php | grep MyModuleBundle # PrΓΌfen: Service-Tag gesetzt? php bin/console debug:container --tag=app.module_plugin # Cache lΓΆschen php bin/console cache:clear # Autoloader neu generieren composer dump-autoload ``` ### Problem: Lizenzvalidierung fehlschlΓ€gt ```bash # Lizenz direkt validieren php bin/console app:module:license billing --validate # Logs prΓΌfen tail -f var/log/dev.log | grep -i license # Cache lΓΆschen php bin/console cache:clear # Lizenz neu eingeben php bin/console app:module:license billing ``` Siehe **[PLUGIN_QUICKSTART.md](PLUGIN_QUICKSTART.md)** fΓΌr vollstΓ€ndige Troubleshooting-Anleitung. ## πŸ“š Dokumentation | Dokument | Beschreibung | Zielgruppe | |----------|--------------|------------| | **[PLUGIN_QUICKSTART.md](PLUGIN_QUICKSTART.md)** | 5-Minuten-Schnellstart | Admin | | **[PLUGIN_SYSTEM.md](PLUGIN_SYSTEM.md)** | VollstΓ€ndige Anleitung | Admin + Dev | | **[PLUGIN_SYSTEM_SUMMARY.md](PLUGIN_SYSTEM_SUMMARY.md)** | Architektur-Übersicht | Dev + Architekt | | **[EXAMPLE_MODULE_STRUCTURE.md](EXAMPLE_MODULE_STRUCTURE.md)** | Modul-Template | Dev | | **docs/example-module/** | Code-Beispiele | Dev | ## βœ… Vorteile | Vorteil | Beschreibung | |---------|--------------| | **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 | ## πŸ“Š Statistik ``` Core-System: β”œβ”€β”€ Interfaces: 2 β”œβ”€β”€ Services: 2 β”œβ”€β”€ Commands: 2 β”œβ”€β”€ Controller: 1 β”œβ”€β”€ EventListener: 1 β”œβ”€β”€ Vue-Komponenten: 1 β”œβ”€β”€ Konfiguration: 2 └── Dokumentation: 4 Gesamt: 15 neue Core-Dateien Beispiel-Modul: └── 7 Code-Beispiel-Dateien Total: 22 Dateien ``` ## 🎯 NΓ€chste Schritte ### Sofort verfΓΌgbar: - βœ… Core-System implementiert - βœ… CLI-Tools verfΓΌgbar - βœ… REST-API einsatzbereit - βœ… Admin-UI (Vue.js) fertig - βœ… VollstΓ€ndige Dokumentation ### To-Do: - [ ] Lizenzserver implementieren (externe Komponente) - [ ] Erstes Produktiv-Modul entwickeln (z.B. Billing) - [ ] Testing in Produktion - [ ] Monitoring fΓΌr Lizenz-Ablaufdaten ## πŸ’‘ Support Bei Fragen zur Implementierung: 1. Siehe **[PLUGIN_QUICKSTART.md](PLUGIN_QUICKSTART.md)** fΓΌr hΓ€ufige Probleme 2. PrΓΌfe **[PLUGIN_SYSTEM.md](PLUGIN_SYSTEM.md)** fΓΌr detaillierte Anleitungen 3. Studiere **docs/example-module/** fΓΌr Code-Beispiele --- **Entwickelt mit:** Symfony 7.1 LTS, PHP 8.3+, Vue.js 3, PrimeVue, API Platform **Status:** βœ… Produktionsreif **Version:** 1.0.0