51 lines
2.9 KiB
PHP
51 lines
2.9 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
// Local-only additive schema upgrade. Never prints connection secrets or patient content.
|
|
$root = dirname(__DIR__, 2) . '/server/';
|
|
chdir($root);
|
|
require $root . 'vendor/autoload.php';
|
|
$app = new \think\App($root);
|
|
$app->initialize();
|
|
use think\facade\Db;
|
|
try {
|
|
$connection = (string) config('database.default');
|
|
$cfg = (array) config('database.connections.' . $connection);
|
|
if (!in_array((string) ($cfg['hostname'] ?? ''), ['127.0.0.1', 'localhost', '::1'], true)
|
|
|| ($cfg['prefix'] ?? '') !== 'zyt_') {
|
|
throw new RuntimeException('Local database/prefix guard rejected');
|
|
}
|
|
$active = Db::name('prescription_ai_task')->whereIn('status', ['queued', 'running', 'retry_wait'])->count()
|
|
+ Db::name('prescription_ai_batch')->where('validity', 'current')->whereIn('status', ['preparing', 'waiting_sources', 'queued', 'running', 'retry_wait'])->count();
|
|
if ($active > 0) { throw new RuntimeException('Tasks must finish before this local upgrade'); }
|
|
$snapshot = static function (): array {
|
|
return [
|
|
'batches' => Db::name('prescription_ai_batch')->count(),
|
|
'results' => Db::name('prescription_ai_result')->count(),
|
|
'attempts' => Db::name('prescription_ai_attempt')->count(),
|
|
'tasks_hash' => hash('sha256', json_encode(Db::name('prescription_ai_task')->field('id,status,attempts,total_attempts,manual_retries,result_id')->order('id')->select()->toArray())),
|
|
];
|
|
};
|
|
$before = $snapshot();
|
|
$present = isset(Db::name('prescription_ai_task')->getFields()['progress_json']);
|
|
$sqlFile = $root . 'database/migrations/2026_09_10_prescription_ai_progress.sql';
|
|
$result = ['time' => date('c'), 'local_database' => true, 'column_previously_present' => $present,
|
|
'migration_sha256' => hash_file('sha256', $sqlFile), 'applied' => false];
|
|
if (in_array('--apply', $argv, true)) {
|
|
Db::execute('SET SESSION lock_wait_timeout = 5');
|
|
foreach (explode(';', preg_replace('/^--.*$/m', '', file_get_contents($sqlFile))) as $statement) {
|
|
if (trim($statement) !== '') { Db::execute($statement); }
|
|
}
|
|
$columns = Db::query("SHOW COLUMNS FROM `zyt_prescription_ai_task` LIKE 'progress_json'");
|
|
if (count($columns) !== 1 || $columns[0]['Type'] !== 'varchar(2048)' || $columns[0]['Null'] !== 'YES') {
|
|
throw new RuntimeException('Unexpected progress column definition');
|
|
}
|
|
$result['applied'] = true;
|
|
$result['business_state_unchanged'] = $before === $snapshot();
|
|
if (!$result['business_state_unchanged']) { throw new RuntimeException('Business task state changed during upgrade'); }
|
|
}
|
|
echo json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE), PHP_EOL;
|
|
} catch (Throwable $e) {
|
|
echo json_encode(['error' => get_class($e), 'code' => $e->getCode()]), PHP_EOL;
|
|
exit(1);
|
|
}
|