<?php
declare(strict_types=1);
require __DIR__.'/bootstrap.php';require __DIR__.'/StrictWire.php';$before=$snapshot();foreach($pks as $t=>$pk)$check((int)$query('SELECT COUNT(*) n FROM yoshop_'.$t.' WHERE store_id=?',[$tenant])[0]['n']===0,'New tenant collision '.$t);
define('TP_ENV','poc');define('BUSINESS','aizhct');define('ENTERPRISE_NO','10001');require $root.'/vendor/autoload.php';spl_autoload_register(static function(string $class)use($root):void{foreach(['app\\'=>'app/','cores\\'=>'cores/'] as $p=>$d)if(strpos($class,$p)===0){$f=$root.'/'.$d.str_replace('\\','/',substr($class,strlen($p))).'.php';if(is_file($f))require $f;return;}},true,true);$app=new \think\App($root);$app->setEnvName('poc');$app->setRuntimePath($runtime.'/fixture-runtime/');$app->initialize();$cache=new \think\cache\driver\File($app,['path'=>$runtime.'/cache/','prefix'=>'','expire'=>0]);$token=bin2hex(random_bytes(24));$cache->set($token,['user'=>['store_user_id'=>$tenant,'store_id'=>$tenant,'real_name'=>$marker,'user_name'=>$marker,'is_super'=>1],'store_id'=>$tenant,'is_login'=>true],1800);
$cases=[];$responses=[];$proofs=[];$findings=[];$errors=[];$uid=0;$sid=0;$masterIds=[];$masterInputs=[];$healthExpected=[];$map=['staff_id'=>0];$saveMap=static function()use($runtime,&$map){file_put_contents($runtime.'/private-owned-map.json',json_encode($map));chmod($runtime.'/private-owned-map.json',0600);};$saveMap();
$shape=static function($v)use(&$shape){if(is_object($v)){$o=[];foreach(get_object_vars($v) as $k=>$x)$o[$k]=$shape($x);ksort($o);return ['object'=>$o];}if(is_array($v))return ['array'=>array_map($shape,$v)];return gettype($v);};
$request=static function(string $name,string $kind,string $action,array $data=[])use($base,$token,$check,$shape,&$cases,&$responses):array{$scenario='PILOT_CF_'.$name;$path='/store/store.'.$kind.'/'.$action;$h="Host: store.staff-config.invalid\r\nAccess-Token: ".$token."\r\nPlatform: POC\r\nX-Pilot-Scenario: ".$scenario."\r\nContent-Type: application/json\r\n";$start=time();$raw=file_get_contents($base.$path,false,stream_context_create(['http'=>['method'=>'POST','header'=>$h,'content'=>json_encode($data,JSON_UNESCAPED_UNICODE),'timeout'=>30,'ignore_errors'=>true]]));$end=time();$body=json_decode((string)$raw,true);preg_match('#^HTTP/\S+\s+(\d+)#',$http_response_header[0]??'',$m);$check(is_array($body)&&strlen($raw)<1048576,'Actual HTTP JSON');$c=['scenario'=>$scenario,'method'=>'POST','path'=>$path,'http_status'=>(int)($m[1]??0),'body'=>$body,'raw_json_shape'=>$shape(json_decode($raw))];$cases[]=$c;$responses[$scenario]=['raw'=>$raw,'start'=>$start,'end'=>$end];return $c;};
$success=static function(array $c)use($check):void{$check($c['http_status']===200&&($c['body']['status']??0)===200,'Business success '.$c['scenario']);};
$wire=static function(array $actual,array $expected,string $scenario)use(&$cases,&$findings,&$responses):void{$raw=json_decode($responses[$scenario]['raw']);if(strictWireEqual($raw->data,json_decode(json_encode($expected)))){$cases[count($cases)-1]['complete_mysql_original_projection_equal']=true;return;}$cases[count($cases)-1]['complete_mysql_original_projection_equal']=false;$findings[]=['scenario'=>$scenario,'classification'=>'wire-vs-MySQL-original-full-projection','full_raw_wire_private'=>true];};
$insert=static function(string $t,array $data)use($db,$query,$check,$tenant,&$owned):int{$check(in_array($t,['user','staff'],true)&&$data['store_id']===$tenant,'Fixture write boundary');$s=$db->prepare('INSERT INTO yoshop_'.$t.' ('.implode(',',array_keys($data)).') VALUES ('.implode(',',array_fill(0,count($data),'?')).')');$s->execute(array_values($data));$pk=$t==='user'?'user_id':'id';$key=$t==='user'?'nick_name':'name';$r=$query('SELECT * FROM yoshop_'.$t.' WHERE '.$key.'=? AND store_id=?',[$data[$key],$tenant]);$check(count($r)===1&&(int)$r[0][$pk]>0,'Exact own positive fixture');$id=(int)$r[0][$pk];$owned[$t][]=$id;return $id;};
$verifyConfigs=static function(string $phase)use($query,$check,$tenant,$marker,&$sid,&$owned,&$masterIds,&$masterInputs,&$proofs):array{$parents=$query('SELECT * FROM yoshop_athlete_master WHERE store_id=? ORDER BY id',[$tenant]);$pal=$query('SELECT * FROM yoshop_athlete_pal WHERE store_id=? ORDER BY id',[$tenant]);$check(count($parents)===count($masterInputs),'Actual config parent cardinality');$out=[];$all=[];foreach($parents as $i=>$r){$data=$masterInputs[$i];$id=(int)$r['id'];$check($id>0&&$r['create_by']===$marker&&$r['notes']===$data['notes']&&$r['staff_id']===(string)$sid,'Exact own config parent');foreach(['sport_id','start_age','end_age','gender'] as $k)$check((int)$r[$k]===$data[$k],'Original parent integer '.$k);$check($r['sport_event_id']===implode(',',$data['sport_event_id'])&&(int)$r['is_delete']===0,'Original CSV/default flag');$masterIds[$i]=$id;if(!in_array($id,$owned['athlete_master'],true))$owned['athlete_master'][]=$id;$children=[];foreach($pal as $p)if((int)$p['master_id']===$id)$children[]=$p;$check(count($children)===5,'Original five PAL rows');foreach($children as $j=>$p){$check((int)$p['store_id']===$tenant&&$p['staff_id']===(string)$sid&&$p['create_by']===$marker,'Own child staff/store/creator');foreach(['sport_id','start_age','end_age','gender'] as $k)$check((int)$p[$k]===$data[$k],'Mirrored child integer '.$k);$check($p['sport_event_id']===implode(',',$data['sport_event_id'])&&(int)$p['strength']===$data['pal_con'][$j]['strength']&&bcadd((string)$p['pal'],'0',2)===bcadd($data['pal_con'][$j]['pal'],'0',2)&&(int)$p['is_delete']===0,'Original PAL precision/CSV/strength');$cid=(int)$p['id'];$check($cid>0,'Positive PAL PK');if(!in_array($cid,$owned['athlete_pal'],true))$owned['athlete_pal'][]=$cid;$all[]=$cid;}$out[$id]=['parent'=>$r,'children'=>$children];}$check(count($all)===count($pal),'No owned orphan PAL');$proofs[]=['phase'=>$phase,'parents'=>count($parents),'pal_rows'=>count($pal),'all_original_inputs_and_fk_verified'=>true,'child_master_fk_verified_after_commit'=>true];return $out;};
$projectParent=static function(array $r):array{foreach(['id','sport_id','start_age','end_age','gender','store_id','is_delete'] as $k)$r[$k]=(int)$r[$k];foreach(['create_time','update_time'] as $k)$r[$k]=date('Y-m-d H:i:s',strtotime((string)$r[$k]));return $r;};
$configRead=static function(string $name,string $action,array $args=[])use($request,$success,$query,$tenant,$projectParent,$wire,&$sid):void{$c=$request($name,'Config',$action,$args);$success($c);$sports=$query('SELECT id,name FROM yoshop_sport ORDER BY id');$sportNames=[];foreach($sports as $s)$sportNames[(string)$s['id']]=$s['name'];
    if($action==='detail'){$r=$query('SELECT * FROM yoshop_athlete_master WHERE id=? AND store_id=?',[$args['id'],$tenant])[0];$p=$projectParent($r);$p['sport_event_id']=!empty($r['sport_event_id'])?explode(',',$r['sport_event_id']):[];$p['staff_id']=!empty($r['staff_id'])?explode(',',$r['staff_id']):[];$p['sport_name']=$sportNames[(string)$r['sport_id']]??'';$p['sport_event_name']=implode(',',array_map(static function($id)use($sportNames){return $sportNames[(string)$id]??'';},$p['sport_event_id']));$staff=$query('SELECT name FROM yoshop_staff WHERE id=? AND store_id=?',[$sid,$tenant]);$p['staff_names']=$staff[0]['name'];$pla=[];foreach($query('SELECT strength,pal FROM yoshop_athlete_pal WHERE master_id=? AND store_id=? ORDER BY id',[$r['id'],$tenant]) as $v)$pla[]=['strength'=>(int)$v['strength'],'pal'=>bcadd((string)$v['pal'],'0',2)];$p['pla']=$pla;$want=['detail'=>$p];}
    else{$rows=$query('SELECT * FROM yoshop_athlete_master WHERE store_id=? AND sport_id=? ORDER BY id DESC',[$tenant,$args['sport_id']]);$list=[];foreach($rows as $r){$p=$projectParent($r);$p['sport_name']=$sportNames[(string)$r['sport_id']]??'';$keys=!empty($r['sport_event_id'])?explode(',',$r['sport_event_id']):[];$p['sport_event_name']=implode(',',array_map(static function($id)use($sportNames){return $sportNames[(string)$id]??'';},$keys));$list[]=$p;}$want=['list'=>['total'=>count($list),'per_page'=>15,'current_page'=>1,'last_page'=>count($list)?1:0,'data'=>$list]];}$wire($c['body']['data'],$want,$c['scenario']);};
