Files
api/scripts/xlvask-automation-migrate.php
T
Jeppe B 801c8e1f6d feat(api): standalone xlvask-automation-migrate script + runbook section (#357)
Adds `scripts/xlvask-automation-migrate.php` mirroring the existing schema-script pattern (`check` / `apply --yes`), a new AUTOMATION_RUNBOOK §2a documenting both operator entry points, and `XLVaskAutomationMigrateScriptTest` pinning the gate, the WD check, and the bootstrap references.

Production autopilot-runs (POST /modules/xlvask/services/usage/autopilot-runs) was returning 500 with:
```
XL Vask automation schema is not ready. Apply migration 20260804_xlvask_ai_auto_policy_v2 explicitly.
```
because no operator had invoked the gated `applyExplicitMigration()` since PR #348 shipped the migration class. The frontend half of the fix is the companion change in pleno-vue#280 (missing `minimax_integration_enabled` key).

Operator action required once merged:
```
php index.php run xlvask-automation-migrate
# or
php scripts/xlvask-automation-migrate.php apply --yes
```
Both produce identical JSON status; retain the artifact and rerun `check` to confirm postflight is green.

Diff: +140/-0 (3 files). Tests: 87/87 XL Vask unit + 5/5 new migration script test pass.
2026-08-10 08:18:28 +02:00

55 lines
1.8 KiB
PHP
Executable File

#!/usr/bin/env php
<?php
/**
* XL Vask automation schema migration script.
*
* Mirrors the scripts/account-deletion-schema.php and
* scripts/bird-control-plane-schema.php patterns so ops can run an explicit,
* non-cron, non-HTTP migration from the API container.
*
* Usage (from the api repo root, against the configured DB):
* php scripts/xlvask-automation-migrate.php check
* php scripts/xlvask-automation-migrate.php apply --yes
*
* "check" never mutates state and always exits 0 when ready / 1 when not.
* "apply" requires an explicit --yes flag before calling the gated
* migration_20260804_xlvask_ai_auto_policy_v2::apply() entry point, which
* itself is operator-only by design (see AUTOMATION_RUNBOOK §2).
*/
if (PHP_SAPI !== 'cli') {
fwrite(STDERR, "This command is CLI-only.\n");
exit(2);
}
const WD = __DIR__ . '/../services/nginx/app';
require_once WD . '/vendor/autoload.php';
require_once WD . '/config.php';
require_once WD . '/classes/db.php';
require_once WD . '/classes/xlvask_usage_logs_schema_bootstrap.php';
require_once WD . '/modules/xlvask/migrations/20260804_xlvask_ai_auto_policy_v2.php';
$command = $argv[1] ?? 'check';
if (!in_array($command, ['check', 'apply'], true)) {
fwrite(STDERR, "Usage: scripts/xlvask-automation-migrate.php check|apply --yes\n");
exit(2);
}
$db = new \classes\db($CONFIG_DB);
$db->connect();
if ($command === 'apply') {
if (($argv[2] ?? '') !== '--yes') {
fwrite(STDERR, "Refusing schema mutation without: apply --yes\n");
exit(2);
}
$status = \classes\xlvask_usage_logs_schema_bootstrap::applyExplicitMigration();
} else {
$status = \classes\xlvask_usage_logs_schema_bootstrap::migrationStatus();
}
fwrite(STDOUT, json_encode($status, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT) . PHP_EOL);
exit((bool)($status['ready'] ?? false) ? 0 : 1);