1
0

feat(modules): harden module platform with event constants, validation checks, and CLI improvements

- Add ModuleEvents constants class with all 8 event strings; update dispatch call sites
- ValidateCommand: check AuthorizationPolicy container registration (check 20)
- ValidateCommand: warn on unknown event_listeners keys (check 21)
- make:module --simple flag for minimal manifests
- module:deactivate reverse-dependency warning
- 12 new PHPUnit tests covering all improvements

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-14 08:23:04 +02:00
parent 143d887a5c
commit b1a907b79c
10 changed files with 604 additions and 24 deletions

View File

@@ -35,17 +35,22 @@ final class ModuleCommand extends Command
public function usage(): string
{
return <<<'USAGE'
Usage: php bin/console make:module <module-id>
Usage: php bin/console make:module <module-id> [--simple]
Arguments:
module-id Lowercase identifier (e.g. notifications, activity-log)
Must match [a-z][a-z0-9-]* pattern.
Options:
--simple Generate a minimal manifest with only essential fields.
Ideal for lightweight UI-only modules.
Example:
php bin/console make:module notifications
php bin/console make:module help-panel --simple
Generates the full module directory structure with:
- module.php manifest (all fields, sensible defaults)
- module.php manifest (all fields or minimal with --simple)
- ContainerRegistrar stub
- AuthorizationPolicy stub
- Empty pages/, templates/, web/css/, web/js/, tests/ directories
@@ -96,8 +101,11 @@ final class ModuleCommand extends Command
}
// Generate files
$simple = $options['simple'] ?? false;
$files = [
'module.php' => self::manifestTemplate($moduleId, $pascalName, $snakeName),
'module.php' => $simple
? self::simpleManifestTemplate($moduleId, $pascalName)
: self::manifestTemplate($moduleId, $pascalName, $snakeName),
"lib/Module/{$pascalName}/{$pascalName}ContainerRegistrar.php" => self::registrarTemplate($pascalName),
"lib/Module/{$pascalName}/{$pascalName}AuthorizationPolicy.php" => self::policyTemplate($pascalName, $snakeName),
];
@@ -199,6 +207,37 @@ final class ModuleCommand extends Command
PHP;
}
private static function simpleManifestTemplate(string $id, string $pascalName): string
{
$registrarClass = "\\MintyPHP\\Module\\{$pascalName}\\{$pascalName}ContainerRegistrar::class";
$policyClass = "\\MintyPHP\\Module\\{$pascalName}\\{$pascalName}AuthorizationPolicy::class";
return <<<PHP
<?php
/**
* {$pascalName} module manifest (minimal).
*
* Extend with routes, permissions, ui_slots, etc. as needed.
* See docs/howto-modul-erstellen.md for all available fields.
*/
return [
'id' => '{$id}',
'version' => '0.1.0',
'enabled_by_default' => false,
'load_order' => 100,
'requires' => [],
'container_registrars' => [
{$registrarClass},
],
'authorization_policies' => [
{$policyClass},
],
];
PHP;
}
private static function registrarTemplate(string $pascalName): string
{
return <<<PHP