<?php
declare(strict_types=1);
date_default_timezone_set('Asia/Shanghai');$lane=(string)getenv('CATEGORY_LANE');$runtime=(string)getenv('CATEGORY_RUNTIME');$base=(string)getenv('CATEGORY_BASE');$dm=getenv('POC_DIALECT')==='dm';$root=(string)getenv('CATEGORY_ROOT');
$check=static function(bool $ok,string $why):void{if(!$ok)throw new RuntimeException($why);};$check(in_array($lane,['B','C'],true)&&preg_match('#^http://127\.0\.0\.1:1832[12]$#D',$base)===1,'Private loopback lane');
$connect=static function()use($dm):PDO{try{return new PDO($dm?'dm:host=127.0.0.1;port=5238;schema=AIZHCT_APP':'mysql:host='.getenv('POC_AI_HOST').';port='.getenv('POC_AI_PORT').';dbname='.getenv('POC_AI_SCHEMA').';charset=utf8',getenv('POC_AI_USER'),getenv('POC_AI_PASSWORD'),[PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION,PDO::ATTR_CASE=>PDO::CASE_LOWER]);}catch(Throwable $e){throw new RuntimeException('Express private identity connection failed');}};
$db=$connect();if($dm)$check($db->query("SELECT SYS_CONTEXT('USERENV','CURRENT_SCHEMA') FROM DUAL")->fetchColumn()==='AIZHCT_APP','DM identity');else $check(strpos((string)$db->query('SELECT VERSION()')->fetchColumn(),'5.6.')===0&&$db->query('SELECT DATABASE()')->fetchColumn()===getenv('POC_AI_SCHEMA'),'Code local MySQL5.6');
$query=static function(string $sql,array $args=[])use($db):array{$s=$db->prepare($sql);$s->execute($args);$rows=$s->fetchAll(PDO::FETCH_ASSOC);foreach($rows as &$row)foreach($row as &$v)if(is_resource($v))$v=stream_get_contents($v);unset($row,$v);return $rows;};
$marker='CDXEX10E1F5';$tenants=['store'=>2147001121,'terminal'=>2147001122];$owned=[];
$gate=json_decode((string)file_get_contents(__DIR__.'/structure-'.$lane.'.json'),true);$check(($gate['lane']??'')===$lane&&$gate['business_dml']===0&&$gate['foreign_keys']===0&&$gate['triggers']===0,'Live FK/trigger gate');
$cols=array_map('strtolower',array_column($gate['metadata']['express']['columns'],'column_name'));$expected=['express_id','express_name','kuaidi100_code','kdniao_code','sort','store_id','create_time','update_time'];sort($cols);sort($expected);$check($cols===$expected,'Exact express schema');$orderCols=array_map('strtolower',array_column($gate['metadata']['order']['columns'],'column_name'));$check(in_array('store_id',$orderCols,true),'Order store scope');$deleteReferenceSupported=in_array('express_id',$orderCols,true);
foreach($gate['metadata']['express']['columns'] as $c)if(in_array(strtolower($c['column_name']),['create_time','update_time'],true))$check(in_array(strtolower($c['data_type']),['int','integer','bigint'],true)&&(int)($dm?$c['data_scale']:$c['numeric_scale'])===0,'Express timestamps are physical Unix integer seconds');
$snapshot=static function()use($connect,$dm,&$owned):array{$scan=$connect();if(!$dm)$scan->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY,false);$s=$scan->query('SELECT * FROM yoshop_express ORDER BY express_id');$h=hash_init('sha256');$n=0;$excluded=0;while($r=$s->fetch(PDO::FETCH_ASSOC)){if(isset($owned[(string)$r['express_id']])){$excluded++;continue;}foreach($r as &$v)if(is_resource($v))$v=stream_get_contents($v);unset($v);hash_update($h,serialize($r));$n++;}$s->closeCursor();return ['natural_rows'=>$n,'sha256'=>hash_final($h)];};
$hashes=['store_model_sha'=>'26d2e540317d083f36c3344c2118598c113d53c172fdb6d5684792a3f23598d9','terminal_model_sha'=>'87b2fce74858c239618153160938bc7ae05eafb15fe7915b080c8a8755dbbcd0','common_model_sha'=>'33317c902e97b49d603c3a16a1db8eba33c1d24de2e353f1ac47044eb9761de0','base_model_sha'=>'15b09472d9152906bd3f6cfa6b98ea87b1952abcc9587e7e72526fff73ab78c6'];
$boundary=json_decode((string)file_get_contents($base.'/__poc_boundary'),true);foreach($hashes as $key=>$want)$check(($boundary[$key]??'')===$want,'Actual pre-write source SHA '.$key);$check($boundary['external_stubs']===true&&$boundary['private_cache']===true&&$boundary['all_external_calls_forbidden']===true,'Actual private boundary');
