Files
compras/scripts/prepare-pilot-access-proposal.php
2026-11-02 20:27:11 +02:00

67 lines
4.9 KiB
PHP

<?php
// Produces a reviewable proposal only. No application bootstrap, database or network.
$root = dirname(__DIR__);
$path = $root.'/storage/app/pilot-access-source.json';
$raw = file_get_contents($path);
$source = json_decode($raw, true, 64, JSON_THROW_ON_ERROR);
if ($source['environment'] !== 'http://127.0.0.1:8005' || $source['active'] !== false || $source['profiles'] !== [] || $source['memberships'] !== []) {
throw new LogicException('Rever a origem: proposta limitada à avaliação sintética ainda sem perfis.');
}
$additions = [
9 => ['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;