feat(FN-4899): complete Step 2 — support source metadata patches

Fusion-Task-Id: FN-4899
Fusion-Task-Lineage: 2ae24667-6635-4268-a620-d6012266d8f2
This commit is contained in:
Fusion (runfusion.ai)
2026-05-17 15:52:29 -07:00
committed by gsxdsm
parent 4b01e8e66e
commit 9eb10fca7e
2 changed files with 99 additions and 0 deletions

View File

@@ -0,0 +1,91 @@
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import { TaskStore } from "../store.js";
import { createTaskStoreTestHarness } from "./store-test-helpers.js";
describe("TaskStore.updateTask sourceMetadataPatch", () => {
const harness = createTaskStoreTestHarness();
beforeEach(harness.beforeEach);
afterEach(harness.afterEach);
it("adds metadata when none exists", async () => {
const task = await harness.store().createTask({ description: "Patch metadata" });
await harness.store().updateTask(task.id, {
sourceMetadataPatch: { duplicateOfTaskIds: ["FN-1"] },
});
const detail = await harness.store().getTask(task.id);
expect(detail.sourceMetadata).toEqual({ duplicateOfTaskIds: ["FN-1"] });
});
it("preserves unrelated keys and overwrites shallowly", async () => {
const task = await harness.store().createTask({
description: "Existing metadata",
source: {
sourceType: "chat_session",
sourceMetadata: {
acknowledgedDuplicateIds: ["FN-8"],
nested: { before: true },
},
},
});
await harness.store().updateTask(task.id, {
sourceMetadataPatch: {
duplicateOfTaskIds: ["FN-2"],
nested: { after: true },
},
});
const detail = await harness.store().getTask(task.id);
expect(detail.sourceMetadata).toEqual({
acknowledgedDuplicateIds: ["FN-8"],
duplicateOfTaskIds: ["FN-2"],
nested: { after: true },
});
});
it("clears metadata when sourceMetadataPatch is null", async () => {
const task = await harness.store().createTask({
description: "Clear metadata",
source: {
sourceType: "chat_session",
sourceMetadata: { duplicateOfTaskIds: ["FN-3"] },
},
});
await harness.store().updateTask(task.id, { sourceMetadataPatch: null });
const detail = await harness.store().getTask(task.id);
expect(detail.sourceMetadata).toBeUndefined();
});
it("persists patched metadata across sqlite reopen", async () => {
harness.store().close();
const store = new TaskStore(harness.rootDir(), harness.globalDir());
await store.init();
try {
const task = await store.createTask({ description: "Persist metadata patch" });
await store.updateTask(task.id, {
sourceMetadataPatch: { duplicateOfTaskIds: ["FN-4", "FN-5"] },
});
store.close();
const reopened = new TaskStore(harness.rootDir(), harness.globalDir());
await reopened.init();
try {
const detail = await reopened.getTask(task.id);
expect(detail.sourceMetadata).toEqual({ duplicateOfTaskIds: ["FN-4", "FN-5"] });
} finally {
reopened.close();
}
} finally {
store.close();
}
});
});

View File

@@ -4510,6 +4510,14 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
}
}
if (updates.description !== undefined) task.description = updates.description;
if (updates.sourceMetadataPatch === null) {
task.sourceMetadata = undefined;
} else if (updates.sourceMetadataPatch !== undefined) {
task.sourceMetadata = {
...(task.sourceMetadata ?? {}),
...updates.sourceMetadataPatch,
};
}
if (updates.priority === null) {
task.priority = normalizeTaskPriority(undefined);
} else if (updates.priority !== undefined) {