567 lines
18 KiB
Markdown
567 lines
18 KiB
Markdown
# 🔌 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
|
|
<?php
|
|
namespace MyCRM\MyModule;
|
|
|
|
use App\Plugin\ModulePluginInterface;
|
|
use App\Plugin\LicenseValidatorInterface;
|
|
|
|
class MyModulePlugin implements ModulePluginInterface
|
|
{
|
|
public function __construct(
|
|
private readonly LicenseValidatorInterface $licenseValidator
|
|
) {}
|
|
|
|
public function getIdentifier(): string
|
|
{
|
|
return 'mymodule';
|
|
}
|
|
|
|
public function getDisplayName(): string
|
|
{
|
|
return 'Mein Modul';
|
|
}
|
|
|
|
public function isLicensed(): bool
|
|
{
|
|
$info = $this->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
|