$verifyHealth=static function(string $phase,array $expected)use($query,$check,$tenant,$marker,&$sid,&$owned,&$proofs):array{$r=$query('SELECT * FROM yoshop_health WHERE staff_id=? AND store_id=? ORDER BY id',[$sid,$tenant]);$got=[];foreach($r as $p){$check((int)$p['staff_id']===$sid&&(int)$p['store_id']===$tenant&&$p['create_by']===$marker&&(int)$p['is_delete']===0,'Original own health relationship');$got[]=(int)$p['health'];$id=(int)$p['id'];$check($id>0,'Health positive PK');if(!in_array($id,$owned['health'],true))$owned['health'][]=$id;}sort($got);$want=$expected;sort($want);$check($got===$want,'Actual health set');$proofs[]=['phase'=>$phase,'health_set'=>$got,'rows'=>count($r),'all_original_ownership_verified'=>true];return $r;};
$healthRead=static function(string $name,array $health)use($request,$success,$query,$dm,$wire,&$sid):void{$c=$request($name,'Health','detail',['staff_id'=>$sid]);$success($c);$enum=$query('SELECT enum_key,enum_name FROM yoshop_config_enum WHERE enum_type=5 AND is_delete=0 ORDER BY '.($dm?'"ORDER"':'`order`').' ASC');$out=[];foreach($enum as $e){$e['checked']=in_array($e['enum_key'],$health)?1:0;$out[]=$e;}$wire($c['body']['data'],['detail'=>$out],$c['scenario']);};
try{$sports=$query('SELECT id,pid,name FROM yoshop_sport ORDER BY id');$sport=null;$events=[];foreach($sports as $s)if((int)$s['pid']===0){$children=[];foreach($sports as $e)if((int)$e['pid']===(int)$s['id'])$children[]=(int)$e['id'];if(count($children)>=2){$sport=(int)$s['id'];$events=array_slice($children,0,2);break;}}$check($sport!==null,'Actual Sport parent with two events');$uid=$insert('user',['nick_name'=>$marker.'_USER','store_id'=>$tenant]);$u=$query('SELECT * FROM yoshop_user WHERE user_id=? AND store_id=?',[$uid,$tenant])[0];foreach($u as $k=>$v)if(strpos($k,'balance')!==false||in_array($k,['pay_money','expend_money','points'],true))$check((float)$v===0.0,'Own User money0');$sid=$insert('staff',['name'=>$marker.'_STAFF','user_id'=>$uid,'staff_type'=>2,'sport_id'=>$sport,'sport_event_id'=>$events[0],'gender'=>1,'birthday'=>'1990-01-01','height'=>'170.00','weight'=>'60.00','store_id'=>$tenant,'create_by'=>$marker]);$map=['staff_id'=>$sid,'user_id'=>$uid];$saveMap();}catch(Throwable $e){$errors[]=['branch'=>'fixtures','class'=>get_class($e),'message'=>$e->getMessage()];}
if($sid>0){
try{foreach(['1','2'] as $sex){$c=$request('STAFF_INFO_PC_SEX_'.$sex,'Config','getStaffInfo',['sport_id'=>(string)$sport,'sport_event_id'=>implode(',',$events),'sex'=>$sex]);$success($c);$rows=$query('SELECT id,name,gender,sport_id,sport_event_id FROM yoshop_staff WHERE id=? AND store_id=?',[$sid,$tenant]);foreach($rows as &$r)foreach(['id','gender','sport_id','sport_event_id'] as $k)$r[$k]=(int)$r[$k];unset($r);$wire($c['body']['data'],['list'=>$rows],$c['scenario']);}
    $pal=[];foreach([2=>'1.25',3=>'1.50',4=>'1.75',5=>'2.00',6=>'2.25'] as $strength=>$value)$pal[]=['strength'=>$strength,'pal'=>$value];$data=['sport_id'=>$sport,'sport_event_id'=>$events,'staff_id'=>[$sid],'start_age'=>18,'end_age'=>60,'gender'=>1,'notes'=>$marker."_参数'中文\\记录",'pal_con'=>$pal];
    foreach(['CREATE','REPEAT_CREATE'] as $phase){$c=$request('CONFIG_'.$phase,'Config','setRecord',$data);$success($c);$masterInputs[]=$data;$rows=$verifyConfigs($phase);$cases[count($cases)-1]['original_response_id']=$c['body']['data']['id'];$configRead('CONFIG_DETAIL_'.$phase,'detail',['id'=>end($masterIds)]);$configRead('CONFIG_LIST_'.$phase,'lists',['sport_id'=>$sport,'start_date'=>date('Y-m-d'),'end_date'=>date('Y-m-d')]);}
}catch(Throwable $e){$errors[]=['branch'=>'Config','class'=>get_class($e),'message'=>$e->getMessage()];}
try{$healthRead('HEALTH_INITIAL',[]);$previous=[];
    foreach(['FIRST'=>[1,3],'REPEAT'=>[1,3],'REPLACE'=>[2,5],'EMPTY'=>[],'RETAIN'=>[5]] as $phase=>$health){$beforeRows=$query('SELECT * FROM yoshop_health WHERE staff_id=? AND store_id=? ORDER BY id',[$sid,$tenant]);$c=$request('HEALTH_'.$phase,'Health','setHealth',['staff_id'=>$sid,'health'=>$health]);$success($c);$rows=$verifyHealth($phase,$health);if($phase==='REPEAT')$check($rows===$beforeRows,'Repeated health same original PK/timestamps');if(in_array($phase,['REPLACE','EMPTY'],true))foreach($beforeRows as $old)$check((int)$query('SELECT COUNT(*) n FROM yoshop_health WHERE id=?',[$old['id']])[0]['n']===0,'Actual health difference physical delete old rows');$healthRead('HEALTH_DETAIL_'.$phase,$health);$healthExpected=$health;}
    $beforeBad=$query('SELECT * FROM yoshop_health WHERE staff_id=? AND store_id=? ORDER BY id',[$sid,$tenant]);$c=$request('HEALTH_INVALID_99_REFUSAL','Health','setHealth',['staff_id'=>$sid,'health'=>[99]]);$check($c['http_status']===200&&$c['body']['status']===500&&$c['body']['message']==='健康状态不在枚举范围内','Original health enum refusal');$check($query('SELECT * FROM yoshop_health WHERE staff_id=? AND store_id=? ORDER BY id',[$sid,$tenant])===$beforeBad,'Invalid health wrote nothing');
}catch(Throwable $e){$errors[]=['branch'=>'Health','class'=>get_class($e),'message'=>$e->getMessage()];}}
$cache->delete($token);$tokenGone=$cache->get($token)===null;$cache->clear();$cacheFiles=0;if(is_dir($runtime.'/cache/'))foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($runtime.'/cache/',FilesystemIterator::SKIP_DOTS)) as $f)if($f->isFile())$cacheFiles++;
$after=$snapshot();$private=['lane'=>$lane,'marker'=>$marker,'tenant'=>$tenant,'user_id'=>$uid,'staff_id'=>$sid,'owned_primary_keys'=>$owned,'master_ids'=>$masterIds,'master_inputs'=>$masterInputs,'health_expected'=>$healthExpected,'cases'=>$cases,'responses'=>$responses,'before'=>$before,'after'=>$after,'errors'=>$errors];file_put_contents($runtime.'/private-retention.json',json_encode($private,JSON_PRETTY_PRINT|JSON_PRESERVE_ZERO_FRACTION|JSON_UNESCAPED_UNICODE));chmod($runtime.'/private-retention.json',0600);
$normal=static function($x,string $context='')use(&$normal,$sid,$masterIds){if(!is_array($x))return $x;if(isset($x['path']))$context=strpos($x['path'],'getStaffInfo')!==false?'staff':'master';foreach($x as $k=>&$v){if($k==='id'&&$context==='staff'&&$v===$sid)$v=1;elseif($k==='id'&&$context==='master'&&is_int($v)&&in_array($v,$masterIds,true))$v=array_search($v,$masterIds,true)+1;elseif($k==='staff_id'&&is_string($v)&&$v===(string)$sid)$v='1';elseif($k==='staff_id'&&is_array($v)&&$v===[(string)$sid])$v=['1'];elseif(in_array($k,['create_time','update_time'],true)&&is_string($v)&&preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/D',$v))$v='VERIFIED_OWN_ORIGINAL_TIME';else $v=$normal($v,$context);}unset($v);return $x;};
foreach($cases as &$c){$trace=$c['body']['trace_id']??null;$c['trace_format_valid']=is_string($trace)&&preg_match('/^[0-9a-f]{13}$/D',$trace)===1;if($c['trace_format_valid'])$c['body']['trace_id']='VALID_DYNAMIC_TRACE';if($c['body']['status']===500&&$c['scenario']!=='PILOT_CF_HEALTH_INVALID_99_REFUSAL'){$c['private_unexpected_message_sha256']=hash('sha256',$c['body']['message']);$c['body']['message']='UNEXPECTED_ERROR_RAW_WIRE_PRIVATE';}}unset($c);$events=[];foreach(file($runtime.'/queries.jsonl',FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES)?:[] as $l)$events[]=json_decode($l,true);$audit=[];foreach(file($runtime.'/write-audit.jsonl',FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES)?:[] as $l)$audit[]=json_decode($l,true);$fresh=$connect();$retained=[];foreach($pks as $t=>$pk){$s=$fresh->prepare('SELECT COUNT(*) FROM yoshop_'.$t.' WHERE store_id=?');$s->execute([$tenant]);$retained[$t]=(int)$s->fetchColumn();}
$report=['lane'=>$lane,'cases'=>$normal($cases),'findings'=>$findings,'original_proofs'=>$proofs,'errors'=>$errors,'retention'=>['mode'=>'retained-owned','fresh_counts'=>$retained,'natural_seven_table_sha_unchanged'=>$before===$after,'exact_owned_pks_only'=>true],'resources'=>['token_absent'=>$tokenGone,'cache_files'=>$cacheFiles],'events'=>$events,'write_audit'=>$audit,'loaded_boundary'=>$boundary];file_put_contents($runtime.'/report.json',json_encode($report,JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE));echo json_encode(['lane'=>$lane,'http_cases'=>count($cases),'findings'=>$findings,'errors'=>$errors,'retained'=>$retained,'natural_sha_unchanged'=>$before===$after,'report'=>$runtime.'/report.json']),"\n";exit(count($errors)||$before!==$after||!$tokenGone||$cacheFiles||in_array(false,array_column($audit,'owned_scope_verified'),true)?1:0);
