Files
SGF/scripts/purchasing-focus-read-body.php
2026-11-04 09:37:20 +02:00

24 lines
6.1 KiB
PHP

<?php
if(!($s['focus']??false)||!($s['read_overlay']??false))throw new LogicException('New read-only focus application required');
$fingerprint=function($connection){$result=[];foreach($connection->select("SELECT tablename FROM pg_tables WHERE schemaname='public' ORDER BY tablename")as$table){if(!preg_match('/^[a-z0-9_]+$/D',$table->tablename))throw new LogicException('Unexpected fixture table');$name=$table->tablename;$row=$connection->selectOne('SELECT count(*) n,md5(coalesce(string_agg(row_to_json(t)::text,\'\' ORDER BY row_to_json(t)::text),\'\')) h FROM "'.$name.'" t');$result[$name]=[(int)$row->n,$row->h];}$result['sequences']=$connection->select("SELECT sequencename,last_value FROM pg_sequences WHERE schemaname='public' ORDER BY sequencename");return $result;};
$before=['host'=>$fingerprint(DB::connection()),'native'=>$fingerprint($db)];$saved=json_decode(file_get_contents($s['original_root'].'/integrated-result.json'),true);$ids=$saved['source_ids'];$request=$ids['request'];$url='/api/purchasing-dossiers/'.$request;$receipt=(int)$db->table('goods_receipts')->where('purchase_order_id',$ids['order'])->value('id');
$r=$call('issuer',$url);$full=$r['data'];$ok($r['status']===200&&$full['read_only']&&$full['_links'][0]['href']==='/purchasing/requests?request='.$request,'dossier identifies exact existing request without issuing a command');
$links=$full['_links'];foreach($full['stages']as$stage)foreach($stage['data']??[]as$row)foreach($row['_links']??[]as$link)$links[]=$link;$hrefs=array_values(array_unique(array_column($links,'href')));
$expected=['/purchasing/requests?request='.$request,'/purchasing/sourcing?request='.$request,'/purchasing/orders?award='.$ids['award'],'/purchasing/receipts?order='.$ids['order'],'/purchasing/invoices?order='.$ids['order'],'/purchasing/receipts?order='.$ids['order'].'&receipt='.$receipt,'/purchasing/invoices?order='.$ids['order'].'&invoice='.$ids['invoice'],'/purchasing/obligations?invoice='.$ids['invoice']];$ok(array_diff($expected,$hrefs)===[]&&array_diff($hrefs,$expected)===[],'all eight contextual links correlate real canonical ids and authorised destination stages');
foreach($hrefs as$href){$r=$call('issuer',$href);$ok($r['status']===200&&str_contains($r['body'],'data-focus-enabled="true"'),'contextual destination is mounted: '.$href);}
foreach([
['/api/purchasing-requests/'.$request,'request','id',$request],
['/api/purchasing-sourcing/requests/'.$request,'request','id',$request],
['/api/purchasing-orders/awards/'.$ids['award'],'basis','award',null],
['/api/purchasing-receipts/orders/'.$ids['order'],'order','id',$ids['order']],
['/api/purchasing-receipts/history/'.$receipt,'receipt','purchase_order_id',$ids['order']],
['/api/purchasing-invoices/orders/'.$ids['order'],'order','id',$ids['order']],
]as[$path,$key,$field,$value]){$r=$call('issuer',$path);$ok($r['status']===200&&($value===null?$r['data'][$key][$field]['id']===$ids['award']:$r['data'][$key][$field]===$value),'destination API independently admits expected source: '.$path);}
$r=$call('issuer','/api/purchasing-obligations/'.$ids['invoice']);$ok($r['status']===200&&$r['data']['documents'][0]['local_id']===$ids['invoice']&&$r['data']['obligations'][0]['principal_minor']===10000,'obligation focus resolves the actual invoice and existing canonical100MZN responsibility');
$r=$call('requester',$url);$owner=$r['data'];$ownerLinks=$owner['_links'];foreach($owner['stages']as$stage)foreach($stage['data']??[]as$row)foreach($row['_links']??[]as$link)$ownerLinks[]=$link;$ok($r['status']===200&&count($ownerLinks)===1&&$ownerLinks[0]['href']==='/purchasing/requests?request='.$request,'request-only dossier reveals no hidden-stage links or record ids');$ok($call('requester','/api/purchasing-invoices/orders/'.$ids['order'])['status']===403&&$call('requester','/api/purchasing-obligations/'.$ids['invoice'])['status']===403,'copied finance links confer no authority on request-only profile');
$r=$call('actor',$url);$buyerLinks=[];foreach($r['data']['stages']as$stage)foreach($stage['data']??[]as$row)foreach($row['_links']??[]as$link)$buyerLinks[]=$link['href'];$ok($r['status']===200&&!array_filter($buyerLinks,fn($v)=>str_contains($v,'/invoices')||str_contains($v,'/obligations')),'buyer links do not advertise restricted economic stages');
$ok($call('issuer','/api/purchasing-invoices/orders/'.($db->table('purchase_orders')->where('tenant_id','<>',$n['tenant'])->value('id')??999999))['status']===403&&$call('issuer','/api/purchasing-dossiers/'.$n['foreign_requisition'])['status']===403,'foreign request and foreign or unknown order remain inaccessible at destination and dossier');
$enter('issuer',1,['module'=>'commercial']);$ok($call('issuer','/api/purchasing-obligations/'.$ids['invoice'],null,1)['status']===409,'link does not switch or bypass active module');$enter('issuer',1,['foreign'=>1]);$ok($call('issuer','/api/purchasing-receipts/history/'.$receipt,null,1)['status']===403,'link does not switch or bypass unit context');$ok($call('issuer','/api/purchasing-orders/awards/'.$ids['award'],null,0,['X-SGF-Context'=>'old'])['status']===409,'stale context token is rechecked in destination API');
config(['receipt_qa.focus_enabled'=>false]);$sample=['stages'=>['orders'=>['accessible'=>true,'data'=>[['id'=>7]]]]];$ok(app(App\Modules\Purchasing\ProcessNavigation::class)->decorate($sample,['sourcing'=>true],3)===$sample,'disabled navigation leaves existing dossier payload unchanged');
$after=['host'=>$fingerprint(DB::connection()),'native'=>$fingerprint($db)];$ok(json_encode($before)===json_encode($after),'all reused canonical host/native tables and sequences unchanged by navigation proof');file_put_contents($out,json_encode(['passed'=>true,'checks'=>$checks,'contextual_links'=>count($hrefs),'reused_proof'=>'purchasing-integrated-composition-20261103.json','financial_commands_repeated'=>0,'before_sha256'=>hash('sha256',json_encode($before)),'after_sha256'=>hash('sha256',json_encode($after)),'tables_checked'=>count($before['host'])+count($before['native'])-2,'new_right_names'=>[],'visual_review'=>false,'deployment_capacity_validated'=>false],JSON_PRETTY_PRINT|JSON_THROW_ON_ERROR));echo count($checks)." purchasing focus read checks passed.\n";