true]); $service = app(SupplierPayables::class); $enter = function (string $role) use ($f, $scope): User { $u = User::findOrFail($f['actors'][$role]); auth()->setUser($u); app(CompanyContext::class)->selectFor($u->id, $scope['tenant_id'], $scope['company_id'], $scope['unit_id']); return $u; }; $command = fn (string $role, string $action, array $data) => $service->engine($enter($role))->settlements()->command($action, $data, (string) Str::uuid()); $fingerprint = function (): string { $h = hash_init('sha256'); foreach (['pa_imported_sources','pa_source_histories','pa_sources','pa_proposals','pa_obligations','pa_history_imports','pa_imported_payments','pa_events','pa_commands','pa_access', ...SettlementSchema::TABLES, ...ReversalSchema::TABLES] as $table) { hash_update($h, $table."\n"); foreach (DB::table($table)->orderBy($table === 'ps_outbox' ? 'event_id' : 'id')->cursor() as $row) hash_update($h, Payables::canonical((array) $row)."\n"); } return hash_final($h); }; if ($phase === 'settlement-page-http') { auth()->forgetGuards(); Illuminate\Support\Facades\Route::middleware('web')->get('/qa/settlement-enter', function (Request $r) use ($f) { $u=User::findOrFail($f['actors']['read']); auth()->login($u); $r->session()->regenerate(); $token=bin2hex(random_bytes(24)); $r->session()->put('auth_version',$u->auth_version); $r->session()->put('company_context',$f['scope']+['token'=>$token,'module_id'=>'purchasing']); return response()->json(['csrf'=>csrf_token(),'context'=>$token])->header('Cache-Control','no-store'); }); $app->handleRequest(Request::capture()); exit; } if ($phase === 'settlement-page-setup') { if (DB::getSchemaBuilder()->hasTable('ps_payments')) throw new LogicException('Fresh settlement fixture required'); SettlementSchema::install(); ReversalSchema::install(); foreach (['prepare'=>['payments_view','payment_prepare','allocation_prepare','reversal_prepare'], 'validate'=>['payments_view','payment_confirm','allocation_confirm','reversal_confirm'], 'read'=>['payments_view']] as $role=>$actions) { foreach($actions as $action) DB::table('pa_access')->insert($scope+['user_id'=>$f['actors'][$role],'action'=>$action,'person'=>'sgf-history-person-'.$f['actors'][$role]]); } $base=$service->document($enter('read'),$f['source_id']); unset($base['local_id']); $obligations=[]; $sources=[]; for($n=1;$n<=61;$n++) { $doc=array_replace($base,['document'=>110000+$n,'number'=>'SETTLE-PAGE-SOURCE-'.$n,'payment_count'=>0]); $payload=Payables::canonical($doc); $id=DB::table('pa_imported_sources')->insertGetId($scope+['payload'=>$payload,'receipt_hash'=>hash('sha256',$payload)]); $p=$service->engine($enter('prepare'))->command('prepare',$id,'Explicit synthetic source for settlement pages.',(string)Str::uuid()); $o=$service->engine($enter('validate'))->command('validate',$p['proposal_id'],'Independent synthetic recognition.',(string)Str::uuid()); $obligations[]=$o['obligation_id']; $sources[]=$id; } $revision=DB::table('pa_obligations')->where('id',$obligations[0])->value('source_revision'); $p=$command('prepare','payment-prepare',['obligation_id'=>$obligations[0],'source_revision'=>$revision,'amount'=>'1.00','currency'=>'MZN','paid_on'=>'2026-10-29','fact_reference'=>'SIM-PAGE-ORIGINAL','evidence_reference'=>'SIM-PAGE-EVIDENCE','reason'=>'Synthetic payment fact for bounded reading.']); $payment=$p['payment_id']; $command('validate','payment-decide',['payment_id'=>$payment,'decision'=>'confirmed','evidence_reference'=>'SIM-PAGE-CONFIRM','reason'=>'Independent synthetic payment evidence.']); $proposalIds=[]; foreach(array_chunk(array_slice($obligations,0,60),30) as $batch=>$ids) { $plan=[];foreach($ids as $id)$plan[]=['obligation_id'=>$id,'source_revision'=>DB::table('pa_obligations')->where('id',$id)->value('source_revision'),'amount'=>'0.01']; $p=$command('prepare','allocation-prepare',['payment_id'=>$payment,'reference'=>'SIM-PAGE-PLAN-'.$batch,'allocations'=>$plan,'reason'=>'Synthetic partial allocations across obligations.']); $command('validate','allocation-decide',['proposal_id'=>$p['proposal_id'],'decision'=>'confirmed','reason'=>'Independent synthetic allocation review.']); $proposalIds[]=$p['proposal_id']; } $oldest=DB::table('ps_allocations')->where('payment_id',$payment)->orderBy('id')->first(); $r=$command('prepare','reversal-prepare',['allocation_id'=>$oldest->id,'source_revision'=>$oldest->source_revision,'reason'=>'Synthetic integral correction with original preserved.']); $command('validate','reversal-confirm',['proposal_id'=>$r['proposal_id'],'reason'=>'Independent integral reversal review.']); $last=end($obligations); $pending=$command('prepare','allocation-prepare',['payment_id'=>$payment,'reference'=>'SIM-PAGE-PENDING','allocations'=>[['obligation_id'=>$last,'source_revision'=>DB::table('pa_obligations')->where('id',$last)->value('source_revision'),'amount'=>'0.10']],'reason'=>'Pending proposal to test current revision after reading.']); file_put_contents($s['root'].'/settlement-fixture.json',json_encode(['source_ids'=>$sources,'obligation_ids'=>$obligations,'payment_id'=>$payment,'confirmed_proposals'=>$proposalIds,'pending_proposal_id'=>$pending['proposal_id'],'original_payment_unallocated_minor'=>41,'synthetic_only'=>true],JSON_PRETTY_PRINT|JSON_THROW_ON_ERROR)); echo "Fresh synthetic settlement workflow prepared: 61 obligations, one payment, 60 allocations and one reversal.\n"; exit; } $g=json_decode(file_get_contents($s['root'].'/settlement-fixture.json'),true,64,JSON_THROW_ON_ERROR); $u=$enter('read'); if(str_starts_with($phase,'settlement-read-')){require __DIR__.'/settlement-read-proof.php';exit;} if ($phase === 'settlement-page-seed') { if(DB::table('ps_payments')->count()!==1)throw new LogicException('Seed cannot reset or replace retained facts'); DB::transaction(function()use($g,$scope,$f){ $template=(array)DB::table('ps_payments')->where('id',$g['payment_id'])->first();unset($template['id']); $proposal=(array)DB::table('ps_proposals')->where('id',$g['confirmed_proposals'][0])->first();unset($proposal['id']); $decision=(array)DB::table('ps_payment_decisions')->where('payment_id',$g['payment_id'])->first();unset($decision['id']); $allocDecision=(array)DB::table('ps_allocation_decisions')->where('proposal_id',$g['confirmed_proposals'][0])->first();unset($allocDecision['id']); $allocation=(array)DB::table('ps_allocations')->where('payment_id',$g['payment_id'])->orderBy('id')->first();unset($allocation['id']); $key=fn($v)=>hash('sha256',Payables::canonical([array_intersect_key($scope,array_flip(['tenant_id','company_id'])),$v])); for($n=1;$n<=999;$n++) { $fact='SIM-PAGE-CLONE-'.str_pad((string)$n,4,'0',STR_PAD_LEFT);$evidence='SIM-EVID-CLONE-'.$n; $snapshot=json_decode($template['snapshot'],true,64,JSON_THROW_ON_ERROR);$snapshot['fact_reference']=$fact;$snapshot['evidence_reference']=$evidence; $row=array_replace($template,['fact_reference'=>$fact,'evidence_reference'=>$evidence,'fact_key'=>$key($fact),'evidence_key'=>$key($evidence),'snapshot'=>Payables::canonical($snapshot),'payload_hash'=>hash('sha256',Payables::canonical($snapshot))]); $id=DB::table('ps_payments')->insertGetId($row);$state=$n%3===0?'proposed':($n%3===1?'confirmed':'rejected'); if($state!=='proposed')DB::table('ps_payment_decisions')->insert(array_replace($decision,['payment_id'=>$id,'decision'=>$state])); if($state==='confirmed') { $reference='SIM-PLAN-CLONE-'.$n;$plan=[['obligation_id'=>$allocation['obligation_id'],'source_revision'=>$allocation['source_revision'],'amount_minor'=>1]]; $pid=DB::table('ps_proposals')->insertGetId(array_replace($proposal,['payment_id'=>$id,'reference'=>$reference,'reference_key'=>$key($reference),'plan'=>Payables::canonical($plan),'plan_hash'=>hash('sha256',Payables::canonical($plan))])); $did=DB::table('ps_allocation_decisions')->insertGetId(array_replace($allocDecision,['proposal_id'=>$pid])); DB::table('ps_allocations')->insert(array_replace($allocation,['payment_id'=>$id,'decision_id'=>$did,'amount_minor'=>1])); } DB::table('ps_events')->insert($scope+['payment_id'=>$id,'actor_id'=>$f['actors']['prepare'],'person'=>'sgf-history-person-'.$f['actors']['prepare'],'kind'=>'qa.explicit_benchmark_clone','payload'=>'{}','created_at'=>now()]); } }); $hash=$fingerprint();file_put_contents($s['root'].'/settlement-volume.json',json_encode(['payments'=>1000,'actual_command_workflow_payments'=>1,'explicit_benchmark_clones'=>999,'indices_added'=>false,'baseline_fingerprint'=>$hash],JSON_PRETTY_PRINT|JSON_THROW_ON_ERROR)); echo "Synthetic volume ready: 1000 payment facts, original command workflow preserved.\n";exit; } if ($phase === 'settlement-page-cases') { require __DIR__.'/settlement-page-cases.php'; exit; } if ($phase === 'settlement-page-nav') { $request=Request::create('/supplier-payments?'.http_build_query(['source'=>$g['source_ids'][0],'payment_state'=>'confirmed','payments_page'=>2]),'GET'); $request->setUserResolver(fn()=>$u);$request->setLaravelSession(app('session')->driver()); $html=app(SupplierPaymentsController::class)->page($request)->getContent(); if(!preg_match('/href="([^"]+)">Consultar todas as origens/',$html,$match))throw new LogicException('Source exit absent'); parse_str(parse_url(html_entity_decode($match[1]),PHP_URL_QUERY)??'',$query); if(isset($query['source'])||($query['payment_state']??'')!=='confirmed'||($query['payments_page']??'')!=='2'||($query['page']??'')!=='1')throw new LogicException('Source exit loses independent payment filters'); file_put_contents($s['root'].'/settlement-nav.json',json_encode(['passed'=>true,'source_exit_preserves_payment_filters'=>true,'document_page_reset'=>true],JSON_PRETTY_PRINT));echo "Source exit preserves independent ledger filters.\n";exit; } if ($phase === 'settlement-page-bench') { $strategy=$argv[3]??'';if(!in_array($strategy,['legacy','page25','page100','focus'],true))throw new LogicException('Unknown measurement'); $book=$service->engine($u)->settlements();$book->listingPage(['payment'=>$g['payment_id']]);$queries=0;$active=false; DB::listen(function()use(&$queries,&$active){if($active)$queries++;});gc_collect_cycles();memory_reset_peak_usage();$baseline=memory_get_usage(true);$active=true;$start=hrtime(true); $data=$strategy==='legacy'?$book->listing():$book->listingPage($strategy==='focus'?['payment'=>$g['payment_id']]:['payment_per_page'=>$strategy==='page25'?25:100]); $ms=(hrtime(true)-$start)/1e6;$active=false;$peak=memory_get_peak_usage(true);$windows=[]; foreach(['payments','proposals','allocations','events'] as $table){ $rows=json_decode(json_encode($data[$table],JSON_THROW_ON_ERROR),true,128,JSON_THROW_ON_ERROR); foreach($rows as &$row)unset($row['local_source_id']);unset($row); usort($rows,fn($a,$b)=>$b['id']<=>$a['id']); foreach($strategy==='legacy'?[25,100]:($strategy==='focus'?[]:[$strategy==='page25'?25:100]) as $size)$windows[$table][$size]=hash('sha256',Payables::canonical(array_slice($rows,0,$size))); } $original=array_values(array_filter($data['payments'],fn($p)=>$p['id']===$g['payment_id'])); $report=['strategy'=>$strategy,'volume'=>DB::table('ps_payments')->count(),'time_ms'=>round($ms,3),'queries'=>$queries,'php_heap_baseline_bytes'=>$baseline,'php_heap_peak_bytes'=>$peak,'window_fingerprints'=>$windows,'original_payment_fingerprint'=>hash('sha256',Payables::canonical(json_decode(json_encode($original,JSON_THROW_ON_ERROR),true,128,JSON_THROW_ON_ERROR))),'original_unallocated_minor'=>$original[0]['unallocated_minor']??null,'rows'=>array_map('count',array_intersect_key($data,array_flip(['payments','proposals','allocations','events','reversal_proposals','reversals']))),'indices_added'=>false,'php'=>PHP_VERSION,'not_deployment_capacity'=>true]; file_put_contents($s['root'].'/settlement-bench-'.$strategy.'.json',json_encode($report,JSON_PRETTY_PRINT|JSON_THROW_ON_ERROR));echo json_encode($report)."\n";exit; } if ($phase === 'settlement-page-post') { DB::beginTransaction();DB::statement('SET TRANSACTION READ ONLY');try{ $baseline=json_decode(file_get_contents($s['root'].'/settlement-volume.json'),true,64,JSON_THROW_ON_ERROR);$hash=$fingerprint(); $bundle=json_decode(file_get_contents($s['root'].'/source.json'),true,64,JSON_THROW_ON_ERROR);$doc=$bundle['source'];unset($doc['local_id']); $original=json_decode(DB::table('pa_imported_sources')->where('id',$f['source_id'])->value('payload'),true,64,JSON_THROW_ON_ERROR); if($baseline['baseline_fingerprint']!==$hash||Payables::canonical($original)!==Payables::canonical($doc)||DB::table('ps_payments')->count()!==1000)throw new LogicException('Retained synthetic facts changed'); file_put_contents($s['root'].'/settlement-post.json',json_encode(['passed'=>true,'read_only'=>true,'baseline_fingerprint_equal'=>true,'business_fingerprint'=>$hash,'copied_original_receipt_unchanged'=>true,'payment_count'=>1000,'source_databases_and_demos_not_written'=>true],JSON_PRETTY_PRINT|JSON_THROW_ON_ERROR)); }finally{DB::rollBack();}echo "Synthetic financial rows unchanged after tests and measurement.\n";exit; } throw new LogicException('Unknown settlement page phase');