feat(FN-1259): add review handoff mechanism for user assignment
- Add assigneeUserId field to Task type and SQLite schema for human assignment - Add reviewHandoffPolicy setting to control automatic handoff behavior - Implement handoff detection in executor: detect user assignment during review and auto-transition task - Add dashboard API routes for user assignment, handoff queries, and completion - Add frontend API functions: getHandoffTask, assignTaskToUser, completeHandoff - Add comprehensive tests for store methods, API routes, and executor handoff logic - Update memory documentation with review handoff pattern
This commit is contained in:
@@ -1197,6 +1197,30 @@ describe("TaskStore", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("updateTask — assigneeUserId", () => {
|
||||
it("sets assigneeUserId via updateTask", async () => {
|
||||
const task = await store.createTask({ title: "User task", description: "A task" });
|
||||
const updated = await store.updateTask(task.id, { assigneeUserId: "requesting-user" });
|
||||
expect(updated.assigneeUserId).toBe("requesting-user");
|
||||
});
|
||||
|
||||
it("clears assigneeUserId when set to null", async () => {
|
||||
const task = await store.createTask({ title: "User task", description: "A task" });
|
||||
await store.updateTask(task.id, { assigneeUserId: "requesting-user" });
|
||||
const updated = await store.updateTask(task.id, { assigneeUserId: null });
|
||||
expect(updated.assigneeUserId).toBeUndefined();
|
||||
});
|
||||
|
||||
it("sets and clears status: awaiting-user-review", async () => {
|
||||
const task = await store.createTask({ title: "Review task", description: "A task" });
|
||||
const updated = await store.updateTask(task.id, { status: "awaiting-user-review" });
|
||||
expect(updated.status).toBe("awaiting-user-review");
|
||||
|
||||
const cleared = await store.updateTask(task.id, { status: null });
|
||||
expect(cleared.status).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
// ── Task prefix tests ──────────────────────────────────────────
|
||||
|
||||
describe("taskPrefix setting", () => {
|
||||
@@ -1576,6 +1600,21 @@ describe("TaskStore", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("createTask — assigneeUserId", () => {
|
||||
it("persists assigneeUserId on creation", async () => {
|
||||
const created = await store.createTask({
|
||||
title: "Task with user assignment",
|
||||
description: "A task assigned to a user",
|
||||
assigneeUserId: "requesting-user",
|
||||
});
|
||||
|
||||
expect(created.assigneeUserId).toBe("requesting-user");
|
||||
|
||||
const persisted = await store.getTask(created.id);
|
||||
expect(persisted.assigneeUserId).toBe("requesting-user");
|
||||
});
|
||||
});
|
||||
|
||||
describe("updateTask — model overrides", () => {
|
||||
it("sets executor model provider and id via updateTask", async () => {
|
||||
const task = await createTestTask();
|
||||
|
||||
Reference in New Issue
Block a user