feat: add app and database modules

This commit is contained in:
2026-05-21 16:05:11 +07:00
parent 37b7e783f5
commit fad70d096b
212 changed files with 23901 additions and 0 deletions
+81
View File
@@ -0,0 +1,81 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Routing\Router;
use Illuminate\Support\Collection;
use Spatie\Permission\Models\Permission;
class AuditPermissions extends Command
{
protected $signature = 'permissions:audit
{--fix : Create missing permissions in the database}
{--json : Output results as JSON}';
protected $description = 'Compare route middleware permissions against the database and report gaps';
public function __construct(private Router $router)
{
parent::__construct();
}
public function handle(): int
{
$routePerms = $this->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('<fg=green>✓ 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('<fg=green>✓ 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();
}
}