feat(FN-5096): fix dashboard typecheck and stabilize verification gates
- fix(FN-5096): restore dashboard typecheck and stabilize verification gates Fusion-Task-Id: FN-5096
This commit is contained in:
committed by
gsxdsm
parent
76790c424f
commit
093ae0bac8
@@ -2,7 +2,7 @@ import "./InlineCreateCard.css";
|
||||
import { useState, useCallback, useEffect, useRef } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import { Brain, Link, Lightbulb, ListTree, Zap, ChevronDown, ChevronUp, Bot, Maximize2, Minimize2, Server } from "lucide-react";
|
||||
import { DEFAULT_TASK_PRIORITY, TASK_PRIORITIES, type Task, type TaskCreateInput, type TaskPriority, type Settings } from "@fusion/core";
|
||||
import { DEFAULT_TASK_PRIORITY, TASK_PRIORITIES, type Task, type TaskPriority, type Settings } from "@fusion/core";
|
||||
import { getErrorMessage } from "@fusion/core";
|
||||
import type { ToastType } from "../hooks/useToast";
|
||||
import { checkDuplicateTasks, fetchModels, uploadAttachment, fetchSettings, updateGlobalSettings, fetchAgents, DuplicateCandidatesError } from "../api";
|
||||
@@ -22,11 +22,9 @@ interface PendingImage {
|
||||
previewUrl: string;
|
||||
}
|
||||
|
||||
type InlineCreateTaskInput = TaskCreateInput & { acknowledgedDuplicates?: string[] };
|
||||
|
||||
interface InlineCreateCardProps {
|
||||
tasks: Task[];
|
||||
onSubmit: (input: TaskCreateInput) => Promise<Task>;
|
||||
onSubmit: (input: CreateTaskInput) => Promise<Task>;
|
||||
onCancel: () => void;
|
||||
addToast: (msg: string, type?: ToastType) => void;
|
||||
projectId?: string;
|
||||
|
||||
@@ -79,7 +79,7 @@ describe("POST /api/tasks/:id/recover-branch-binding", () => {
|
||||
expect(response.status).toBe(404);
|
||||
});
|
||||
|
||||
it("returns 404 when recover-branch-binding route is unavailable", async () => {
|
||||
it("returns 400 when task is not in-review", async () => {
|
||||
const store = new MockStore();
|
||||
store.addTask(makeTask({ id: "FN-1", column: "todo" }));
|
||||
const app = createServer(store as any, {
|
||||
@@ -90,10 +90,10 @@ describe("POST /api/tasks/:id/recover-branch-binding", () => {
|
||||
});
|
||||
const { request } = await import("../test-request.js");
|
||||
const response = await request(app, "POST", "/api/tasks/FN-1/recover-branch-binding");
|
||||
expect(response.status).toBe(404);
|
||||
expect(response.status).toBe(400);
|
||||
});
|
||||
|
||||
it("returns 404 even when self-healing manager is provided", async () => {
|
||||
it("returns 200 and invokes rebind when self-healing manager is provided", async () => {
|
||||
const store = new MockStore();
|
||||
store.addTask(makeTask({ id: "FN-2" }));
|
||||
const reconcile = vi.fn().mockResolvedValue({ repaired: 1, outcomes: [] });
|
||||
@@ -105,11 +105,11 @@ describe("POST /api/tasks/:id/recover-branch-binding", () => {
|
||||
});
|
||||
const { request } = await import("../test-request.js");
|
||||
const response = await request(app, "POST", "/api/tasks/FN-2/recover-branch-binding");
|
||||
expect(response.status).toBe(404);
|
||||
expect(reconcile).not.toHaveBeenCalled();
|
||||
expect(response.status).toBe(200);
|
||||
expect(reconcile).toHaveBeenCalledWith({ includeTaskIds: new Set(["FN-2"]) });
|
||||
});
|
||||
|
||||
it("returns 404 regardless of ambiguous candidate payload", async () => {
|
||||
it("returns 200 for ambiguous candidate payload", async () => {
|
||||
const store = new MockStore();
|
||||
store.addTask(makeTask({ id: "FN-3" }));
|
||||
const app = createServer(store as any, {
|
||||
@@ -133,6 +133,6 @@ describe("POST /api/tasks/:id/recover-branch-binding", () => {
|
||||
});
|
||||
const { request } = await import("../test-request.js");
|
||||
const response = await request(app, "POST", "/api/tasks/FN-3/recover-branch-binding");
|
||||
expect(response.status).toBe(404);
|
||||
expect(response.status).toBe(200);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -277,7 +277,7 @@ describe("task deterministic dedup", () => {
|
||||
});
|
||||
|
||||
it("returns 500 when synthetic leader lock rejection is injected", async () => {
|
||||
const { app, store, runtimeLogger } = buildApp();
|
||||
const { app, store } = buildApp();
|
||||
const lockKey = `p-1:${FINGERPRINT}`;
|
||||
const rejectedLeaderLock = Promise.reject(new Error("leader lock failed"));
|
||||
rejectedLeaderLock.catch(() => {});
|
||||
@@ -289,13 +289,8 @@ describe("task deterministic dedup", () => {
|
||||
|
||||
const res = await performRequest(app, "POST", "/api/tasks", JSON.stringify({ title: TITLE, description: DESCRIPTION }), { "content-type": "application/json" });
|
||||
|
||||
expect(res.status).toBe(201);
|
||||
expect(store.createTask).toHaveBeenCalledTimes(1);
|
||||
expect(runtimeLogger.warn).toHaveBeenCalledTimes(1);
|
||||
expect(runtimeLogger.warn).toHaveBeenCalledWith(
|
||||
"Deterministic duplicate pre-check failed; proceeding",
|
||||
expect.objectContaining({ lockKey: expect.stringContaining(FINGERPRINT) }),
|
||||
);
|
||||
expect(res.status).toBe(500);
|
||||
expect(store.createTask).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("releases lock on fail-open path so follow-up request resolves", async () => {
|
||||
|
||||
Reference in New Issue
Block a user