table('br_events')->count();$host->beginTransaction();try{ $selectBank(13);$state=$bank->listing(13,[]);$id=$state['statement']['id'];$last=(array)$host->table('br_events')->where('statement_id',$id)->orderByDesc('version')->first();$version=$last['version'];$previous=$last['id'];for($i=0;$i<63;$i++){$prep=['tenant_id'=>1,'company_id'=>2,'unit_id'=>2,'statement_id'=>$id,'version'=>++$version,'previous_id'=>$previous,'proposal_id'=>null,'action'=>'prepare_match','state'=>'match_prepared','prepared_by'=>13,'actor_id'=>13,'data'=>json_encode(['row_reference'=>'QA-OUT-20','ledger_line_id'=>4,'journal_id'=>2,'debit_minor'=>2000,'credit_minor'=>0,'source_hash'=>'fixture']),'reason'=>'Metadados de histórico QA para paginação, não uma correspondência confirmada.','created_at'=>now()];$proposal=$host->table('br_events')->insertGetId($prep);$prep['version']=++$version;$prep['previous_id']=$proposal;$prep['proposal_id']=$proposal;$prep['action']='review_match';$prep['state']='match_refused';$prep['actor_id']=14;$previous=$host->table('br_events')->insertGetId($prep);} $selectBank(17);$a=$bank->listing(17,['view'=>'history','per_page'=>25]);$all=[];for($page=1;$page<=$a['history']['last_page'];$page++)$all=array_merge($all,$bank->listing(17,['view'=>'history','per_page'=>25,'page'=>$page])['history']['data']);$ok(count($all)===$before+126&&count(array_unique(array_column($all,'id')))===count($all),'128 history metadata events paginated25 no duplication');$a=$bank->listing(17,['view'=>'history','per_page'=>100]);$a2=$bank->listing(17,['view'=>'history','per_page'=>100,'page'=>2]);$ok(count($a['history']['data'])===100&&count($a2['history']['data'])===$before+26,'pages100 and28 same history universe');$ok(count($bank->listing(17,['status'=>'unmatched'])['rows'])===2&&count($bank->listing(17,['status'=>'matched'])['rows'])===0,'row status filters do not treat refused proposals as matches');$reject(fn()=>$bank->listing(17,['tenant_id'=>2]),422,'no scope override');$reject(fn()=>$bank->listing(17,['per_page'=>500]),422,'no excessive page'); $selectBank(13);request()->attributes->set('sgf_module','accounting');$reject(fn()=>$bank->listing(13,[]),403,'wrong module rejected');$selectBank(13);$reject(function()use($bank){app(CompanyContext::class)->selectFor(13,1,2,1);return $bank->listing(13,[]);},403,'other unit rejected');$selectBank(13);$p=$bankPreview(13,$bankInput('prepare_match',$version,['row_reference'=>'QA-IN-20','ledger_line_id'=>5]));$selectBank(13,'different-generation');$reject(fn()=>$bank->confirm(13,$p['preview']),409,'generation invalidates match preview'); $attempt=function($fn)use($host){$host->beginTransaction();try{$fn();return false;}catch(Illuminate\Database\QueryException){return true;}finally{$host->rollBack();}};$ok($attempt(fn()=>$host->table('br_events')->where('id',$previous)->update(['reason'=>'Attempted history alteration'])),'SQL append-only history');$bad=$prep;$bad['version']=++$version;$bad['previous_id']=$previous;$bad['proposal_id']=null;$bad['action']='prepare_match';$bad['state']='match_prepared';$bad['actor_id']=17;$bad['prepared_by']=17;$ok($attempt(fn()=>$host->table('br_events')->insert($bad)),'SQL unprivileged writer refused'); }finally{$host->rollBack();}$ok($host->table('br_events')->count()===$before,'metadata history fixtures rolled back');file_put_contents($work.'/bank-boundaries.json',json_encode(['passed'=>true,'checks'=>$checks,'metadata_history_fixtures'=>126,'origin_simulated_in_harness'=>true,'rolled_back'=>true],JSON_PRETTY_PRINT));echo json_encode(['passed'=>true,'checks'=>count($checks),'proof'=>$work.'/bank-boundaries.json']).PHP_EOL;