true]);if($book!=='regression')throw new LogicException('Simulated source only in regression harness'); $analysisSource=new class extends FinancialIndicatorSource{public array $values=['available'=>true,'kind'=>'analysis_harness_fixture','scope'=>['tenant_id'=>1,'company_id'=>2,'unit_id'=>2],'currency'=>'MZN','unit'=>'money','as_of'=>'2026-11-10','cash_balance_minor'=>'95000','cash_expenses_minor'=>'5000','cash_receipts_minor'=>'100000','supplier_credit_minor'=>'10000','cash_revision'=>9];public function snapshot(int $actor,array $scope):array{if($scope!==['tenant_id'=>1,'company_id'=>2,'unit_id'=>2])throw new LogicException('Fixture scope');$v=$this->values;$v['hash']=hash('sha256',Tempo\Finance\Payables\Payables::canonical($v));return $v;}}; $app->instance(FinancialIndicatorSource::class,$analysisSource);$analysis=app(FinancialIndicators::class); $selectAnalysis=function($actor=13,$generation='analysis-proof')use($app){Auth::forgetGuards();Auth::shouldUse('web');$user=App\Models\User::findOrFail($actor);Auth::guard('web')->setUser($user);$session=app('session')->driver();$session->start();$session->put('company_context',['tenant_id'=>1,'company_id'=>2,'unit_id'=>2,'module_id'=>'finance','token'=>$generation.'-'.$actor]);$r=Illuminate\Http\Request::create('/api/financial-indicators','POST');$r->setUserResolver(fn()=>$user);$r->setLaravelSession($session);$r->attributes->set('sgf_module','finance');$app->instance('request',$r);app(CompanyContext::class)->selectFor($actor,1,2,2);return $actor;}; $criterionData=function($metric){$d=FinancialIndicators::templates()[$metric];unset($d['label']);return $d+['scope_description'=>'Apenas as fontes QA expressamente delimitadas e data2026-11-10.','evidence'=>'Critério de ensaio confirmado explicitamente, sem recomendação financeira real.'];}; $criterionInput=fn($action,$metric,$version,$data)=>['action'=>$action,'metric'=>$metric,'version'=>$version,'data'=>$data,'reason'=>'Conferência individual QA do critério, fontes, direcção e fotografia.']; $indicatorInput=fn($id,$date='2026-11-10')=>['action'=>'calculate','version'=>0,'data'=>['criterion_id'=>$id,'as_of'=>$date],'reason'=>'Cálculo QA por versão do critério seleccionada e fontes conciliadas.']; $analysisPreview=function($actor,$in,$key=null)use($analysis,$selectAnalysis){$selectAnalysis($actor);return $analysis->preview($actor,$in,$key??(string)Str::uuid());}; $analysisCommand=function($actor,$in)use($analysis,$analysisPreview,$selectAnalysis){$p=$analysisPreview($actor,$in);$selectAnalysis($actor);return [$analysis->confirm($actor,$p['preview']),$p];}; $reject=function($fn,$status,$name)use($ok){try{$fn();throw new RuntimeException('Expected refusal: '.$name);}catch(Symfony\Component\HttpKernel\Exception\HttpExceptionInterface $e){$ok($e->getStatusCode()===$status,$name);}catch(Illuminate\Validation\ValidationException){$ok($status===422,$name);}};