myCRM/docs/PLUGIN_SYSTEM_README.md
2025-12-04 10:53:18 +01:00

18 KiB

🔌 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

cp .env.plugin.example .env.local
# .env.local
LICENSE_SERVER_URL=https://license.mycrm.local
INSTANCE_ID=$(openssl rand -hex 16)

2. Cache leeren

php bin/console cache:clear

3. System testen

php bin/console app:module:list

Core-System ist bereit!

Siehe PLUGIN_QUICKSTART.md für vollständige Anleitung.

📦 Modul installieren (Beispiel)

# 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

# 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

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:

// 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 Abschnitt "Modul entwickeln" für vollständige Anleitung.

Minimal-Beispiel

  1. Plugin-Klasse erstellen:
<?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
}
  1. Service registrieren:
# config/services.yaml
services:
    MyCRM\MyModule\MyModulePlugin:
        tags: ['app.module_plugin']
  1. Entity mit ModuleAwareInterface:
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)

{
    "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

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

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

# 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

# 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

# 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 für vollständige Troubleshooting-Anleitung.

📚 Dokumentation

Dokument Beschreibung Zielgruppe
PLUGIN_QUICKSTART.md 5-Minuten-Schnellstart Admin
PLUGIN_SYSTEM.md Vollständige Anleitung Admin + Dev
PLUGIN_SYSTEM_SUMMARY.md Architektur-Übersicht Dev + Architekt
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 für häufige Probleme
  2. Prüfe 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