fix(FN-5105): complete Step 6 — stabilize verification gates

Fusion-Task-Id: FN-5105
Fusion-Task-Lineage: a876d5eb-d828-415e-b6f0-07bbc8713417
This commit is contained in:
Fusion (runfusion.ai)
2026-05-19 05:07:36 -07:00
committed by gsxdsm
parent e4178718ef
commit 7380adc7b6
3 changed files with 18 additions and 32 deletions

View File

@@ -1362,39 +1362,34 @@ export class Database {
const hasTaskTitle = this.hasColumn("tasks", "title");
const hasDeletedAt = this.hasColumn("tasks", "deletedAt");
const insertWhenClause = hasDeletedAt ? "WHEN NEW.deletedAt IS NULL " : "";
this.db.exec(`
CREATE TRIGGER IF NOT EXISTS tasks_fts_ai AFTER INSERT ON tasks
${insertWhenClause}BEGIN
${hasDeletedAt ? "WHEN NEW.deletedAt IS NULL " : ""}BEGIN
INSERT INTO tasks_fts(rowid, id, title, description, comments)
VALUES (new.rowid, new.id, COALESCE(new.title, ''), new.description, COALESCE(new.comments, '[]'));
END
`);
const updateColumns = hasTaskTitle
? hasDeletedAt
? "id, title, description, comments, deletedAt"
: "id, title, description, comments"
: hasDeletedAt
? "id, description, comments, deletedAt"
: "id, description, comments";
? hasDeletedAt ? "id, title, description, comments, deletedAt" : "id, title, description, comments"
: hasDeletedAt ? "id, description, comments, deletedAt" : "id, description, comments";
const oldTitle = hasTaskTitle ? "COALESCE(old.title, '')" : "''";
const newTitle = hasTaskTitle ? "COALESCE(new.title, '')" : "''";
const liveRowPredicate = hasDeletedAt ? "new.deletedAt IS NULL" : "1 = 1";
this.db.exec(`
CREATE TRIGGER IF NOT EXISTS tasks_fts_au AFTER UPDATE OF ${updateColumns} ON tasks BEGIN
INSERT INTO tasks_fts(tasks_fts, rowid, id, title, description, comments)
VALUES('delete', old.rowid, old.id, ${oldTitle}, old.description, COALESCE(old.comments, '[]'));
INSERT INTO tasks_fts(rowid, id, title, description, comments)
SELECT new.rowid, new.id, ${newTitle}, new.description, COALESCE(new.comments, '[]')
WHERE ${liveRowPredicate};
WHERE ${hasDeletedAt ? "new.deletedAt IS NULL" : "1 = 1"};
END
`);
this.db.exec(`
CREATE TRIGGER IF NOT EXISTS tasks_fts_ad AFTER DELETE ON tasks BEGIN
CREATE TRIGGER IF NOT EXISTS tasks_fts_ad AFTER DELETE ON tasks
${hasDeletedAt ? "WHEN OLD.deletedAt IS NULL " : ""}BEGIN
INSERT INTO tasks_fts(tasks_fts, rowid, id, title, description, comments)
VALUES('delete', old.rowid, old.id, COALESCE(old.title, ''), old.description, COALESCE(old.comments, '[]'));
END
@@ -2023,42 +2018,37 @@ export class Database {
// AFTER INSERT trigger - index new tasks
const hasTaskTitle = this.hasColumn("tasks", "title");
const hasDeletedAt = this.hasColumn("tasks", "deletedAt");
const insertWhenClause = hasDeletedAt ? "WHEN NEW.deletedAt IS NULL " : "";
this.db.exec(`
CREATE TRIGGER IF NOT EXISTS tasks_fts_ai AFTER INSERT ON tasks
${insertWhenClause}BEGIN
${hasDeletedAt ? "WHEN NEW.deletedAt IS NULL " : ""}BEGIN
INSERT INTO tasks_fts(rowid, id, title, description, comments)
VALUES (new.rowid, new.id, COALESCE(new.title, ''), new.description, COALESCE(new.comments, '[]'));
END
`);
const updateColumns = hasTaskTitle
? hasDeletedAt
? "id, title, description, comments, deletedAt"
: "id, title, description, comments"
: hasDeletedAt
? "id, description, comments, deletedAt"
: "id, description, comments";
? hasDeletedAt ? "id, title, description, comments, deletedAt" : "id, title, description, comments"
: hasDeletedAt ? "id, description, comments, deletedAt" : "id, description, comments";
const oldTitle = hasTaskTitle ? "COALESCE(old.title, '')" : "''";
const newTitle = hasTaskTitle ? "COALESCE(new.title, '')" : "''";
// AFTER UPDATE trigger - reindex updated tasks (delete old + insert new).
// Restrict this to searchable columns so log/status churn does not bloat
// the FTS index during long-running executor activity.
const liveRowPredicate = hasDeletedAt ? "new.deletedAt IS NULL" : "1 = 1";
this.db.exec(`
CREATE TRIGGER IF NOT EXISTS tasks_fts_au AFTER UPDATE OF ${updateColumns} ON tasks BEGIN
INSERT INTO tasks_fts(tasks_fts, rowid, id, title, description, comments)
VALUES('delete', old.rowid, old.id, ${oldTitle}, old.description, COALESCE(old.comments, '[]'));
INSERT INTO tasks_fts(rowid, id, title, description, comments)
SELECT new.rowid, new.id, ${newTitle}, new.description, COALESCE(new.comments, '[]')
WHERE ${liveRowPredicate};
WHERE ${hasDeletedAt ? "new.deletedAt IS NULL" : "1 = 1"};
END
`);
// AFTER DELETE trigger - remove deleted tasks from index
this.db.exec(`
CREATE TRIGGER IF NOT EXISTS tasks_fts_ad AFTER DELETE ON tasks BEGIN
CREATE TRIGGER IF NOT EXISTS tasks_fts_ad AFTER DELETE ON tasks
${hasDeletedAt ? "WHEN OLD.deletedAt IS NULL " : ""}BEGIN
INSERT INTO tasks_fts(tasks_fts, rowid, id, title, description, comments)
VALUES('delete', old.rowid, old.id, COALESCE(old.title, ''), old.description, COALESCE(old.comments, '[]'));
END
@@ -2488,16 +2478,11 @@ export class Database {
const hasTaskTitle = this.hasColumn("tasks", "title");
const hasDeletedAt = this.hasColumn("tasks", "deletedAt");
const updateColumns = hasTaskTitle
? hasDeletedAt
? "id, title, description, comments, deletedAt"
: "id, title, description, comments"
: hasDeletedAt
? "id, description, comments, deletedAt"
: "id, description, comments";
? hasDeletedAt ? "id, title, description, comments, deletedAt" : "id, title, description, comments"
: hasDeletedAt ? "id, description, comments, deletedAt" : "id, description, comments";
const oldTitle = hasTaskTitle ? "COALESCE(old.title, '')" : "''";
const newTitle = hasTaskTitle ? "COALESCE(new.title, '')" : "''";
const liveRowPredicate = hasDeletedAt ? "new.deletedAt IS NULL" : "1 = 1";
this.db.exec(`
DROP TRIGGER IF EXISTS tasks_fts_au;
CREATE TRIGGER tasks_fts_au AFTER UPDATE OF ${updateColumns} ON tasks BEGIN
@@ -2505,7 +2490,7 @@ export class Database {
VALUES('delete', old.rowid, old.id, ${oldTitle}, old.description, COALESCE(old.comments, '[]'));
INSERT INTO tasks_fts(rowid, id, title, description, comments)
SELECT new.rowid, new.id, ${newTitle}, new.description, COALESCE(new.comments, '[]')
WHERE ${liveRowPredicate};
WHERE ${hasDeletedAt ? "new.deletedAt IS NULL" : "1 = 1"};
END;
`);

View File

@@ -1783,6 +1783,7 @@ export interface Task {
* Set once on first transition to `done`; may be cleared on reopen to
* todo/triage when resume state is not preserved. */
executionCompletedAt?: string;
deletedAt?: string;
createdAt: string;
updatedAt: string;
}