true]); $u=App\Models\User::findOrFail($profiles['finance_prepare']['user_id']);Auth::guard('web')->setUser($u);$r=Illuminate\Http\Request::create('/api/finance/payables','GET');$session=app('session')->driver();$session->start();$session->put('company_context',$f['scope']+['module_id'=>'finance','token'=>'lock-proof']);$r->setLaravelSession($session);$r->setUserResolver(fn()=>$u);$app->instance('request',$r);app(CompanyContext::class)->selectFor($u->id,$f['tenant'],$f['company'],$f['unit']); config(['database.connections.finance_lock_probe'=>$host->getConfig()]);$blocking=DB::connection('finance_lock_probe');$before=$native->table('ps_payments')->count();$blocking->beginTransaction(); try{ $blocking->table('companies')->where(['tenant_id'=>1,'id'=>2])->lockForUpdate()->firstOrFail();$start=microtime(true);$result=app(App\Modules\Purchasing\ComposedFinance::class)->run('view',fn()=>throw new LogicException('Blocked work must not start'));$elapsed=microtime(true)-$start; $ok($result->getStatusCode()===503,'competing company transaction returns recoverable503');$ok($result->headers->get('Retry-After')==='5','busy response provides bounded retry guidance');$ok($elapsed>=4.5&&$elapsed<12,'company mutex timeout is bounded near five seconds'); }finally{$blocking->rollBack();DB::purge('finance_lock_probe');} $result=app(App\Modules\Purchasing\ComposedFinance::class)->run('view',fn($engine)=>$engine->positionsPage([]));$ok(is_array($result),'same finance authority proceeds after first transaction releases company mutex');$ok($before===$native->table('ps_payments')->count(),'timeout and recovery do not duplicate or create financial facts'); file_put_contents($work.'/finance-lock-result.json',json_encode(['passed'=>true,'checks'=>$checks,'blocked_seconds'=>$elapsed,'blocking_resource'=>'host companies row tenant1/company2; authority and immutable source boundary','new_business_effects'=>0],JSON_PRETTY_PRINT));echo json_encode(['passed'=>true,'checks'=>count($checks),'proof'=>$work.'/finance-lock-result.json']).PHP_EOL;