feat(FN-996): add in-review to todo retry transition with UI and state cleanup
- Add valid board transitions from todo to in-review and in-review to todo (retry) - Clear transient fields (agentId, worktree, branch, prInfo, mergeRetries, etc.) on in-review→todo transition - Add Retry button to TaskDetailModal for in-review tasks - Add tests for retry transition and transient field cleanup in store
This commit is contained in:
@@ -79,7 +79,7 @@ describe("board", () => {
|
||||
});
|
||||
|
||||
it("returns correct transitions for in-review", () => {
|
||||
expect(getValidTransitions("in-review")).toEqual(["done", "in-progress"]);
|
||||
expect(getValidTransitions("in-review")).toEqual(["done", "in-progress", "todo"]);
|
||||
});
|
||||
|
||||
it("returns correct transitions for done", () => {
|
||||
|
||||
@@ -2775,6 +2775,33 @@ Task with acceptance criteria
|
||||
expect(reopened.blockedBy).toBeUndefined();
|
||||
expect(reopened.workflowStepResults).toBeUndefined();
|
||||
});
|
||||
|
||||
it("allows retrying in-review tasks back to todo and clears transient fields", async () => {
|
||||
const task = await store.createTask({ description: "test retry in-review task to todo" });
|
||||
await store.moveTask(task.id, "todo");
|
||||
await store.moveTask(task.id, "in-progress");
|
||||
await store.moveTask(task.id, "in-review");
|
||||
await store.updateTask(task.id, {
|
||||
status: "completed",
|
||||
error: "stale error",
|
||||
worktree: "stale-worktree",
|
||||
blockedBy: "FN-456",
|
||||
workflowStepResults: [{
|
||||
workflowStepId: "wf-1",
|
||||
workflowStepName: "Workflow step 1",
|
||||
status: "passed",
|
||||
startedAt: new Date().toISOString(),
|
||||
}],
|
||||
});
|
||||
|
||||
const retried = await store.moveTask(task.id, "todo");
|
||||
expect(retried.column).toBe("todo");
|
||||
expect(retried.status).toBeUndefined();
|
||||
expect(retried.error).toBeUndefined();
|
||||
expect(retried.worktree).toBeUndefined();
|
||||
expect(retried.blockedBy).toBeUndefined();
|
||||
expect(retried.workflowStepResults).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("columnMovedAt", () => {
|
||||
|
||||
@@ -980,7 +980,7 @@ export class TaskStore extends EventEmitter<TaskStoreEvents> {
|
||||
// preserved here — the recovery-policy module manages those fields. They are
|
||||
// only cleared on terminal transitions (in-review, done, archived).
|
||||
if (
|
||||
(fromColumn === "in-progress" || fromColumn === "done")
|
||||
(fromColumn === "in-progress" || fromColumn === "done" || fromColumn === "in-review")
|
||||
&& (toColumn === "todo" || toColumn === "triage")
|
||||
) {
|
||||
task.status = undefined;
|
||||
|
||||
@@ -1119,7 +1119,7 @@ export const VALID_TRANSITIONS: Record<Column, Column[]> = {
|
||||
triage: ["todo"],
|
||||
todo: ["in-progress", "triage"],
|
||||
"in-progress": ["in-review", "todo", "triage"],
|
||||
"in-review": ["done", "in-progress"],
|
||||
"in-review": ["done", "in-progress", "todo"],
|
||||
done: ["todo", "triage", "archived"],
|
||||
archived: ["done"],
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user