fix(sf): guard escalation index migration
This commit is contained in:
parent
62dacb6270
commit
d3574f3c4d
2 changed files with 93 additions and 5 deletions
|
|
@ -374,9 +374,11 @@ function initSchema(db: DbAdapter, fileBacked: boolean): void {
|
|||
)
|
||||
`);
|
||||
|
||||
db.exec(`
|
||||
CREATE INDEX IF NOT EXISTS idx_tasks_escalation_pending ON tasks(milestone_id, slice_id, escalation_pending)
|
||||
`);
|
||||
if (columnExists(db, "tasks", "escalation_pending")) {
|
||||
db.exec(`
|
||||
CREATE INDEX IF NOT EXISTS idx_tasks_escalation_pending ON tasks(milestone_id, slice_id, escalation_pending)
|
||||
`);
|
||||
}
|
||||
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS verification_evidence (
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import assert from "node:assert/strict";
|
|||
import * as fs from "node:fs";
|
||||
import * as os from "node:os";
|
||||
import * as path from "node:path";
|
||||
import { DatabaseSync } from "node:sqlite";
|
||||
import { describe, test } from 'vitest';
|
||||
import {
|
||||
_getAdapter,
|
||||
|
|
@ -83,8 +84,34 @@ describe("sf.db", () => {
|
|||
.get();
|
||||
assert.deepStrictEqual(
|
||||
version?.["version"],
|
||||
21,
|
||||
"schema version should be 21",
|
||||
23,
|
||||
"schema version should be 23",
|
||||
);
|
||||
|
||||
const sliceColumns = adapter
|
||||
.prepare("PRAGMA table_info(slices)")
|
||||
.all()
|
||||
.map((row) => row["name"]);
|
||||
assert.ok(
|
||||
sliceColumns.includes("is_sketch"),
|
||||
"slices table should include progressive-planning is_sketch column",
|
||||
);
|
||||
assert.ok(
|
||||
sliceColumns.includes("sketch_scope"),
|
||||
"slices table should include progressive-planning sketch_scope column",
|
||||
);
|
||||
|
||||
const taskColumns = adapter
|
||||
.prepare("PRAGMA table_info(tasks)")
|
||||
.all()
|
||||
.map((row) => row["name"]);
|
||||
assert.ok(
|
||||
taskColumns.includes("escalation_pending"),
|
||||
"tasks table should include escalation_pending column",
|
||||
);
|
||||
assert.ok(
|
||||
taskColumns.includes("escalation_artifact_path"),
|
||||
"tasks table should include escalation_artifact_path column",
|
||||
);
|
||||
|
||||
// Check tables exist by querying them
|
||||
|
|
@ -153,6 +180,65 @@ describe("sf.db", () => {
|
|||
cleanup(dbPath);
|
||||
});
|
||||
|
||||
test("sf-db: v22 database migrates task escalation columns before index", () => {
|
||||
const dbPath = tempDbPath();
|
||||
const db = new DatabaseSync(dbPath);
|
||||
db.exec(`
|
||||
CREATE TABLE schema_version (version INTEGER NOT NULL, applied_at TEXT NOT NULL);
|
||||
INSERT INTO schema_version VALUES (22, '2026-01-01T00:00:00.000Z');
|
||||
CREATE TABLE milestones (
|
||||
id TEXT PRIMARY KEY,
|
||||
title TEXT NOT NULL DEFAULT '',
|
||||
status TEXT NOT NULL DEFAULT 'active',
|
||||
created_at TEXT NOT NULL,
|
||||
completed_at TEXT DEFAULT NULL
|
||||
);
|
||||
CREATE TABLE slices (
|
||||
milestone_id TEXT NOT NULL,
|
||||
id TEXT NOT NULL,
|
||||
title TEXT NOT NULL DEFAULT '',
|
||||
status TEXT NOT NULL DEFAULT 'pending',
|
||||
risk TEXT NOT NULL DEFAULT 'medium',
|
||||
created_at TEXT NOT NULL DEFAULT '',
|
||||
completed_at TEXT DEFAULT NULL,
|
||||
PRIMARY KEY (milestone_id, id)
|
||||
);
|
||||
CREATE TABLE tasks (
|
||||
milestone_id TEXT NOT NULL,
|
||||
slice_id TEXT NOT NULL,
|
||||
id TEXT NOT NULL,
|
||||
title TEXT NOT NULL DEFAULT '',
|
||||
status TEXT NOT NULL DEFAULT 'pending',
|
||||
PRIMARY KEY (milestone_id, slice_id, id)
|
||||
);
|
||||
`);
|
||||
db.close();
|
||||
|
||||
openDatabase(dbPath);
|
||||
const adapter = _getAdapter()!;
|
||||
const version = adapter
|
||||
.prepare("SELECT MAX(version) as version FROM schema_version")
|
||||
.get();
|
||||
assert.deepStrictEqual(version?.["version"], 23);
|
||||
|
||||
const taskColumns = adapter
|
||||
.prepare("PRAGMA table_info(tasks)")
|
||||
.all()
|
||||
.map((row) => row["name"]);
|
||||
assert.ok(taskColumns.includes("escalation_pending"));
|
||||
assert.ok(taskColumns.includes("escalation_artifact_path"));
|
||||
assert.ok(
|
||||
adapter
|
||||
.prepare(
|
||||
"SELECT 1 as present FROM sqlite_master WHERE type = 'index' AND name = 'idx_tasks_escalation_pending'",
|
||||
)
|
||||
.get(),
|
||||
"escalation index should exist after migration",
|
||||
);
|
||||
|
||||
cleanup(dbPath);
|
||||
});
|
||||
|
||||
test("sf-db: insert + get decision", () => {
|
||||
openDatabase(":memory:");
|
||||
insertDecision({
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue