<?php
/** 默认预览；--apply 才执行。新增可空列，历史成绩保持原值。 */
function newcomerReceiptMigration($prefix,$query) {
    if(!preg_match('/^[a-zA-Z0-9_]+$/D',$prefix))throw new RuntimeException('Invalid prefix');
    $table=$prefix.'member_newcomer_score';$sql=[];
    $columns=$query("SHOW COLUMNS FROM `$table`");$fields=array_column($columns,'Field');
    foreach($columns as $column)if($column['Field']==='score' && preg_match('/^(?:tiny|small|medium)?int\b/i',$column['Type'])){
        $nullable=$column['Null']==='YES'?' NULL':' NOT NULL';$default='';
        if($column['Default']!==null){if(!is_numeric($column['Default']))throw new RuntimeException('Unexpected score default');$default=' DEFAULT '.(float)$column['Default'];}
        elseif($column['Null']==='YES')$default=' DEFAULT NULL';
        $sql[]="ALTER TABLE `$table` MODIFY score DECIMAL(12,1)".$nullable.$default;
    }
    if(!in_array('submission_key',$fields,true))$sql[]="ALTER TABLE `$table` ADD submission_key CHAR(32) CHARACTER SET ascii COLLATE ascii_bin NULL";
    if(!in_array('submission_result',$fields,true))$sql[]="ALTER TABLE `$table` ADD submission_result MEDIUMTEXT NULL";
    $indexes=$query("SHOW INDEX FROM `$table`");$valid=false;
    foreach($indexes as $index)if($index['Key_name']==='newcomer_submission' && (int)$index['Non_unique']===0 && $index['Column_name']==='submission_key')$valid=true;
    if(!$valid)$sql[]="ALTER TABLE `$table` ADD UNIQUE KEY newcomer_submission (submission_key)";
    return $sql;
}
if(PHP_SAPI!=='cli'||realpath($_SERVER['SCRIPT_FILENAME'])!==__FILE__)return;
$root=$argv[1]??'D:/phpstudy_pro/WWW/cqoms.com';require $root.'/vendor/autoload.php';
$app=new \think\App($root.'/');$app->initialize();
$name=config('database.default');$prefix=config('database.connections.'.$name.'.prefix');
$before=\think\facade\Db::query("SELECT COUNT(*) n,SUM(COALESCE(score,0)) total,SUM(score IS NULL) nulls FROM `{$prefix}member_newcomer_score`")[0];
$sql=newcomerReceiptMigration($prefix,function($statement){return \think\facade\Db::query($statement);});
foreach($sql as $statement){echo $statement.";\n";if(in_array('--apply',$argv,true))\think\facade\Db::execute($statement);}
if(in_array('--apply',$argv,true)){
    $after=\think\facade\Db::query("SELECT COUNT(*) n,SUM(COALESCE(score,0)) total,SUM(score IS NULL) nulls FROM `{$prefix}member_newcomer_score`")[0];
    if((int)$before['n']!==(int)$after['n']||(float)$before['total']!==(float)$after['total']||(int)$before['nulls']!==(int)$after['nulls'])throw new RuntimeException('Historical score validation mismatch');
    // 只清除此表字段缓存，避免旧字段清单拒绝新回执列。
    $cache=config('database.connections.'.$name.'.schema_cache_path');
    foreach(glob(rtrim($cache,'/\\').'/*'.$prefix.'member_newcomer_score*.php')?:[] as $file)unlink($file);
}
echo in_array('--apply',$argv,true)?"APPLIED: nullable receipt columns; historical records unchanged\n":"PREVIEW ONLY\n";
