fix: resequence existing workbench trace migration
This commit is contained in:
@@ -314,6 +314,37 @@ test("apply mode records ledger and verifies durable runtime readiness", async (
|
||||
assert.equal(JSON.stringify(report).includes("redacted@example.invalid"), false);
|
||||
});
|
||||
|
||||
test("apply mode reports sanitized migration diagnostics", async () => {
|
||||
const migrationApplyError = new Error("duplicate key blocked postgresql://hwlab:secret-password@db.example.test:5432/hwlab");
|
||||
migrationApplyError.code = "23505";
|
||||
migrationApplyError.constraint = "idx_workbench_trace_events_trace_source_event";
|
||||
migrationApplyError.table = "workbench_trace_events";
|
||||
migrationApplyError.detail = "Key (trace_id, source_event_id)=(trc_1, password=secret) already exists.";
|
||||
const queryClient = createFakeQueryClient({ migrationReady: false, migrationApplyError });
|
||||
|
||||
const report = await buildDevRuntimeMigrationReport(
|
||||
parseArgs(["--apply", "--confirm-dev", "--confirmed-non-production"]),
|
||||
{
|
||||
env: {
|
||||
HWLAB_CLOUD_DB_URL: "postgresql://hwlab:redacted@example.invalid:5432/hwlab",
|
||||
HWLAB_CLOUD_DB_SSL_MODE: "disable"
|
||||
},
|
||||
queryClient,
|
||||
now: () => "2026-05-22T00:00:00.000Z"
|
||||
}
|
||||
);
|
||||
|
||||
assert.equal(report.conclusion.status, "blocked");
|
||||
assert.equal(report.actions.migrationApplied, false);
|
||||
assert.equal(report.blockers[0].evidence.errorCode, "23505");
|
||||
assert.equal(report.blockers[0].evidence.errorConstraint, "idx_workbench_trace_events_trace_source_event");
|
||||
assert.equal(report.blockers[0].evidence.errorTable, "workbench_trace_events");
|
||||
assert.match(report.blockers[0].evidence.errorMessage, /\[redacted-postgres-url\]/u);
|
||||
assert.match(report.blockers[0].evidence.errorDetail, /password=\[redacted\]/u);
|
||||
assert.equal(JSON.stringify(report.blockers[0].evidence).includes("secret-password"), false);
|
||||
assert.ok(queryClient.calls.some((call) => call.sql === "ROLLBACK"));
|
||||
});
|
||||
|
||||
test("live dry-run closes pg pool after readiness verification", async () => {
|
||||
const backingClient = createFakeQueryClient({ migrationReady: true });
|
||||
const pools = [];
|
||||
@@ -388,7 +419,7 @@ test("apply mode uses a dedicated pg client transaction", async () => {
|
||||
assert.ok(pools[1].calls.some((call) => call.type === "end"));
|
||||
});
|
||||
|
||||
function createFakeQueryClient({ migrationReady, countErrorCode = null }) {
|
||||
function createFakeQueryClient({ migrationReady, countErrorCode = null, migrationApplyError = null }) {
|
||||
const state = {
|
||||
migrationReady,
|
||||
calls: []
|
||||
@@ -402,6 +433,9 @@ function createFakeQueryClient({ migrationReady, countErrorCode = null }) {
|
||||
if (sql === "BEGIN" || sql === "COMMIT" || sql === "ROLLBACK") {
|
||||
return { rows: [] };
|
||||
}
|
||||
if (migrationApplyError && sql.includes("CREATE TABLE IF NOT EXISTS projects")) {
|
||||
throw migrationApplyError;
|
||||
}
|
||||
if (sql.includes("INSERT INTO hwlab_schema_migrations")) {
|
||||
state.migrationReady = true;
|
||||
return { rows: [] };
|
||||
|
||||
Reference in New Issue
Block a user