make(Kernel::class)->bootstrap(); $owner = DB::connection('pgsql')->getConfig(); unset($owner['name']); if ($owner['host'] !== '127.0.0.1') { throw new LogicException('Local server required.'); } $qa = [...$owner, 'url'=>null, 'database'=>$s['DB_DATABASE'], 'username'=>$s['DB_USERNAME'], 'password'=>$s['DB_PASSWORD']]; config(['database.connections.receipt_install'=>$qa, 'database.connections.receipt_owner'=>[...$owner,'url'=>null,'database'=>'postgres']]); DB::setDefaultConnection('receipt_install'); $db = DB::connection(); $admin = DB::connection('receipt_owner'); $identity = $db->selectOne('select current_database() as db, current_user as role'); if ($identity->db !== $s['DB_DATABASE'] || $identity->role !== $s['DB_USERNAME']) { throw new LogicException('Identity mismatch.'); } $proofPath = $root.'/docs/proofs/receipt-block-installation.json'; if (file_exists($proofPath)) { throw new LogicException('Installation proof exists; inspect before repeating.'); } $tables = array_column($db->select("select tablename from pg_tables where schemaname='public' order by tablename"),'tablename'); if (in_array('receipt_documents',$tables,true)) { throw new LogicException('Document table already exists.'); } $fingerprint = function($connection,$tables) { $out=[]; foreach($tables as $table) { $rows=$connection->select('select row_to_json(t)::text as row from "'.str_replace('"','""',$table).'" t order by row_to_json(t)::text'); $out[$table]=hash('sha256',json_encode(array_column($rows,'row'),JSON_THROW_ON_ERROR)); } return $out; }; $pg = function($binary,$args,$connection) { $p=new Process(['C:/Program Files/PostgreSQL/17/bin/'.$binary.'.exe',...$args],null,['PGHOST'=>$connection['host'],'PGPORT'=>(string)$connection['port'],'PGUSER'=>$connection['username'],'PGPASSWORD'=>$connection['password']],timeout:120); $p->run(); if(!$p->isSuccessful()) { throw new RuntimeException('Backup/restore failed.'); } }; $restore='compras_pilot_restore_'.bin2hex(random_bytes(6)); $created=false; try { $db->beginTransaction(); $db->statement('SET TRANSACTION ISOLATION LEVEL REPEATABLE READ'); $baseline=$fingerprint($db,$tables); $directory='C:/laragon/data/sgf-tempo/backups/compras-receipt-documents-'.gmdate('Ymd-His').'-'.bin2hex(random_bytes(3)); if(!mkdir($directory,0700,true)) { throw new RuntimeException('Backup directory unavailable.'); } $dump=$directory.'/before.dump'; $snapshot=$db->selectOne('select pg_export_snapshot() as snapshot')->snapshot; $pg('pg_dump',['--format=custom','--snapshot='.$snapshot,'--file='.$dump,'--dbname='.$qa['database']],$qa); $db->commit(); $admin->statement('CREATE DATABASE "'.$restore.'"'); $created=true; $pg('pg_restore',['--no-owner','--no-privileges','--exit-on-error','--dbname='.$restore,$dump],$owner); config(['database.connections.receipt_restore'=>[...$owner,'url'=>null,'database'=>$restore]]); if($fingerprint(DB::connection('receipt_restore'),$tables)!==$baseline) { throw new LogicException('Restored backup differs.'); } $disk=Storage::disk('receipt_documents'); $probe='.installation-'.bin2hex(random_bytes(8)); try { $disk->put($probe,'private-storage-probe'); if($disk->get($probe)!=='private-storage-probe') { throw new RuntimeException('Storage unavailable.'); } } finally { $disk->delete($probe); } $migration='database/migrations/2026_11_03_000002_create_receipt_documents.php'; $db->transaction(function() use($db,$tables,$baseline,$fingerprint,$migration) { foreach($tables as $table) { $db->statement('LOCK TABLE "'.str_replace('"','""',$table).'" IN SHARE MODE'); } if($fingerprint($db,$tables)!==$baseline) { throw new LogicException('Pilot changed after backup; abort.'); } if(Artisan::call('migrate',['--database'=>'receipt_install','--path'=>$migration,'--force'=>true])!==0) { throw new RuntimeException('Target migration failed.'); } $protected=array_values(array_diff($tables,['migrations'])); if($fingerprint($db,$protected)!==array_intersect_key($baseline,array_flip($protected))) { throw new LogicException('Business data changed.'); } if($db->table('receipt_documents')->count()!==0 || $db->table('migrations')->where('migration','2026_11_03_000001_add_two_factor_columns_to_users')->exists()) { throw new LogicException('Unexpected installation state.'); } }); $proof=['checked_at'=>gmdate('c'),'environment'=>'http://127.0.0.1:8005','result'=>'passed','authorization'=>'User explicitly authorized receipt document block installation','migration'=>$migration,'backup'=>$dump,'backup_sha256'=>hash_file('sha256',$dump),'restored_tables_checked'=>count($tables),'protected_tables_checked'=>count($tables)-1,'business_data_unchanged'=>true,'documents_created'=>0,'mfa_enabled'=>false,'restore_database_removed'=>false]; } finally { if($db->transactionLevel()>0) { $db->rollBack(); } DB::purge('receipt_restore'); if($created) { $admin->statement('DROP DATABASE "'.$restore.'" WITH (FORCE)'); } } $proof['restore_database_removed']=true; file_put_contents($proofPath,json_encode($proof,JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES).PHP_EOL); echo 'Receipt documents installed; backup restored and business data preserved.'.PHP_EOL;