Files
SGF/scripts/dossier-demo-proof.php
2026-11-04 09:37:20 +02:00

9 lines
3.3 KiB
PHP

<?php
use Illuminate\Support\Facades\DB;
$s=json_decode(file_get_contents(getenv('RECEIPT_COMPOSITION_STATE')),true);$out=$s['root'].'/dossier-demo-result.json';if(!($s['dossiers']??false)||is_file($out))throw new LogicException('New dossier demonstration required');require $s['app'].'/vendor/autoload.php';$app=require $s['app'].'/bootstrap/app.php';$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();$f=json_decode(file_get_contents($s['root'].'/fixture.json'),true);$n=json_decode(file_get_contents($s['root'].'/native-fixture.json'),true);config(['database.connections.dossier_demo'=>$s['nativeConnection']]);$db=DB::connection('dossier_demo');$checks=[];$ok=function($v,$name)use(&$checks){if(!$v)throw new RuntimeException($name);$checks[]=$name;};
$fingerprint=function()use($db){$rows=[];foreach(['requisitions','quotations','purchase_orders','goods_receipts','invoices','pa_obligations','audit_logs']as$table)$rows[$table]=$db->table($table)->orderBy('id')->get();$rows['grants']=DB::table('permission_grants')->orderBy('id')->get();$rows['locations']=DB::table('geo_locations')->get();return hash('sha256',json_encode($rows));};$before=$fingerprint();$ok($db->table('requisitions')->where('tenant_id',$n['tenant'])->count()===0&&$db->table('pa_obligations')->count()===0,'live dossier starts without invented process or responsibility');$client=new GuzzleHttp\Client(['base_uri'=>'http://127.0.0.1:8074','http_errors'=>false,'timeout'=>25]);
foreach(['requester','approver','actor','issuer','validator','reviewer']as$role){$jar=new GuzzleHttp\Cookie\CookieJar;$r=$client->get('/qa/enter/'.$role,['cookies'=>$jar]);$v=json_decode((string)$r->getBody(),true);$o=['cookies'=>$jar,'headers'=>['Accept'=>'application/json','X-SGF-Context'=>$v['context']]];$r=$client->get('/api/purchasing-dossiers',$o);$d=json_decode((string)$r->getBody(),true);$allowed=in_array($role,['requester','approver','actor','issuer'],true);$ok($allowed?($r->getStatusCode()===200&&$d['data']===[]):$r->getStatusCode()===403,'live dossier list respects '.$role);
if($role==='actor'){$r=$client->get('/purchasing/dossiers',$o);$ok($r->getStatusCode()===200&&str_contains((string)$r->getBody(),'purchasing-dossier.mjs'),'live dossier page served');$grant=DB::table('permission_grants')->where($f['scope'])->where('user_id',$f['actor'])->where('permission','purchasing_requests.view')->first();DB::table('permission_grants')->where('id',$grant->id)->delete();try{$r=$client->get('/api/purchasing-dossiers',$o);$ok($r->getStatusCode()===403,'revoked existing request right immediately removes dossier access');}finally{DB::table('permission_grants')->insert((array)$grant);}$r=$client->get('/api/purchasing-dossiers',$o);$ok($r->getStatusCode()===200,'restored fixture grant recovers consultation');}
}
$r=$client->get('/purchasing-dossier.mjs');$ok($r->getStatusCode()===200&&hash('sha256',(string)$r->getBody())===hash_file('sha256',$s['app'].'/public/purchasing-dossier.mjs'),'served dossier script matches delivery');$ok($fingerprint()===$before,'live checks preserve process grants and geographical evidence');file_put_contents($out,json_encode(['passed'=>true,'checks'=>$checks,'before'=>$before,'after'=>$fingerprint(),'visual_review'=>false],JSON_PRETTY_PRINT|JSON_THROW_ON_ERROR));echo count($checks)." dossier demonstration checks passed.\n";