<?php
declare(strict_types=1);
require __DIR__.'/bootstrap.php';require __DIR__.'/oracle.php';require __DIR__.'/StrictWire.php';require __DIR__.'/SqlCoverageRecorder.php';$phase=getenv('ANALYSIS_PHASE')==='green'?'green':'red';$reportPath=$runtime.($phase==='green'?'/private-green-report.json':'/private-report.json');$check(!is_file($reportPath),'No blind repeat; this phase checkpoint already exists');if($phase==='green'){$red=json_decode(file_get_contents($runtime.'/private-report.json'),true);$check(count($red['cases'])===7,'Exact original seven native requests required');}$check((int)$query('SELECT COUNT(*) n FROM yoshop_meal_score_subtable WHERE user_id=?',[$operator])[0]['n']===0,'Synthetic Auth operator has no natural score records');$token=bin2hex(random_bytes(24));$cache->set($token,['user'=>['store_user_id'=>$operator,'store_id'=>$tenant,'real_name'=>$marker,'user_name'=>$marker,'is_super'=>1],'store_id'=>$tenant,'is_login'=>true],1800);
$snapshot=analysisOriginalSnapshot($read,$tenant,$staff,$operator);$beforeHash=hash('sha256',serialize($snapshot));$cases=[];$errors=[];$collections=[];$stats=[];$diff=static function($a,$b,$path='')use(&$diff){if(gettype($a)!==gettype($b))return [['path'=>$path,'actual_type'=>gettype($a),'expected_type'=>gettype($b)]];if(is_object($a)){$x=get_object_vars($a);$y=get_object_vars($b);$out=[];foreach(array_unique(array_merge(array_keys($x),array_keys($y))) as $k){if(!array_key_exists($k,$x)||!array_key_exists($k,$y))$out[]=['path'=>$path.'/'.$k,'missing_in'=>array_key_exists($k,$x)?'expected':'actual'];else $out=array_merge($out,$diff($x[$k],$y[$k],$path.'/'.$k));}return $out;}if(is_array($a)){$out=[];if(count($a)!==count($b))$out[]=['path'=>$path,'array_length_differs'=>true];foreach($a as $k=>$v)if(array_key_exists($k,$b))$out=array_merge($out,$diff($v,$b[$k],$path.'/'.$k));return $out;}return $a===$b?[]:[['path'=>$path,'actual_type'=>gettype($a),'expected_type'=>gettype($b),'actual_sha256'=>hash('sha256',serialize($a)),'expected_sha256'=>hash('sha256',serialize($b))]];};
$checkpoint=static function()use($reportPath,&$cases,&$errors,&$collections,&$stats,$snapshot,$beforeHash,$boundary,$tenant,$staff){file_put_contents($reportPath,json_encode(['cases'=>$cases,'errors'=>$errors,'collections'=>$collections,'stats'=>$stats,'original_snapshot'=>$snapshot,'before_sha256'=>$beforeHash,'boundary'=>$boundary,'tenant'=>$tenant,'staff'=>$staff],JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE|JSON_PRESERVE_ZERO_FRACTION));chmod($reportPath,0600);};$checkpoint();
foreach([['supply',0],['dishesType',0],['dietary',0],['vitamin',1],['vitamin',2],['dietaryFiber',0],['cookingMethod',0]] as [$action,$type]){try{$want=analysisOriginalOracle($snapshot,$action,$type?:1);$expected=json_decode(json_encode($want,JSON_UNESCAPED_UNICODE));$scenario='PILOT_TA_'.strtoupper($action).($type?'_'.$type:'');$params=['staff_id'=>$staff];if($type)$params['type']=$type;$script=["pm.test('HTTP transport200',function(){pm.response.to.have.status(200);});var b=pm.response.json();","pm.test('Numeric business200',function(){pm.expect(b.status).to.eql(200);});","pm.test('Trace contract',function(){pm.expect(b.trace_id).to.match(/^[0-9a-f]{13}$/);});","pm.test('Complete independent original-table projection and formulas',function(){pm.expect(b.data).to.deep.eql(".json_encode($want,JSON_UNESCAPED_UNICODE|JSON_UNESCAPED_SLASHES).");});"];$item=['id'=>$scenario,'name'=>'terminal '.$action.($type?' type'.$type:''),'type'=>'http','metaInfo'=>['type'=>'HTTP'],'request'=>['method'=>'GET','url'=>$base.'/terminal/analysis.analysis/'.$action.'?'.http_build_query($params),'header'=>[['key'=>'Host','value'=>'analysis-natural.invalid'],['key'=>'Access-Token','value'=>$token],['key'=>'Platform','value'=>'POC'],['key'=>'X-Pilot-Scenario','value'=>$scenario]]],'event'=>[['listen'=>'test','script'=>['type'=>'text/javascript','exec'=>$script]]]];$collection=['apifoxCli'=>'2.2.8','info'=>['name'=>'设备端营养分析自然原表只读验收'],'item'=>[['name'=>'有界自然样本完整原表oracle','item'=>[$item]]]];$collections[]=$collection;$file=$runtime.'/private-collection.json';file_put_contents($file,json_encode($collection,JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE));chmod($file,0600);$dir=$runtime.'/private-cli-report/'.$scenario;if(!is_dir($dir))mkdir($dir,0700,true);$proc=proc_open(['node',getenv('ANALYSIS_CLI'),'run',$file,'-r','json','--out-dir',$dir,'--out-file','result','--on-error','continue','--timeout-request','30000','--silent'],[0=>['file','/dev/null','r'],1=>['file',$runtime.'/private-cli.log','a'],2=>['file',$runtime.'/private-cli.log','a']],$pipes);$exit=proc_close($proc);$wire=null;foreach(is_file($runtime.'/private-wire.jsonl')?file($runtime.'/private-wire.jsonl',FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES):[] as $line){$w=json_decode($line,true);if($w['scenario']===$scenario)$wire=$w;}$check($wire!==null,'Native actual wire missing '.$scenario);$body=json_decode($wire['raw']);$actual=$body->data??null;$equal=strictWireEqual($actual,$expected);$current=analysisOriginalSnapshot($read,$tenant,$staff,$operator);$stateEqual=hash('sha256',serialize($current))===$beforeHash;$case=['scenario'=>$scenario,'path'=>'/terminal/analysis.Analysis/'.$action,'method'=>'GET','action'=>$action,'type'=>$type,'native_exit'=>$exit,'http_status'=>$wire['http_status'],'business_status'=>$body->status??null,'actual_body'=>$body,'expected_data'=>$expected,'complete_original_equal'=>$equal,'difference'=>$diff($actual,$expected),'consumed_original_unchanged'=>$stateEqual,'raw_sha256'=>hash('sha256',$wire['raw']),'elapsed_ms'=>$wire['elapsed_ms']];$cases[]=$case;$checkpoint();foreach(glob($dir.'/*.json') as $f){$r=json_decode(file_get_contents($f),true);if(isset($r['run']))$stats[]=['scenario'=>$scenario,'stats'=>$r['run']['stats'],'failures'=>count($r['run']['failures']),'raw_report_sha256'=>hash_file('sha256',$f)];}$checkpoint();$check($stateEqual,'Consumed natural original rows drifted');}catch(Throwable $e){$errors[]=['action'=>$action,'type'=>$type,'message'=>$e->getMessage()];$checkpoint();}}
$cache->delete($token);$cache->clear();$after=analysisOriginalSnapshot($read,$tenant,$staff,$operator);$private=json_decode(file_get_contents($reportPath),true);$private['after_sha256']=hash('sha256',serialize($after));$private['tokens_reclaimed']=$cache->get($token)===null;$private['business_DML']=0;$private['source_row_counts']=array_map(static function($v){return is_array($v)?count($v):1;},$snapshot);$sqlAudit=[];foreach(file($runtime.'/private-sql.jsonl',FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES)?:[] as $line){$v=json_decode($line,true);$sql=$v['sql'];if(preg_match('/^\s*(INSERT|UPDATE|DELETE|REPLACE|MERGE|ALTER|DROP|CREATE)\b/i',$sql))$private['business_DML']++;$sqlAudit[]=['scenario'=>$v['scenario'],'operation'=>SqlCoverageRecorder::fingerprint($sql)['operation'],'sha256'=>hash('sha256',$sql)];}$private['sql_audit']=$sqlAudit;file_put_contents($reportPath,json_encode($private,JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE|JSON_PRESERVE_ZERO_FRACTION));chmod($reportPath,0600);echo json_encode(['lane'=>$lane,'phase'=>$phase,'HTTP'=>count($cases),'original_equal'=>array_column($cases,'complete_original_equal'),'diff_paths'=>array_map(static function($c){return [$c['scenario'],$c['difference']];},$cases),'errors'=>$errors,'DML'=>$private['business_DML'],'consumed_unchanged'=>$private['before_sha256']===$private['after_sha256']]),"\n";
