From 3eebded9e1c8ea48326fbf7277c3757bea59b345 Mon Sep 17 00:00:00 2001 From: "Hugo P.Brito" Date: Thu, 16 Jul 2026 14:08:04 +0100 Subject: [PATCH] fix(ui): shorten Jira dispatch polling rounds --- ui/actions/integrations/jira-dispatch.test.ts | 47 +++++++++++++++++++ ui/actions/integrations/jira-dispatch.ts | 28 +++++++++-- ui/types/integrations.ts | 4 ++ 3 files changed, 75 insertions(+), 4 deletions(-) diff --git a/ui/actions/integrations/jira-dispatch.test.ts b/ui/actions/integrations/jira-dispatch.test.ts index 14afb1e602..56c19b8fe6 100644 --- a/ui/actions/integrations/jira-dispatch.test.ts +++ b/ui/actions/integrations/jira-dispatch.test.ts @@ -139,4 +139,51 @@ describe("sendJiraDispatch", () => { message: "Finding successfully sent to Jira!", }); }); + + it("should succeed completed task polling with grouped created and updated issue result shape", async () => { + // Given + pollTaskUntilSettledMock.mockResolvedValue({ + ok: true, + state: "completed", + result: { + created_count: 1, + updated_count: 1, + failed_count: 0, + created_issues: [{ key: "SEC-1" }], + updated_issues: [{ key: "SEC-2" }], + failed_groups: [], + }, + }); + + // When + const result = await pollJiraDispatchTask("task-1"); + + // Then + expect(pollTaskUntilSettledMock).toHaveBeenCalledWith("task-1", { + maxAttempts: 5, + delayMs: 2000, + }); + expect(result).toEqual({ + success: true, + message: "Finding successfully sent to Jira!", + }); + }); + + it("should fail completed task polling when Jira dispatch completed as a no-op", async () => { + // Given + pollTaskUntilSettledMock.mockResolvedValue({ + ok: true, + state: "completed", + result: { created_count: 0, updated_count: 0, failed_count: 0 }, + }); + + // When + const result = await pollJiraDispatchTask("task-1"); + + // Then + expect(result).toEqual({ + success: false, + error: "Jira dispatch completed but did not create or update any issues.", + }); + }); }); diff --git a/ui/actions/integrations/jira-dispatch.ts b/ui/actions/integrations/jira-dispatch.ts index 0729c4e335..41df32e492 100644 --- a/ui/actions/integrations/jira-dispatch.ts +++ b/ui/actions/integrations/jira-dispatch.ts @@ -32,15 +32,27 @@ interface JiraDispatchInput { dispatchMode?: JiraDispatchMode; } -const getArrayFailureCount = (value: unknown[] | undefined) => +const getArrayCount = (value: unknown[] | undefined) => Array.isArray(value) ? value.length : 0; const getJiraDispatchFailedCount = (result: JiraTaskResult | undefined) => { if (!result) return 0; return Math.max( result.failed_count ?? 0, - getArrayFailureCount(result.failed_groups), - getArrayFailureCount(result.failed_batches), + getArrayCount(result.failed_groups), + getArrayCount(result.failed_batches), + ); +}; + +const getJiraDispatchSuccessCount = (result: JiraTaskResult | undefined) => { + if (!result) return 0; + return Math.max( + result.successful_count ?? 0, + result.created_count ?? 0, + result.updated_count ?? 0, + getArrayCount(result.created_issues), + getArrayCount(result.updated_issues), + result.issue_key || result.issue_url ? 1 : 0, ); }; @@ -217,7 +229,7 @@ export const pollJiraDispatchTask = async ( { success: true; message: string } | { success: false; error: string } > => { const res = await pollTaskUntilSettled(taskId, { - maxAttempts: 30, + maxAttempts: 5, delayMs: 2000, }); if (!res.ok) { @@ -242,6 +254,14 @@ export const pollJiraDispatchTask = async ( }; } + if (jiraResult && getJiraDispatchSuccessCount(jiraResult) === 0) { + return { + success: false, + error: + "Jira dispatch completed but did not create or update any issues.", + }; + } + return { success: true, message: "Finding successfully sent to Jira!" }; } diff --git a/ui/types/integrations.ts b/ui/types/integrations.ts index fc458ec037..6a08ba2ffd 100644 --- a/ui/types/integrations.ts +++ b/ui/types/integrations.ts @@ -71,8 +71,12 @@ export interface JiraDispatchResponse { success?: boolean; error?: string; message?: string; + successful_count?: number; created_count?: number; + updated_count?: number; failed_count?: number; + created_issues?: unknown[]; + updated_issues?: unknown[]; failed_groups?: unknown[]; failed_batches?: unknown[]; issue_url?: string;