| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- <?php
- namespace Database\Seeders;
- use App\Models\Permission;
- use App\Models\Role;
- use App\Models\User;
- use App\Services\Access\AccessService;
- use Illuminate\Database\Seeder;
- use Illuminate\Support\Facades\DB;
- class RbacSeeder extends Seeder
- {
- public function run(): void
- {
- DB::transaction(function () {
- $roles = $this->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',
- 'catalog.import',
- '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'];
- }
- }
- $role->permissions()->sync($sync);
- }
- }
- 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)
- ));
- }
- }
|