['expected_role' => 'requester', 'name' => 'Requisitar ao armazém', 'permission' => 'warehouse_request_prepare'], 10 => ['expected_role' => 'department_head', 'name' => 'Autorizar requisições internas', 'permission' => 'warehouse_request_review'], 13 => ['expected_role' => 'warehouse', 'name' => 'Entregar requisições internas', 'permission' => 'warehouse_request_deliver'], 11 => ['expected_role' => 'procurement', 'name' => 'Preparar reposição', 'permission' => 'supply_prepare'], 12 => ['expected_role' => 'finance', 'name' => 'Conferir reposição', 'permission' => 'supply_review'], ]; $profiles = []; $people = []; $admins = []; foreach ($source['users'] as $person) { if (count($person['current_permissions']) !== 1 || ! is_array($person['current_contexts']) || ! $person['current_can_request']) { throw new LogicException('A origem deixou de corresponder às funções de desenvolvimento esperadas.'); } $role = $person['current_permissions'][0]; $key = 'base.'.$role; $base = ['key' => $key, 'name' => 'Piloto sintético — base '.$role, 'permissions' => array_values(array_unique([$role, 'requester'])), 'work_contexts' => $person['current_contexts']]; if (isset($profiles[$key]) && $profiles[$key] !== $base) { throw new LogicException('Contextos diferentes exigem proposta por pessoa, sem expansão implícita.'); } $profiles[$key] = $base; $keys = [$key]; $planned = $base['permissions']; if ($role === 'admin') { $admins[] = $person['id']; } if (isset($additions[$person['id']])) { $extra = $additions[$person['id']]; if ($role !== $extra['expected_role'] || ! str_contains($person['name'], 'avaliação local')) { throw new LogicException('Uma identidade proposta mudou. Confirmar os intervenientes antes de prosseguir.'); } $extraKey = 'task.'.$person['id']; $profiles[$extraKey] = ['key' => $extraKey, 'name' => 'Piloto sintético — '.$extra['name'], 'permissions' => [$extra['permission']], 'work_contexts' => ['procurement.internal']]; $keys[] = $extraKey; $planned[] = $extra['permission']; } $people[] = ['id' => $person['id'], 'name' => $person['name'], 'department_id' => $person['department_id'], 'current_permissions' => $person['current_permissions'], 'current_contexts' => $person['current_contexts'], 'current_can_request' => $person['current_can_request'], 'profile_keys' => $keys, 'planned_permissions' => $planned, 'added_task_permissions' => isset($additions[$person['id']]) ? [$additions[$person['id']]['permission']] : []]; } sort($admins); if (count($people) !== 12 || $admins !== [6, 8] || count(array_intersect(array_column($people, 'id'), array_keys($additions))) !== 5) { throw new LogicException('A lista de avaliação mudou. Produzir nova proposta revista.'); } $proposal = ['status' => 'pending_owner_authorization', 'scope' => 'synthetic_local_pilot_only', 'environment' => $source['environment'], 'prepared_at' => gmdate('c'), 'source_captured_at' => $source['captured_at'], 'source_sha256' => hash('sha256', $raw), 'source_version' => $source['version'], 'current_rules' => $source['company_rules'], 'proposed_rules' => [...$source['company_rules'], 'provisional' => false], 'enabled_contexts' => $source['enabled_contexts'], 'profiles' => array_values($profiles), 'users' => $people, 'permanent_administrator_source_ids' => $admins, 'effects' => ['activate_saved_profiles' => true, 'preserve_existing_permissions_and_contexts' => true, 'preserve_legacy_request_preparation' => true, 'make_existing_approval_limits_explicit_for_synthetic_pilot' => true, 'new_accounts' => false, 'change_existing_process_snapshots' => false, 'change_payables_specific_grants' => false, 'publish_stock_or_set_minimum_quantities' => false, 'change_sgf' => false], 'departments' => $source['departments'], 'cost_centers' => $source['cost_centers']]; file_put_contents($root.'/docs/proofs/pilot-access-proposal.json', json_encode($proposal, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR)); echo json_encode(['result' => 'proposal_prepared_not_applied', 'users' => count($people), 'profiles' => count($profiles), 'new_task_assignments' => count($additions), 'permanent_administrators' => $admins], JSON_THROW_ON_ERROR).PHP_EOL;