Files
SGF/scripts/sgc-invoice-authority-proof.php
2026-11-11 09:00:17 +02:00

23 lines
2.6 KiB
PHP

<?php
require __DIR__.'/sgc-invoice-proof-bootstrap.php';
use Illuminate\Support\Facades\{Crypt,DB};
if(!is_file($proofRoot.'/context-result.json')||is_file($proofRoot.'/authority-result.json'))throw new LogicException('Fresh authority continuation required');
$p=json_decode(file_get_contents($proofRoot.'/initial-preview.json'),true);$cut=json_decode(Crypt::decryptString($p['data']['preview']),true);
$body=['phase'=>'confirm','order_id'=>$cut['order_id'],'preview'=>$p['data']['preview']];$key=$cut['operation_key'];
$checks=[];$ok=function($v,$name)use(&$checks){if(!$v)throw new RuntimeException($name);$checks[]=$name;};
$invoices=$native->table('invoices')->orderBy('id')->get()->toJson();$events=$native->table('audit_logs')->count();
$ok($send($body,$key)['status']===200,'current native operator lock permits authorised recovery');
$nativeRuntime=DB::connection('receipt_native');$role=$nativeRuntime->table('users')->where('id',$cut['actor'])->value('purchasing_role');
$nativeRuntime->beginTransaction();try{$nativeRuntime->table('users')->where('id',$cut['actor'])->update(['purchasing_role'=>'warehouse']);$ok($send($body,$key)['status']===403,'revoked native finance function prevents receipt recovery');}finally{$nativeRuntime->rollBack();}
$ok($nativeRuntime->table('users')->where('id',$cut['actor'])->value('purchasing_role')===$role,'native finance fixture restored by transaction rollback');
$app->instance(Tempo\Purchasing\Embedded\Services\OrganizationAccess::class,new class extends Tempo\Purchasing\Embedded\Services\OrganizationAccess{
public function maintenanceOnly(Tempo\Purchasing\Embedded\Models\User $user):bool{return true;}
});
try{$ok($send($body,$key)['status']===403,'maintenance-only native operator cannot recover invoice receipt');}
finally{$app->forgetInstance(Tempo\Purchasing\Embedded\Services\OrganizationAccess::class);}
$ok($send($body,$key)['status']===200,'normal recovery resumes without another business command');
$ok($invoices===$native->table('invoices')->orderBy('id')->get()->toJson()&&$events===$native->table('audit_logs')->count(),'operator guard checks add no invoice or audit commands');
file_put_contents($proofRoot.'/authority-result.json',json_encode(['passed'=>true,'checks'=>$checks,'new_business_rows'=>0,'previous_context_sha256'=>hash_file('sha256',$proofRoot.'/context-result.json'),
'sources'=>[['file'=>'app/Modules/Purchasing/SgcInvoiceIngress.php','sha256'=>hash_file('sha256',$repo.'/app/Modules/Purchasing/SgcInvoiceIngress.php')]]],JSON_PRETTY_PRINT|JSON_THROW_ON_ERROR));
echo json_encode(['passed'=>true,'checks'=>count($checks)]).PHP_EOL;