From f903914c2bc5964eb655d5560eb6196937409b01 Mon Sep 17 00:00:00 2001 From: theRADcozaDEV Date: Wed, 11 Mar 2026 08:42:06 +0200 Subject: [PATCH] Add auto-loading of module permissions in RolePermissionSeeder RolePermissionSeeder now automatically scans app/Modules/*/Permissions.php files and registers all permissions found. No manual registration required. - Added loadModulePermissions() method to scan module directories - Changed givePermissionTo() to syncPermissions() for idempotency - Updated Modules README to document auto-loading - Updated CLAUDE.md to reflect auto-loading behavior --- CLAUDE.md | 5 +- src/app/Modules/README.md | 3 ++ src/database/seeders/RolePermissionSeeder.php | 47 +++++++++++++++++-- 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index d7ec8de..624f6f8 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -260,7 +260,7 @@ return new class extends Migration }; ``` -### 5. Permissions (REQUIRED) +### 5. Permissions (REQUIRED) - AUTO-LOADED **File**: `src/app/Modules/[ModuleName]/Permissions.php` @@ -275,6 +275,9 @@ return [ ]; ``` +> **✅ AUTO-LOADED**: `RolePermissionSeeder` automatically scans all `app/Modules/*/Permissions.php` +> files and registers them. Just run `php artisan db:seed --class=RolePermissionSeeder`. + ### 6. Filament Resource (REQUIRED for admin) **File**: `src/app/Modules/[ModuleName]/Filament/Resources/[ModelName]Resource.php` diff --git a/src/app/Modules/README.md b/src/app/Modules/README.md index 1f98389..29268cd 100644 --- a/src/app/Modules/README.md +++ b/src/app/Modules/README.md @@ -94,6 +94,9 @@ ## Permissions ]; ``` +**Permissions are auto-loaded!** When you run `php artisan db:seed --class=RolePermissionSeeder`, +it scans all `app/Modules/*/Permissions.php` files and registers them automatically. + Use in Blade: ```blade @can('stock_management.view') diff --git a/src/database/seeders/RolePermissionSeeder.php b/src/database/seeders/RolePermissionSeeder.php index b509cbb..56b0658 100644 --- a/src/database/seeders/RolePermissionSeeder.php +++ b/src/database/seeders/RolePermissionSeeder.php @@ -3,6 +3,7 @@ namespace Database\Seeders; use Illuminate\Database\Seeder; +use Illuminate\Support\Facades\File; use Spatie\Permission\Models\Role; use Spatie\Permission\Models\Permission; use App\Models\User; @@ -13,7 +14,8 @@ public function run(): void { app()[\Spatie\Permission\PermissionRegistrar::class]->forgetCachedPermissions(); - $permissions = [ + // Core permissions + $corePermissions = [ 'users.view', 'users.create', 'users.edit', @@ -21,18 +23,22 @@ public function run(): void 'settings.manage', ]; - foreach ($permissions as $permission) { + foreach ($corePermissions as $permission) { Permission::firstOrCreate(['name' => $permission]); } + // Auto-load module permissions from app/Modules/*/Permissions.php + $this->loadModulePermissions(); + + // Create roles $adminRole = Role::firstOrCreate(['name' => 'admin']); - $adminRole->givePermissionTo(Permission::all()); + $adminRole->syncPermissions(Permission::all()); $editorRole = Role::firstOrCreate(['name' => 'editor']); - $editorRole->givePermissionTo(['users.view', 'users.edit']); + $editorRole->syncPermissions(['users.view', 'users.edit']); $viewerRole = Role::firstOrCreate(['name' => 'viewer']); - $viewerRole->givePermissionTo(['users.view']); + $viewerRole->syncPermissions(['users.view']); // Create admin user if not exists $admin = User::firstOrCreate( @@ -45,4 +51,35 @@ public function run(): void ); $admin->assignRole('admin'); } + + /** + * Scan app/Modules/*/Permissions.php and register all module permissions. + */ + protected function loadModulePermissions(): void + { + $modulesPath = app_path('Modules'); + + if (!File::isDirectory($modulesPath)) { + return; + } + + $modules = File::directories($modulesPath); + + foreach ($modules as $modulePath) { + $permissionsFile = $modulePath . '/Permissions.php'; + + if (File::exists($permissionsFile)) { + $permissions = require $permissionsFile; + + if (is_array($permissions)) { + foreach ($permissions as $permissionName => $description) { + // Handle both formats: + // ['permission.name' => 'Description'] or ['permission.name'] + $name = is_string($permissionName) ? $permissionName : $description; + Permission::firstOrCreate(['name' => $name]); + } + } + } + } + } }