collectRoutePermissions(); $dbPerms = Permission::pluck('name')->map(fn ($n) => strtolower($n))->toArray(); $missing = $routePerms->filter(fn ($p) => ! in_array(strtolower($p), $dbPerms))->values(); $orphaned = collect($dbPerms)->filter(fn ($p) => ! $routePerms->map(fn ($r) => strtolower($r))->contains($p))->values(); if ($this->option('json')) { $this->line(json_encode(compact('missing', 'orphaned'), JSON_PRETTY_PRINT)); return self::SUCCESS; } $this->info('=== Permission Audit ==='); $this->newLine(); if ($missing->isEmpty()) { $this->line('✓ All route permissions exist in database.'); } else { $this->warn("Missing in database ({$missing->count()} permissions used in routes but not in DB):"); $missing->each(fn ($p) => $this->line(" - {$p}")); if ($this->option('fix')) { $missing->each(fn ($p) => Permission::findOrCreate($p, 'web')); $this->info("Created {$missing->count()} missing permission(s)."); } } $this->newLine(); if ($orphaned->isEmpty()) { $this->line('✓ No orphaned permissions in database.'); } else { $this->warn("Orphaned in database ({$orphaned->count()} permissions in DB but not used in any route):"); $orphaned->each(fn ($p) => $this->line(" - {$p}")); } return $missing->isEmpty() ? self::SUCCESS : self::FAILURE; } private function collectRoutePermissions(): Collection { $permissions = collect(); foreach ($this->router->getRoutes() as $route) { $middleware = $route->gatherMiddleware(); foreach ($middleware as $mw) { if (is_string($mw) && str_starts_with($mw, 'permission:')) { $perm = trim(str_replace('permission:', '', $mw)); $permissions->push($perm); } } } return $permissions->unique()->sort()->values(); } }