make(Kernel::class)->bootstrap(); $args = getopt('', ['qa', 'apply', 'output:', 'preview-sha256:', 'backup:']); $qa = isset($args['qa']); $apply = isset($args['apply']); $expected = $qa ? 'simulator_fiscal_delta_20261021_test' : 'teste_investidor'; $port = $qa ? 55441 : 5432; $identity = DB::selectOne('select current_database() as name,inet_server_port() as port'); if ($identity->name !== $expected || (int) $identity->port !== $port) { throw new RuntimeException('Named isolated QA or homologation required.'); } if (! $qa && (! getenv('SSH_CONNECTION') || ! function_exists('posix_geteuid') || posix_geteuid() !== 0 || rtrim(config('app.url'), '/') !== 'https://teste-investidor.tempo.co.mz')) { throw new RuntimeException('Authenticated destination operator required.'); } $output = $args['output'] ?? ''; if (! $output || is_file($output) || str_contains(str_replace('\\', '/', $output), '/public/')) { throw new RuntimeException('New private receipt path required.'); } $service = app(ApprovedAnchorTerritories::class); DB::beginTransaction(); try { DB::statement($apply ? 'SET TRANSACTION ISOLATION LEVEL SERIALIZABLE' : 'SET TRANSACTION ISOLATION LEVEL REPEATABLE READ READ ONLY'); if ($apply) { DB::select('select pg_advisory_xact_lock(231026,28)'); } $plan = $service->plan(); $hash = hash('sha256', json_encode([$expected, $plan], JSON_THROW_ON_ERROR)); $result = ['mode' => $apply ? 'applied' : 'preview', 'database' => $expected, 'port' => $port, 'qa' => $qa, 'manifest_sha256' => ApprovedAnchorTerritories::HASH, 'preview_sha256' => $hash, 'relations' => count($plan['links']), 'projects' => count($plan['projects'])]; if ($apply) { if (! hash_equals($hash, $args['preview-sha256'] ?? '')) { throw new RuntimeException('Destination changed after preview.'); } if (! $qa) { $directory = $args['backup'] ?? ''; $backup = json_decode(file_get_contents($directory.'/backup-receipt.json'), true, 512, JSON_THROW_ON_ERROR); $restore = json_decode(file_get_contents($directory.'/restore-receipt.json'), true, 512, JSON_THROW_ON_ERROR); if (! $restore['restore_verified'] || $backup['target']['database'] !== $expected || (int) $backup['target']['port'] !== $port || ! hash_equals($backup['sha256'], $restore['source_dump_sha256']) || ! hash_equals($backup['sha256'], hash_file('sha256', $backup['dump_path']))) { throw new RuntimeException('Matching backup and isolated restoration required.'); } } file_put_contents($output.'.before.json', json_encode($plan, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR)); if (! $qa) { chmod($output.'.before.json', 0600); } $result += $service->apply($plan); DB::commit(); } else { DB::rollBack(); } file_put_contents($output, json_encode([...$result, 'plan' => $plan], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR)); if (! $qa) { chmod($output, 0600); } echo json_encode($result, JSON_THROW_ON_ERROR); } catch (Throwable $error) { if (DB::transactionLevel()) { DB::rollBack(); } throw $error; }