Files
SGF/scripts/sgf-statements-preservation.php
T
2026-11-11 09:00:17 +02:00

8 lines
4.6 KiB
PHP

<?php
$book='8085';require __DIR__.'/sgf-single-bootstrap.php';$pointer=json_decode(file_get_contents($s['root'].'/statements-backup-pointer.json'),true);$before=json_decode(file_get_contents($pointer['root'].'/preservation-private.json'),true);$checks=[];$ok=function($v,$name)use(&$checks){if(!$v)throw new LogicException($name);$checks[]=$name;};$identical=[];$allowed=[];
foreach(['host','native']as$name){$db=$name==='host'?$host:$native;foreach($before[$name]as$table=>$json){$order=in_array($table,['sr_outbox','sr_deliveries'],true)?'event_id':(in_array($table,['sc_catalogue_meta','pd_due_meta','fo_meta'],true)?'policy':'id');$rows=$db->table($table)->orderBy($order)->get();$old=json_decode($json,true);if(($name==='host'&&$table==='permission_grants')||($name==='native'&&$table==='audit_logs')){$byId=collect($old)->keyBy('id');$original=$rows->filter(fn($v)=>$byId->has($v->id))->values();$ok($original->toJson()===$json,'old '.$name.'.'.$table.' identical');$new=$rows->reject(fn($v)=>$byId->has($v->id))->values();$ok($new->count()===($table==='audit_logs'?4:2),'only authorized appended '.$name.'.'.$table);if($table==='permission_grants')$ok($new->map(fn($v)=>['user_id'=>$v->user_id,'permission'=>$v->permission,'tenant_id'=>$v->tenant_id,'company_id'=>$v->company_id,'unit_id'=>$v->unit_id])->all()===[['user_id'=>15,'permission'=>'general_ledger.statements.prepare','tenant_id'=>1,'company_id'=>2,'unit_id'=>2],['user_id'=>16,'permission'=>'general_ledger.statements.review','tenant_id'=>1,'company_id'=>2,'unit_id'=>2]],'exact approved two grants only');else$ok($new->every(fn($v)=>$v->action==='sgf.statements.command'),'only approved due command audits appended');$allowed[]=$name.'.'.$table;}else{$ok($rows->toJson()===$json,'identical '.$name.'.'.$table);$identical[]=$name.'.'.$table;}}}
foreach(['binding'=>'binding.json','single_binding'=>'single-bindings.json','stock_binding'=>'stock-binding.json']as$key=>$file)$ok(hash_file('sha256',$s['root'].'/'.$file)===$before[$key],$file.' unchanged');
$versions=$native->table('fs_versions')->orderBy('id')->get();$ok($versions->count()===4&&$versions->pluck('host_actor_id')->all()===[15,16,15,16],'four administrative versions distinct actors');$ok($native->table('fs_commands')->count()===4&&$native->table('fs_results')->count()===1&&$native->table('fs_result_lines')->count()===19,'one frozen result19lines four receipts');$result=json_decode($native->table('fs_results')->first()->data,true);$ok($result['summary']['currencies']['MZN']['unclassified_accounts']===9&&$result['summary']['currencies']['MZN']['equity_minor']===null&&$result['summary']['currencies']['MZN']['complete_result_minor']===null,'nine pending capital/result unknown');$ok($native->table('gl_journals')->count()===27&&$native->table('gl_accounts')->where(['tenant_id'=>1,'company_id'=>2,'unit_id'=>2])->count()===19,'original27 journals and19 accounts');$oldSource=json_decode(file_get_contents($s['root'].'/statements-source-private.json'),true);$accountRows=$native->table('gl_accounts')->where(['tenant_id'=>1,'company_id'=>2,'unit_id'=>2])->orderBy('code')->get(['id','code','label','currency']);foreach($oldSource['rows']as$row){$current=$accountRows->firstWhere('id',$row['account_id']);if(!$current||$current->code!==$row['code']||$current->label!==$row['label']||$current->currency!==$row['currency'])throw new LogicException('Original account changed');}$ok(true,'account metadata equals previous read-only report');
$public=$native->select("SELECT c.relname FROM pg_class c CROSS JOIN LATERAL aclexplode(coalesce(c.relacl,CASE WHEN c.relkind='S' THEN acldefault('S',c.relowner) ELSE acldefault('r',c.relowner) END)) a WHERE c.relnamespace='public'::regnamespace AND c.relname IN('fs_meta','fs_versions','fs_results','fs_result_lines','fs_commands','fs_versions_id_seq','fs_commands_id_seq') AND a.grantee=0");$ok($public===[],'no PUBLIC table or sequence rights');$fun=$native->select("SELECT a.* FROM pg_proc p CROSS JOIN LATERAL aclexplode(coalesce(p.proacl,acldefault('f',p.proowner))) a WHERE p.pronamespace='public'::regnamespace AND p.proname='fs_append_only' AND a.grantee=0");$ok($fun===[],'no PUBLIC function execution');
file_put_contents($work.'/statements-preservation.json',json_encode(['passed'=>true,'checks'=>$checks,'identical_original_tables'=>$identical,'original_rows_preserved_with_authorized_append'=>$allowed,'new_grants'=>2,'new_command_receipts'=>4,'new_demo'=>false,'financial_effects'=>0,'cache_cleared'=>false,'protected_six_targeted'=>false],JSON_PRETTY_PRINT));echo json_encode(['passed'=>true,'checks'=>count($checks),'identical_tables'=>count($identical),'preserved_plus_append'=>count($allowed),'proof'=>$work.'/statements-preservation.json']).PHP_EOL;