seedRoles(); $permissions = $this->seedPermissions(); $this->backfillUserRoles($roles); $this->seedRolePermissions($roles, $permissions); }); app(AccessService::class)->bumpCacheVersion(); } private function seedRoles(): array { $roles = []; foreach (Role::NAMES as $slug => $name) { $roles[$slug] = Role::query()->updateOrCreate( ['slug' => $slug], [ 'name' => $name, 'is_system' => true, 'is_active' => true, 'sort' => array_search($slug, Role::VALID_ROLES, true) + 10, ], ); } return $roles; } private function seedPermissions(): array { $permissions = []; $sort = 10; foreach (config('access', []) as $module => $definition) { foreach (($definition['actions'] ?? []) as $action => $name) { $slug = "{$module}.{$action}"; $permissions[$slug] = Permission::query()->updateOrCreate( ['slug' => $slug], [ 'name' => $name, 'module' => $module, 'entity' => $definition['entity'] ?? null, 'field' => null, 'action' => $action, 'type' => Permission::TYPE_ACTION, 'group' => $definition['name'] ?? $module, 'sort' => $sort++, 'is_system' => true, ], ); } foreach (($definition['fields'] ?? []) as $field => $name) { foreach (['view' => 'Просмотр', 'update' => 'Редактирование'] as $action => $actionName) { $slug = "{$module}.fields.{$field}.{$action}"; $permissions[$slug] = Permission::query()->updateOrCreate( ['slug' => $slug], [ 'name' => "{$name}: {$actionName}", 'module' => $module, 'entity' => $definition['entity'] ?? null, 'field' => $field, 'action' => $action, 'type' => Permission::TYPE_FIELD, 'group' => ($definition['name'] ?? $module) . ' / Поля', 'sort' => $sort++, 'is_system' => true, ], ); } } } return $permissions; } private function backfillUserRoles(array $roles): void { foreach ($roles as $slug => $role) { User::query() ->where('role', $slug) ->whereNull('role_id') ->withTrashed() ->update(['role_id' => $role->id]); } } private function seedRolePermissions(array $roles, array $permissions): void { $all = array_keys($permissions); $auth = [ 'orders.view', 'orders.photos.upload', 'orders.documents.generate', 'orders.chat.create', 'reclamations.view', 'reclamations.photos.upload', 'reclamations.chat.create', 'schedule.view', 'profile.view', 'profile.update', 'profile.delete', 'notifications.view', 'notifications.mark_read', 'areas.ajax.view', 'catalog.search', 'pricing_codes.search', 'filters.view', ]; $manager = array_merge($auth, [ 'orders.update', 'orders.export', 'orders.documents.upload', 'orders.documents.delete', 'orders.documents.generate', 'orders.photos.delete', 'reclamations.create', 'reclamations.update', 'reclamations.export', 'reclamations.status.update', 'reclamations.documents.upload', 'reclamations.documents.delete', 'reclamations.documents.generate', 'reclamations.photos.delete', 'reclamations.act.upload', 'reclamations.act.delete', 'reclamations.spare_parts.manage', 'catalog.view', 'maf.view', 'maf.update', 'maf.passports.upload', 'contracts.view', 'contracts.create', 'contracts.update', 'contracts.delete', 'responsibles.view', 'responsibles.create', 'responsibles.update', 'responsibles.delete', 'reports.view', 'spare_parts.view', 'spare_parts.search', 'spare_part_orders.view', 'spare_part_orders.create', 'spare_part_orders.update', 'spare_part_orders.ship', 'spare_part_orders.stock.manage', 'spare_part_reservations.view', 'spare_part_reservations.manage', 'spare_part_reservations.issue', 'spare_part_reservations.cancel', 'spare_part_reservations.reassign', 'spare_part_inventory.view', 'chat_messages.create', 'chat_messages.notify', ]); $manager = array_merge($manager, $this->fieldPermissions('catalog', ['view'], $permissions)); $brigadier = array_merge($auth, [ 'reclamations.act.upload', ]); $warehouseHead = array_merge($auth, [ 'reclamations.act.upload', ]); $rolePermissions = [ Role::ADMIN => $all, Role::ASSISTANT_HEAD => $all, Role::MANAGER => $manager, Role::BRIGADIER => $brigadier, Role::WAREHOUSE_HEAD => $warehouseHead, ]; foreach ($rolePermissions as $roleSlug => $permissionSlugs) { $role = $roles[$roleSlug] ?? null; if (!$role) { continue; } $sync = []; foreach (array_unique($permissionSlugs) as $permissionSlug) { if (isset($permissions[$permissionSlug])) { $sync[$permissions[$permissionSlug]->id] = ['effect' => 'allow']; } } if ($this->rolePermissionsChanged($role, $sync)) { $role->permissions()->sync($sync); } } } private function rolePermissionsChanged(Role $role, array $sync): bool { $current = $role->permissions() ->pluck('role_permissions.effect', 'permissions.id') ->all(); $expected = array_map( fn (array $attributes): string => $attributes['effect'], $sync ); ksort($current); ksort($expected); return $current !== $expected; } private function fieldPermissions(string $module, array $actions, array $permissions): array { return array_values(array_filter( array_keys($permissions), fn (string $slug): bool => str_starts_with($slug, "{$module}.fields.") && in_array(substr($slug, strrpos($slug, '.') + 1), $actions, true) )); } }