- Hinzufügen der DependencyInjection-Konfiguration für das Billing-Modul. - Erstellen der Invoice-Entity mit API-Ressourcen und Berechtigungen. - Konfigurieren der Services in services.yaml für das Billing-Modul. - Implementieren von CLI-Commands zur Verwaltung von Modul-Lizenzen und zur Auflistung installierter Module. - Erstellen eines API-Controllers zur Verwaltung von Modulen und Lizenzen. - Hinzufügen eines EventListeners für das Booten von Modulen. - Definieren von Interfaces für Lizenzvalidierung und Modul-Plugins. - Implementieren der ModuleRegistry zur Verwaltung und Booten von Modulen. - Erstellen eines LicenseValidator-Services zur Validierung und Registrierung von Lizenzen.
5.1 KiB
5.1 KiB
Beispiel-Struktur für ein lizenzierbares Modul
Dieses Dokument beschreibt die Struktur eines eigenständigen, lizenzierbaren Moduls als Composer-Package.
Verzeichnisstruktur
mycrm-billing-module/
├── composer.json # Composer-Paket-Definition
├── README.md
├── LICENSE
├── config/
│ ├── routes.yaml # Modul-spezifische Routes
│ ├── services.yaml # Modul-Services
│ └── packages/ # Modul-Konfigurationen
│ └── doctrine.yaml # Doctrine-Mappings
├── src/
│ ├── BillingModulePlugin.php # Hauptklasse (implementiert ModulePluginInterface)
│ ├── BillingBundle.php # Symfony Bundle
│ ├── DependencyInjection/
│ │ ├── BillingExtension.php # Container-Extension
│ │ └── Configuration.php # Bundle-Konfiguration
│ ├── Entity/
│ │ ├── Invoice.php # Modul-Entities
│ │ ├── InvoiceItem.php
│ │ └── PaymentMethod.php
│ ├── Controller/
│ │ └── Api/
│ │ ├── InvoiceController.php # API-Controller
│ │ └── PaymentController.php
│ ├── Repository/
│ │ └── InvoiceRepository.php
│ ├── Service/
│ │ ├── InvoiceService.php
│ │ ├── PdfGenerator.php
│ │ └── PaymentProcessor.php
│ ├── Security/
│ │ └── Voter/
│ │ └── InvoiceVoter.php # Permissions für Entities
│ └── EventListener/
│ └── InvoiceEventListener.php
├── assets/ # Frontend-Assets (optional)
│ ├── js/
│ │ ├── components/
│ │ │ └── InvoiceManagement.vue
│ │ └── views/
│ │ └── InvoiceDashboard.vue
│ └── styles/
│ └── billing.scss
├── migrations/ # Doctrine Migrations für Modul
│ └── Version20250103120000.php
└── tests/
├── Unit/
└── Functional/
composer.json
{
"name": "mycrm/billing-module",
"description": "Rechnungsmodul für myCRM",
"type": "symfony-bundle",
"license": "proprietary",
"version": "1.0.0",
"require": {
"php": ">=8.3",
"symfony/framework-bundle": "^7.1",
"api-platform/core": "^3.0",
"doctrine/orm": "^2.0 || ^3.0"
},
"require-dev": {
"phpunit/phpunit": "^10.0"
},
"autoload": {
"psr-4": {
"MyCRM\\BillingModule\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"MyCRM\\BillingModule\\Tests\\": "tests/"
}
},
"extra": {
"symfony": {
"allow-contrib": true,
"require": "7.1.*"
}
}
}
Installation
# Als privates Composer-Repository
composer config repositories.mycrm-billing vcs https://github.com/your-org/mycrm-billing-module
composer require mycrm/billing-module
# Bundle in config/bundles.php registrieren (falls nicht automatisch)
# MyCRM\BillingModule\BillingBundle::class => ['all' => true],
# Migrations ausführen
php bin/console doctrine:migrations:migrate --em=billing
# Lizenz registrieren
php bin/console app:module:license billing YOUR_LICENSE_KEY
# Cache leeren
php bin/console cache:clear
Deinstallation
# Lizenz entfernen
php bin/console app:module:license:revoke billing
# Modul entfernen
composer remove mycrm/billing-module
# Migrations rückgängig machen (optional)
php bin/console doctrine:migrations:migrate prev --all --em=billing
Lizenzschlüssel-Format
Lizenzschlüssel sind JWT-Tokens mit folgender Struktur:
{
"sub": "billing",
"customer_id": "CUST-12345",
"licensed_to": "Firma GmbH",
"expires_at": "2026-12-31T23:59:59Z",
"features": [
"invoicing",
"recurring_billing",
"payment_gateway"
],
"iat": 1704278400,
"nbf": 1704278400,
"exp": 1767350399
}
Frontend-Integration
Das Modul kann optional Frontend-Komponenten bereitstellen:
// assets/js/billing-module.js
import InvoiceManagement from './components/InvoiceManagement.vue'
import InvoiceDashboard from './views/InvoiceDashboard.vue'
export default {
install(app) {
app.component('InvoiceManagement', InvoiceManagement)
app.component('InvoiceDashboard', InvoiceDashboard)
},
routes: [
{
path: '/invoices',
name: 'invoices',
component: InvoiceDashboard,
meta: {
requiresAuth: true,
requiresModule: 'billing'
}
}
]
}
Integration in Haupt-App:
// assets/app.js
import { createApp } from 'vue'
import BillingModule from '@mycrm/billing-module/assets/js/billing-module'
const app = createApp(App)
// Modul nur laden, wenn lizenziert
if (window.myCRM.modules.billing?.active) {
app.use(BillingModule)
router.addRoute(BillingModule.routes)
}