forgetCachedPermissions(); $catalogue = Permissions::all(); foreach ($catalogue as $name) { Permission::findOrCreate($name, 'web'); } // Drop permissions that were retired from the catalogue, along with // their role and user assignments. Permission::query()->whereNotIn('name', $catalogue)->delete(); foreach (Permissions::roleDefinitions() as $roleName => $permissions) { $role = Role::findOrCreate($roleName, 'web'); // syncPermissions is what makes this idempotent: the role ends up // with exactly the definition in code, no more and no less. // super_admin gets an empty set on purpose — its power comes from // the Gate::before hook in AuthServiceProvider. $role->syncPermissions($permissions); } app(PermissionRegistrar::class)->forgetCachedPermissions(); $this->command?->info(sprintf( 'Synced %d permissions across %d roles.', count($catalogue), count(Permissions::roleDefinitions()), )); } }