fix(schema): guard migration 28 indexes behind tableExists
Migration 28 (add_snapshot_hot_path_indexes) referenced task_comments,
documents, meetings, sprints, agent_messages, activity — all tables
created by ensureOptionalColumns() which runs AFTER runMigrations() on
a fresh DB. Converted from sql-string migration to fn-based so each
index is gated by tableExists(); safe on both fresh and migrated DBs.
Also updated tests/unit/selective-ipc.test.ts exhaustive switch to
include the 7 new DesktopEvent variants added in ef90a58.
This commit is contained in:
1 parent
bb52477e1b
commit
aba3ccd275
2 files changed
+36
-11
No files matched your search
+22
-11
@@ -409,17 +409,28 @@ export function runMigrations(
|
||||
},
|
||||
{
|
||||
version: 28, name: "add_snapshot_hot_path_indexes",
|
||||
sql: `CREATE INDEX IF NOT EXISTS idx_tasks_company_created_at ON tasks(company_id, created_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_tasks_company_updated_at ON tasks(company_id, updated_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_approvals_company_created_at ON approvals(company_id, created_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_task_comments_company_created_at ON task_comments(company_id, created_at);
|
||||
CREATE INDEX IF NOT EXISTS idx_documents_company_updated_at ON documents(company_id, updated_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_meetings_company_scheduled_at ON meetings(company_id, scheduled_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_sprints_company_start_date ON sprints(company_id, start_date DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_runs_agent_created_at ON runs(agent_id, created_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_cost_entries_agent_created_at ON cost_entries(agent_id, created_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_activity_company_actor_action ON activity(company_id, actor, action);
|
||||
CREATE INDEX IF NOT EXISTS idx_tasks_company_assignee_status ON tasks(company_id, assignee_agent_id, status)`,
|
||||
fn: () => {
|
||||
// Some tables (task_comments / documents / meetings / sprints / agent_messages)
|
||||
// are created by ensureOptionalColumns, which runs AFTER runMigrations on
|
||||
// a fresh DB. Guard each CREATE INDEX with a tableExists check so the
|
||||
// migration is safe on both fresh and migrated databases.
|
||||
const indexPlan: Array<{ table: string; sql: string }> = [
|
||||
{ table: "tasks", sql: "CREATE INDEX IF NOT EXISTS idx_tasks_company_created_at ON tasks(company_id, created_at DESC)" },
|
||||
{ table: "tasks", sql: "CREATE INDEX IF NOT EXISTS idx_tasks_company_updated_at ON tasks(company_id, updated_at DESC)" },
|
||||
{ table: "approvals", sql: "CREATE INDEX IF NOT EXISTS idx_approvals_company_created_at ON approvals(company_id, created_at DESC)" },
|
||||
{ table: "task_comments", sql: "CREATE INDEX IF NOT EXISTS idx_task_comments_company_created_at ON task_comments(company_id, created_at)" },
|
||||
{ table: "documents", sql: "CREATE INDEX IF NOT EXISTS idx_documents_company_updated_at ON documents(company_id, updated_at DESC)" },
|
||||
{ table: "meetings", sql: "CREATE INDEX IF NOT EXISTS idx_meetings_company_scheduled_at ON meetings(company_id, scheduled_at DESC)" },
|
||||
{ table: "sprints", sql: "CREATE INDEX IF NOT EXISTS idx_sprints_company_start_date ON sprints(company_id, start_date DESC)" },
|
||||
{ table: "runs", sql: "CREATE INDEX IF NOT EXISTS idx_runs_agent_created_at ON runs(agent_id, created_at DESC)" },
|
||||
{ table: "cost_entries", sql: "CREATE INDEX IF NOT EXISTS idx_cost_entries_agent_created_at ON cost_entries(agent_id, created_at DESC)" },
|
||||
{ table: "activity", sql: "CREATE INDEX IF NOT EXISTS idx_activity_company_actor_action ON activity(company_id, actor, action)" },
|
||||
{ table: "tasks", sql: "CREATE INDEX IF NOT EXISTS idx_tasks_company_assignee_status ON tasks(company_id, assignee_agent_id, status)" },
|
||||
];
|
||||
for (const { table, sql } of indexPlan) {
|
||||
if (tableExists(db, table)) db.exec(sql);
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
version: 29, name: "add_run_events_seq_unique_index",
|
||||
|
||||
@@ -110,6 +110,20 @@ describe("selective IPC event types", () => {
|
||||
return "thread-wait-state-updated";
|
||||
case "recovery-needed":
|
||||
return "recovery-needed";
|
||||
case "oauth:status":
|
||||
return "oauth:status";
|
||||
case "oauth:auth-url":
|
||||
return "oauth:auth-url";
|
||||
case "oauth:progress":
|
||||
return "oauth:progress";
|
||||
case "oauth:prompt-request":
|
||||
return "oauth:prompt-request";
|
||||
case "oauth:manual-code-request":
|
||||
return "oauth:manual-code-request";
|
||||
case "credentials-changed":
|
||||
return "credentials-changed";
|
||||
case "agent-event":
|
||||
return "agent-event";
|
||||
default: {
|
||||
const _exhaustive: never = event;
|
||||
return _exhaustive;
|
||||
|
||||
Reference in new issue
Block a user