$v) { putenv($k.'='.$v); $_ENV[$k] = $_SERVER[$k] = $v; } require $s['HOST_ROOT'].'/vendor/autoload.php'; $app = require $s['HOST_ROOT'].'/bootstrap/app.php'; $app->make(\Illuminate\Contracts\Console\Kernel::class)->bootstrap(); $before = []; $columns = []; foreach (\Tempo\Finance\Payables\SettlementSchema::TABLES as $table) { $columns[$table] = \Illuminate\Support\Facades\DB::connection()->getSchemaBuilder()->getColumnListing($table); $before[$table] = \Tempo\Finance\Payables\Payables::canonical(\Illuminate\Support\Facades\DB::table($table)->orderBy($table === 'ps_outbox' ? 'event_id' : 'id')->get()->all()); } \Tempo\Finance\Payables\ReversalSchema::install(); foreach ($columns as $table => $names) { $after = \Tempo\Finance\Payables\Payables::canonical(\Illuminate\Support\Facades\DB::table($table)->select($names)->orderBy($table === 'ps_outbox' ? 'event_id' : 'id')->get()->all()); if ($before[$table] !== $after) throw new LogicException('Existing rows changed during upgrade.'); } $f = json_decode(file_get_contents($s['PAYABLE_ACCESS_FILE']), true, 32, JSON_THROW_ON_ERROR); \Illuminate\Support\Facades\DB::transaction(function () use ($f): void { foreach (['preparacao' => 'reversal_prepare', 'validacao' => 'reversal_confirm'] as $role => $action) { $person = \Illuminate\Support\Facades\DB::table('pa_access')->where($f['scope'])->where(['user_id' => $f['accounts'][$role]['id'], 'action' => 'view'])->value('person'); if ($person !== 'synthetic-person-'.$role) throw new LogicException('Synthetic identity required.'); \Illuminate\Support\Facades\DB::table('pa_access')->insert($f['scope'] + ['user_id' => $f['accounts'][$role]['id'], 'person' => $person, 'action' => $action]); } }); echo "Explicit reversal upgrade and two synthetic grants installed on disposable $mode proof only.\n"; echo "All nine existing settlement tables preserved, including original allocations and decisions.\n";