<?php
$schemaDir=__DIR__.'/schema-api-evidence';$phase=json_decode(file_get_contents($schemaDir.'/phase.json'),true);$auth=json_decode(file_get_contents(__DIR__.'/private-request.json'),true);$path=parse_url($_SERVER['REQUEST_URI'],PHP_URL_PATH);
if(!$phase||$_SERVER['REQUEST_METHOD']!=='POST'||($_SERVER['HTTP_TOKEN']??'')!==$auth['token']||($_SERVER['HTTP_X_CDX_CRUD']??'')!==$phase['nonce']||$path!==$phase['path']){http_response_code(403);exit;}
$actual=$_POST;$expected=$phase['params'];ksort($actual);ksort($expected);if($actual!==$expected||file_exists($schemaDir.'/'.$phase['label'].'.wire.json')){http_response_code(403);exit;}
foreach(json_decode(file_get_contents($schemaDir.'/source-lock.json'),true)as $file=>$sha)if(hash_file('sha256',__DIR__.'/source/application/'.$file)!==$sha){http_response_code(403);exit;}
require __DIR__.'/schema-api-common.php';$lease=$slease();$before=$schemaSource();$sguard($before,$lease);$beforeClock=$sclock();$GLOBALS['CDX_PREPARED']=[];$GLOBALS['CDX_ALLOWED']=$phase['allowed'];ob_start();
register_shutdown_function(static function()use($schemaSource,$sguard,$ssave,$slease,$before,$beforeClock,$sclock,$phase,$marker,&$schemaReads,&$schemaQueries){
 try{
  $body=(string)ob_get_contents();$after=$schemaSource();$lease=$slease();
  foreach($after['material_category']as $row)if(strpos($row['name'],$marker.'-')===0&&!in_array((string)$row['id'],array_map('strval',array_column($lease,'id')),true))$lease[]=$row;
  $sguard($after,$lease);$ssave('lease.json',$lease);$afterClock=$sclock();
  $prepared=$GLOBALS['CDX_PREPARED'];$reads=$schemaReads+count(array_filter($prepared,static function($entry){return preg_match('/^\s*(SELECT|SHOW|EXPLAIN|CALL)\b/i',$entry['queryString']);}));
  $ssave($phase['label'].'.wire.json',['label'=>$phase['label'],'path'=>$phase['path'],'params'=>$phase['params'],'HTTP'=>http_response_code(),'body'=>$body,'body_sha256'=>hash('sha256',$body),'source_before'=>$before,'source_after'=>$after,'clock_before'=>$beforeClock,'clock_after'=>$afterClock,'prepared_SQL'=>$prepared,'readonly_SQL'=>$schemaQueries,'SELECT'=>$reads,'remaining_allowances'=>$GLOBALS['CDX_ALLOWED'],'last_error'=>error_get_last()]);
 }catch(Throwable $e){$ssave($phase['label'].'.audit-error.json',['class'=>get_class($e),'message'=>$e->getMessage()]);}
});
$_SERVER['PATH_INFO']=$path;require __DIR__.'/crud-init.php';\think\App::run()->send();
