commit21
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Contracts\Console\Kernel;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Symfony\Component\Process\Process;
|
||||
|
||||
require dirname(__DIR__).'/vendor/autoload.php';
|
||||
$root = dirname(__DIR__);
|
||||
if (!in_array('--apply-authorized', $argv, true)) { throw new LogicException('Explicit authorized installation required.'); }
|
||||
$s = json_decode(file_get_contents('C:/laragon/data/sgf-tempo/secrets/payables-demo-compras.json'), true, 32, JSON_THROW_ON_ERROR);
|
||||
if (($s['APP_ENV'] ?? '') !== 'payable-testing' || ($s['DB_HOST'] ?? '') !== '127.0.0.1' || realpath($s['HOST_ROOT'] ?? '') !== realpath($root) || !preg_match('/^compras_receipts_test_([a-f0-9]{12})$/D', $s['DB_DATABASE'] ?? '', $m) || $s['DB_USERNAME'] !== 'payable_qa_'.$m[1]) { throw new LogicException('Wrong pilot destination.'); }
|
||||
$app = require $root.'/bootstrap/app.php';
|
||||
$app->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;
|
||||
Reference in New Issue
Block a user