make(\Illuminate\Contracts\Console\Kernel::class)->bootstrap(); use App\Modules\Industry\IndustrialCosts; use App\Shared\Context\CompanyContext; use Illuminate\Support\Facades\DB; use Illuminate\Support\Str; use Symfony\Component\Process\Process; IndustrialCosts::guard();$f=json_decode(file_get_contents('C:/laragon/data/sgf-tempo/secrets/browser-fixture.json'),true,32,JSON_THROW_ON_ERROR);$fx=$f['industrial'];$proof=[];$key=fn()=>(string)Str::uuid(); $base=['tenant'=>$f['tenant'],'company'=>$f['company'],'unit'=>$f['unit'],'lot'=>$fx['lot']]; $pair=function($one,$two)use($base){ $a=new Process([PHP_BINARY,'scripts/industrial-cost-worker.php','--env=testing'],base_path(),null,json_encode($one+$base+['pause'=>true]));$b=new Process([PHP_BINARY,'scripts/industrial-cost-worker.php','--env=testing'],base_path(),null,json_encode($two+$base)); $a->start();if(!$a->waitUntil(fn($t,$v)=>str_contains($v,'LOCK_HELD')))throw new RuntimeException('Industrial concurrent lock not observed.');$b->start();$a->wait();$b->wait();$out=[]; foreach([$a,$b] as $p){if(!$p->isSuccessful())throw new RuntimeException('Industrial worker failed.');$lines=array_values(array_filter(explode("\n",trim($p->getOutput())),fn($v)=>str_starts_with($v,'{')));$out[]=json_decode(end($lines),true,32,JSON_THROW_ON_ERROR);}return $out; }; $check=function($out,bool $replay){if($out[0]['status']!==200||$out[1]['status']!==($replay?200:409)||($replay&&(!$out[1]['result']['replayed']||$out[0]['result']['id']!==$out[1]['result']['id'])))throw new RuntimeException('Unexpected concurrent industrial result.');}; $old=DB::table('ic_inputs')->where(['lot_id'=>$fx['lot'],'kind'=>'criterion'])->orderByDesc('version')->first(); $input=['method'=>'input','actor'=>$f['manager_id'],'key'=>$key(),'input'=>['kind'=>'criterion','source_ref'=>$old->source_ref,'version'=>$old->version+1,'previous_id'=>$old->id,'data'=>json_decode($old->data,true),'evidence'=>'Revisão concorrente sintética.']];$out=$pair($input,$input);$check($out,true);$proof['criterion_repetition_one_version']=true;$id=$out[0]['result']['id'];$ver=$out[0]['result']['version']; $decision=['method'=>'decide','actor'=>$f['reader_id'],'key'=>$key(),'input'=>['type'=>'input','id'=>$id,'version'=>$ver,'decision'=>'approved','reason'=>'Validação concorrente de hipótese sintética.']];$check($pair($decision,$decision),true);$proof['decision_repetition_one_effect']=true; $one=$input;$one['key']=$key();$one['input']['version']=$ver+1;$one['input']['previous_id']=$id;$two=$one;$two['key']=$key();$two['input']['data']['capacity']='20';$out=$pair($one,$two);$check($out,false);$proof['competing_criteria_one_successor']=true;$cid=$out[0]['result']['id'];$cv=$out[0]['result']['version']; app(CompanyContext::class)->selectFor($f['reader_id'],$f['tenant'],$f['company'],$f['unit']);app(IndustrialCosts::class)->decide($fx['lot'],$f['reader_id'],['type'=>'input','id'=>$cid,'version'=>$cv,'decision'=>'approved','reason'=>'Validado critério sintético vencedor.'],$key()); $refs=$fx['refs']+['criterion'=>['id'=>$cid,'version'=>$cv]];$last=DB::table('ic_results')->where('lot_id',$fx['lot'])->orderByDesc('version')->first(); $calc=['method'=>'calculate','actor'=>$f['manager_id'],'key'=>$key(),'input'=>['currency'=>'MZN','version'=>$last->version+1,'previous_id'=>$last->id,'refs'=>$refs]];$out=$pair($calc,$calc);$check($out,true);$proof['calculation_repetition_one_snapshot']=true; $last=DB::table('ic_results')->where('lot_id',$fx['lot'])->orderByDesc('version')->first();$calc['key']=$key();$calc['input']['version']=$last->version+1;$calc['input']['previous_id']=$last->id;$calc['input']['refs']['material_rate']=null;$two=$calc;$two['key']=$key();$two['input']['refs']=$refs;$check($pair($calc,$two),false);$proof['competing_calculations_one_current_allocation']=true; $last=DB::table('ic_results')->where('lot_id',$fx['lot'])->orderByDesc('version')->first();$calc['key']=$key();$calc['input']['version']=$last->version+1;$calc['input']['previous_id']=$last->id;$calc['input']['refs']=$refs; $stale=['method'=>'decide','actor'=>$f['reader_id'],'key'=>$key(),'input'=>['type'=>'result','id'=>$last->id,'version'=>$last->version,'decision'=>'approved','reason'=>'Aprovação agora obsoleta.']];$check($pair($calc,$stale),false);$proof['new_result_refuses_old_approval']=true; file_put_contents(base_path('docs/proofs/industrial-cost-concurrency.json'),json_encode(['policy'=>IndustrialCosts::POLICY,'database'=>'sgf_tempo_test','overlapping_processes_per_case'=>2,'checks'=>$proof,'synthetic_only'=>true],JSON_PRETTY_PRINT|JSON_THROW_ON_ERROR));echo "Six overlapping industrial concurrency cases passed; historical allocations not accumulated.\n";