diff --git a/server/src/__tests__/board-chat-route-feature-flag.test.ts b/server/src/__tests__/board-chat-route-feature-flag.test.ts index 2a6c18c6bd8..521a526d5de 100644 --- a/server/src/__tests__/board-chat-route-feature-flag.test.ts +++ b/server/src/__tests__/board-chat-route-feature-flag.test.ts @@ -194,6 +194,8 @@ describe("board-chat client disconnect", () => { description: "Standing issue for board concierge conversations and decision log", originKind: "manual", status: "todo", + assigneeAgentId: null, + assigneeUserId: null, }, ]); mockIssueService.update.mockResolvedValue({ id: "issue-legacy", originKind: "board_chat" }); @@ -232,6 +234,64 @@ describe("board-chat client disconnect", () => { req.abort(); await pending; }); + + it("does not repair or anchor assigned manual issues that only look like legacy board chat issues", async () => { + mockGetExperimental.mockResolvedValue({ enableConferenceRoomChat: true }); + mockIssueService.list + .mockResolvedValueOnce([]) + .mockResolvedValueOnce([ + { + id: "issue-agent-assigned-manual", + title: "Board Operations", + description: "Standing issue for board concierge conversations and decision log", + originKind: "manual", + status: "todo", + assigneeAgentId: "agent-1", + assigneeUserId: null, + }, + { + id: "issue-user-assigned-manual", + title: "Board Operations", + description: "Standing issue for board concierge conversations and decision log", + originKind: "manual", + status: "todo", + assigneeAgentId: null, + assigneeUserId: "user-2", + }, + ]); + mockIssueService.create.mockResolvedValue({ id: "issue-new" }); + mockIssueService.addComment.mockResolvedValue({ id: "comment-1" }); + mockIssueService.listComments.mockResolvedValue([]); + const fakeProc = makeFakeProc(); + mockSpawn.mockReturnValue(fakeProc); + const app = await createApp(); + + const req = request(app) + .post("/api/board/chat/stream") + .set("Content-Type", "application/json") + .send(JSON.stringify({ companyId: "company-1", message: "hello" })); + const pending = req.then( + () => undefined, + () => undefined, + ); + + await vi.waitFor(() => expect(mockSpawn).toHaveBeenCalled()); + fakeProc.exitCode = 0; + fakeProc.emit("close", 0); + + expect(mockIssueService.update).not.toHaveBeenCalled(); + expect(mockIssueService.create).toHaveBeenCalledWith("company-1", expect.objectContaining({ + title: "hello", + originKind: "board_chat", + })); + expect(mockIssueService.addComment).toHaveBeenCalledWith( + "issue-new", + "hello", + expect.any(Object), + ); + req.abort(); + await pending; + }); }); describe("board-chat history role classification", () => { diff --git a/server/src/routes/board-chat.ts b/server/src/routes/board-chat.ts index 87fe709f95b..6e5247e927d 100644 --- a/server/src/routes/board-chat.ts +++ b/server/src/routes/board-chat.ts @@ -81,11 +81,15 @@ function isLegacyBoardChatIssue(issue: { description?: string | null; originKind?: string | null; status?: string | null; + assigneeAgentId?: string | null; + assigneeUserId?: string | null; }) { return ( issue.title === LEGACY_BOARD_CHAT_TITLE && issue.description === BOARD_CHAT_DESCRIPTION && (issue.originKind === undefined || issue.originKind === null || issue.originKind === "manual") && + issue.assigneeAgentId === null && + issue.assigneeUserId === null && isOpenBoardChatIssue(issue) ); }