Files
SGF/scripts/payables-provision.php
2026-10-29 18:43:29 +02:00

31 lines
4.5 KiB
PHP

<?php
$sgf=realpath(__DIR__.'/..');$compras=realpath($sgf.'/../compras');require $compras.'/vendor/autoload.php';
foreach(['APP_ENV'=>'payables-coordinator','DB_CONNECTION'=>'pgsql','CACHE_STORE'=>'array','SESSION_DRIVER'=>'array'] as $k=>$v){putenv($k.'='.$v);$_ENV[$k]=$_SERVER[$k]=$v;}
$app=require $compras.'/bootstrap/app.php';$app->make(\Illuminate\Contracts\Console\Kernel::class)->bootstrap();
use Illuminate\Support\Facades\DB;use Symfony\Component\Process\Process;
$proof=in_array('--proof',$argv,true)||in_array('--cleanup-proof',$argv,true);$tag=$proof?'proof':'demo';$private='C:/laragon/data/sgf-tempo/secrets/';
$source=DB::connection('pgsql')->getConfig();if($source['host']!=='127.0.0.1')throw new LogicException('Local QA maintenance only.');
config(['database.connections.pa_admin'=>[...$source,'database'=>'postgres','url'=>null]]);$admin=DB::connection('pa_admin')->getPdo();
if(in_array('--cleanup-proof',$argv,true)){
foreach(['compras','sgf'] as $mode){$path=$private.'payables-proof-'.$mode.'.json';if(!is_file($path))continue;$s=json_decode(file_get_contents($path),true,32,JSON_THROW_ON_ERROR);$db=$s['DB_DATABASE'];$role=$s['DB_USERNAME'];
if(!preg_match('/^(compras_receipts_test_|payable_sgf_)([a-f0-9]{12})$/D',$db,$m)||$role!=='payable_qa_'.$m[2])throw new LogicException('Invalid proof cleanup target.');
$team=$private.'payables-demo-'.$mode.'.json';if(is_file($team)&&json_decode(file_get_contents($team),true)['DB_DATABASE']===$db)throw new LogicException('Team database protected.');
$q=$admin->prepare('select pg_terminate_backend(pid) from pg_stat_activity where datname=? and pid<>pg_backend_pid()');$q->execute([$db]);$admin->exec('DROP DATABASE "'.$db.'"');$admin->exec('DROP ROLE "'.$role.'"');unlink($path);$a=$private.'payables-proof-'.$mode.'-access.json';if(is_file($a))unlink($a);
}$bundle=$private.'payables-proof-source.json';if(is_file($bundle))unlink($bundle);echo "Disposable payables proof databases and roles removed.\n";exit;
}
$instance='qa-compras-'.bin2hex(random_bytes(16));$bundle=$private.'payables-'.$tag.'-source.json';
foreach(['compras','sgf'] as $mode){
$path=$private.'payables-'.$tag.'-'.$mode.'.json';if(is_file($path)){echo "Existing $mode payables scenario retained.\n";continue;}
if($mode==='sgf'&&is_file($private.'payables-'.$tag.'-compras.json'))$instance=json_decode(file_get_contents($private.'payables-'.$tag.'-compras.json'),true)['PAYABLE_SOURCE_INSTANCE'];
$suffix=bin2hex(random_bytes(6));$db=($mode==='compras'?'compras_receipts_test_':'payable_sgf_').$suffix;$role='payable_qa_'.$suffix;$pw=bin2hex(random_bytes(32));
$admin->exec('CREATE ROLE "'.$role.'" LOGIN NOSUPERUSER NOCREATEDB NOCREATEROLE PASSWORD '.$admin->quote($pw));
$admin->exec('CREATE DATABASE "'.$db.'" OWNER "'.$role.'"');
$root=$mode==='compras'?$compras:$sgf;$runtime=$root.'/storage/framework/payables/'.$tag;
$env=['APP_ENV'=>$mode==='compras'?'testing':'payable-testing','APP_DEBUG'=>'false','APP_KEY'=>'base64:'.base64_encode(random_bytes(32)),'DB_CONNECTION'=>'pgsql','DB_URL'=>'','DB_HOST'=>'127.0.0.1','DB_PORT'=>(string)$source['port'],'DB_DATABASE'=>$db,'DB_USERNAME'=>$role,'DB_PASSWORD'=>$pw,'SESSION_DRIVER'=>'file','SESSION_COOKIE'=>'payables_'.$tag.'_'.$mode,'SESSION_FILES'=>$runtime.'/sessions','CACHE_STORE'=>'file','CACHE_FILE_PATH'=>$runtime.'/cache','CACHE_LOCK_PATH'=>$runtime.'/locks','QUEUE_CONNECTION'=>'sync','MAIL_MAILER'=>'array','BCRYPT_ROUNDS'=>'4','COMMON_PAYABLES_PATH'=>$sgf.'/packages/payables','PAYABLE_SOURCE_INSTANCE'=>$instance,'PAYABLE_ACCESS_FILE'=>$private.'payables-'.$tag.'-'.$mode.'-access.json','PAYABLE_BUNDLE'=>$bundle,'HOST_MODE'=>$mode,'HOST_ROOT'=>$root];
foreach(['sessions','cache','locks'] as $dir)if(!is_dir($runtime.'/'.$dir))mkdir($runtime.'/'.$dir,0700,true);
$php=$mode==='compras'?PHP_BINARY:'C:/laragon/tools/sgf-tempo/php-8.4.27/php.exe';
try{$p=new Process([$php,$sgf.'/packages/payables/tests/seed.php',$mode],$root,$env);$p->setTimeout(70);$p->run();if(!$p->isSuccessful())throw new RuntimeException('QA source preparation failed: '.$p->getOutput().$p->getErrorOutput());
$env['APP_ENV']='payable-testing';file_put_contents($path,json_encode($env,JSON_THROW_ON_ERROR),LOCK_EX);echo "Prepared isolated $mode payables scenario from conferred source.\n";
}catch(\Throwable $e){$q=$admin->prepare('select pg_terminate_backend(pid) from pg_stat_activity where datname=?');$q->execute([$db]);$admin->exec('DROP DATABASE "'.$db.'"');$admin->exec('DROP ROLE "'.$role.'"');throw $e;}
}