# 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 ```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 ```bash # 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 ```bash # 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: ```json { "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: ```javascript // 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: ```javascript // 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) } ```