$v){putenv($k.'='.$v);$_ENV[$k]=$_SERVER[$k]=$v;} require $settings['HOST_ROOT'].'/vendor/autoload.php';$app=require $settings['HOST_ROOT'].'/bootstrap/app.php';$app->make(\Illuminate\Contracts\Console\Kernel::class)->bootstrap(); use Illuminate\Support\Facades\DB; use Symfony\Component\Process\Process; $db=DB::connection();if(!preg_match('/^(compras_receipts_test_|payable_sgf_)[a-f0-9]{12}$/D',$db->getDatabaseName())||$db->selectOne('select current_database() as d')->d!==$settings['DB_DATABASE'])throw new LogicException('Unsafe probe target'); $f=json_decode(file_get_contents($settings['PAYABLE_ACCESS_FILE']),true,32,JSON_THROW_ON_ERROR); $input=json_decode(stream_get_contents(STDIN)?:'{}',true,64,JSON_THROW_ON_ERROR); $class=$mode==='compras'?\App\Services\SupplierPayables::class:\App\Modules\Purchasing\SupplierPayables::class; $select=function($role)use($mode,$f){$u=\App\Models\User::findOrFail($f['accounts'][$role]['id']);auth()->guard()->setUser($u);if($mode==='sgf')app(\App\Shared\Context\CompanyContext::class)->selectFor($u->id,$f['scope']['tenant_id'],$f['scope']['company_id'],$f['scope']['unit_id']);return $u;}; if($job==='inspect'){ $counts=[];foreach(['sources','proposals','obligations','events','outbox','commands'] as $t)$counts[$t]=$db->table('pa_'.$t)->count(); $domain=[];if($mode==='compras')foreach(['invoices','invoice_items','budget_entries','budget_consumptions','stock_movements','external_payments'] as $t)$domain[$t]=hash('sha256',\Tempo\Finance\Payables\Payables::canonical($db->table($t)->orderBy('id')->get()->map(fn($r)=>(array)$r)->all())); $u=$select('consulta');$d=app($class)->listing($u);$out=['counts'=>$counts,'domain_hashes'=>$domain,'core_sha256'=>hash_file('sha256',__DIR__.'/../packages/payables/src/Payables.php'),'recognised_events'=>$db->table('pa_events')->where('kind','payable.recognised')->count(),'obligations'=>$d['obligations']]; if($mode==='compras'){try{$out['legacy_balance']=app(\App\Services\ExternalPaymentWorkflow::class)->outstanding(\App\Models\Invoice::findOrFail($f['source_id']));}catch(\Symfony\Component\HttpKernel\Exception\HttpException $e){$out['legacy_balance_blocked']=$e->getStatusCode();}} }elseif($job==='grant'){ $role=$input['role'];$action=$input['action'];if(!isset($f['accounts'][$role])||!in_array($action,['view','prepare','validate'],true))throw new LogicException('Invalid synthetic grant'); $match=$f['scope']+['user_id'=>$f['accounts'][$role]['id'],'action'=>$action]; if($input['enabled'])$db->table('pa_access')->insertOrIgnore($match+['person'=>'synthetic-person-'.$role]);else$db->table('pa_access')->where($match)->delete();$out=['changed'=>true]; }elseif($job==='source'){ $original=json_decode(file_get_contents($settings['PAYABLE_BUNDLE']),true,64,JSON_THROW_ON_ERROR); $over=$input['override']??[];if(array_diff(array_keys($over),['status','total_minor','supplier_name','currency','payment_count']))throw new LogicException('Invalid adversarial fields'); $s=array_replace($original,$over); if($mode==='compras'){ $row=$db->table('invoices')->where('id',$f['source_id'])->first();$snap=json_decode($row->snapshot,true);$snap['currency']=$s['currency'];$snap['supplier']['name']=$s['supplier_name']; $db->table('invoices')->where('id',$f['source_id'])->update(['status'=>$s['status'],'total_minor'=>$s['total_minor'],'snapshot'=>json_encode($snap,JSON_THROW_ON_ERROR)]); }else{$db->table('pa_imported_sources')->where('id',$f['source_id'])->update(['payload'=>\Tempo\Finance\Payables\Payables::canonical($s),'receipt_hash'=>hash('sha256',\Tempo\Finance\Payables\Payables::canonical($s))]);} $out=['source_revision_test_only'=>true]; }elseif($job==='fault'){ if($input['enabled'])$db->unprepared("CREATE FUNCTION pa_qa_fault() RETURNS trigger LANGUAGE plpgsql AS $$ BEGIN IF NEW.kind='payable.recognised' THEN RAISE EXCEPTION 'PA_QA_FAULT'; END IF; RETURN NEW; END $$; CREATE TRIGGER pa_qa_fault BEFORE INSERT ON pa_events FOR EACH ROW EXECUTE FUNCTION pa_qa_fault()"); else $db->unprepared('DROP TRIGGER pa_qa_fault ON pa_events; DROP FUNCTION pa_qa_fault()');$out=['fault_configured'=>true]; }elseif($job==='worker'){ $u=$select($input['role']);$db->select('select set_config(?, ?, false)',['application_name',$input['label']]); try{$r=app($class)->engine($u)->command($input['action'],$input['id'],'Concurrent synthetic proof',$input['key']);$out=['status'=>200,'state'=>$r['state']];} catch(\Symfony\Component\HttpKernel\Exception\HttpException $e){$out=['status'=>$e->getStatusCode()];} $out['pid']=$db->selectOne('select pg_backend_pid() as p')->p; }elseif($job==='race'){ $db->beginTransaction();$db->table($mode==='compras'?'tenants':'companies')->where('id',$mode==='compras'?$f['scope']['tenant_id']:$f['scope']['company_id'])->lockForUpdate()->firstOrFail(); $processes=[];$results=[]; try{ foreach([0,1] as $i){$p=new Process([PHP_BINARY,__FILE__,$mode,'worker'],$settings['HOST_ROOT']);$p->setInput(json_encode($input+['key'=>\Illuminate\Support\Str::uuid()->toString(),'label'=>'pa_proof_'.$i],JSON_THROW_ON_ERROR));$p->setTimeout(30);$p->start();$processes[]=$p;} config(['database.connections.pa_monitor'=>$db->getConfig()]);$monitor=DB::connection('pa_monitor');$deadline=microtime(true)+15;$waits=0; do{$waits=(int)$monitor->selectOne("select count(*) as n from pg_stat_activity where datname=? and application_name in ('pa_proof_0','pa_proof_1') and wait_event_type='Lock'",[$db->getDatabaseName()])->n;if($waits===2)break;foreach($processes as $p)if(!$p->isRunning())throw new RuntimeException('Worker exited: '.$p->getOutput().$p->getErrorOutput());usleep(20000);}while(microtime(true)<$deadline); if($waits!==2)throw new RuntimeException('Concurrency overlap not observed'); if($input['revoke']??false)$db->table('pa_access')->where($f['scope'])->where(['user_id'=>$f['accounts']['validacao']['id'],'action'=>'validate'])->delete(); $db->commit();foreach($processes as $p){$p->wait();if(!$p->isSuccessful())throw new RuntimeException('Worker failed: '.$p->getOutput().$p->getErrorOutput());$results[]=json_decode($p->getOutput(),true,32,JSON_THROW_ON_ERROR);} $out=['waits'=>$waits,'results'=>$results]; }finally{if($db->transactionLevel())$db->rollBack();foreach($processes as $p)if($p->isRunning())$p->stop();} }elseif($job==='history'){ $u=$select('preparacao'); if($mode==='compras'){ $invoice=\App\Models\Invoice::findOrFail($f['source_id']); $bank=\App\Models\SupplierBankDetail::query()->create(['tenant_id'=>$u->tenant_id,'supplier_id'=>$invoice->supplier_id,'created_by'=>$u->id,'revision'=>1,'bank_name'=>'Banco exclusivamente fictício','country'=>'MZ','currency'=>'MZN','beneficiary'=>'Titular de fixture histórica','account_identifier'=>'SYNTHETIC-HISTORY-NOT-A-BANK-ACCOUNT','evidence_reference'=>'Fixture histórica adversarial','reason'=>'Prova de exclusão de documentos com liquidações','created_at'=>now()]); \App\Models\ExternalPayment::query()->create(['tenant_id'=>$u->tenant_id,'invoice_id'=>$invoice->id,'supplier_bank_detail_id'=>$bank->id,'created_by'=>$u->id,'reviewed_by'=>$f['accounts']['validacao']['id'],'status'=>'confirmed','amount_minor'=>30000,'currency'=>'MZN','paid_on'=>now()->format('Y-m-d'),'external_reference'=>'HISTORY-QA-ONLY','reference_hash'=>hash('sha256','HISTORY-QA-ONLY'),'payload_hash'=>hash('sha256','HISTORY-PAYLOAD'),'evidence_reference'=>'Historical test fixture, not executed payment','bank_snapshot'=>['synthetic_fixture'=>true],'review_reason'=>'Existing historical fact fixture','reviewed_at'=>now()]); $rows=$db->table('external_payments')->orderBy('id')->get()->map(fn($r)=>(array)$r)->all();$out=['payment_history_hash'=>hash('sha256',\Tempo\Finance\Payables\Payables::canonical($rows))]; }else{ $r=$db->table('pa_imported_sources')->where('id',$f['source_id'])->first();$s=json_decode($r->payload,true);$s['payment_count']=1; $db->table('pa_imported_sources')->where('id',$r->id)->update(['payload'=>\Tempo\Finance\Payables\Payables::canonical($s),'receipt_hash'=>hash('sha256',\Tempo\Finance\Payables\Payables::canonical($s))]);$out=['historical_source_projection'=>true]; } }elseif($job==='foreign_actor'){ $now=now();$tenant=$db->table('tenants')->insertGetId(['name'=>'Outra empresa sintética','created_at'=>$now,'updated_at'=>$now]); if($mode==='compras'){ $u=\App\Models\User::factory()->create(['tenant_id'=>$tenant,'purchasing_role'=>'finance']);$scope=['tenant_id'=>$tenant,'company_id'=>0,'unit_id'=>0]; }else{ $company=$db->table('companies')->insertGetId(['tenant_id'=>$tenant,'name'=>'Outra empresa sintética','created_at'=>$now,'updated_at'=>$now]);$unit=$db->table('units')->insertGetId(['tenant_id'=>$tenant,'company_id'=>$company,'name'=>'Outra unidade','created_at'=>$now,'updated_at'=>$now]);$scope=['tenant_id'=>$tenant,'company_id'=>$company,'unit_id'=>$unit]; $u=\App\Models\User::create(['name'=>'Outro preparador sintético','email'=>'other-'.bin2hex(random_bytes(6)).'@example.test','password'=>bin2hex(random_bytes(20))]); $db->table('company_memberships')->insert(['user_id'=>$u->id,'tenant_id'=>$tenant,'company_id'=>$company]);foreach(['company.view'=>null,'unit.view'=>$unit,'supplier_payables.view'=>$unit] as $permission=>$unitId)$db->table('permission_grants')->insert(['user_id'=>$u->id,'tenant_id'=>$tenant,'company_id'=>$company,'unit_id'=>$unitId,'permission'=>$permission,'created_at'=>$now,'updated_at'=>$now]); } foreach(['view','prepare'] as $action)$db->table('pa_access')->insert($scope+['user_id'=>$u->id,'person'=>'foreign-synthetic-person','action'=>$action]); auth()->guard()->setUser($u);if($mode==='sgf')app(\App\Shared\Context\CompanyContext::class)->selectFor($u->id,$scope['tenant_id'],$scope['company_id'],$scope['unit_id']); try{app($class)->engine($u)->command('prepare',$f['source_id'],'Forbidden foreign document',\Illuminate\Support\Str::uuid()->toString());$out=['refused'=>false];}catch(\Illuminate\Database\Eloquent\ModelNotFoundException|\Symfony\Component\HttpKernel\Exception\HttpException){$out=['refused'=>true];} }elseif($job==='future'){ \Illuminate\Support\Carbon::setTestNow('2030-12-31 12:00:00');$out=app($class)->listing($select('consulta'))['obligations']; }elseif($job==='foreign'){ $u=$select('consulta');$engine=app($class)->engine($u);$foreign=new \Tempo\Finance\Payables\Payables($db,$u->id,'foreign-person',['tenant_id'=>999999,'company_id'=>999999,'unit_id'=>999999],fn()=>null,fn($id)=>$mode==='compras'?app($class)->document($u,$f['source_id']):app($class)->document($u,$f['source_id'])); try{$foreign->command('prepare',$f['source_id'],'Wrong mapped context',\Illuminate\Support\Str::uuid()->toString());$out=['refused'=>false];}catch(\DomainException){$out=['refused'=>true];} }else throw new LogicException('Unknown probe'); echo json_encode($out,JSON_THROW_ON_ERROR).PHP_EOL;