diff --git a/generated/kysely/types.ts b/generated/kysely/types.ts index 358479117..36e951501 100644 --- a/generated/kysely/types.ts +++ b/generated/kysely/types.ts @@ -95,6 +95,8 @@ export type ExternalTask = { ownerEmail: string; ownerName: string; ownerId: string; + resolution: string | null; + resolutionId: string | null; createdAt: Generated; updatedAt: Generated; }; diff --git a/prisma/migrations/20240923113428_append_resolution_fields_for_task_model/migration.sql b/prisma/migrations/20240923113428_append_resolution_fields_for_task_model/migration.sql new file mode 100644 index 000000000..e64b73c2a --- /dev/null +++ b/prisma/migrations/20240923113428_append_resolution_fields_for_task_model/migration.sql @@ -0,0 +1,3 @@ +-- AlterTable +ALTER TABLE "ExternalTask" ADD COLUMN "resolution" TEXT, +ADD COLUMN "resolutionId" TEXT; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index de80eaf18..c1f988247 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -442,6 +442,8 @@ model ExternalTask { ownerEmail String ownerName String ownerId String + resolution String? + resolutionId String? criteria GoalAchieveCriteria[] @relation("taskToCriteria") createdAt DateTime @default(dbgenerated("timezone('utc'::text, now())")) @db.Timestamp() diff --git a/src/utils/db/calculatedGoalsFields.ts b/src/utils/db/calculatedGoalsFields.ts index a2290671d..c6ac1bf93 100644 --- a/src/utils/db/calculatedGoalsFields.ts +++ b/src/utils/db/calculatedGoalsFields.ts @@ -114,7 +114,11 @@ export const calculateGoalCriteria = (list: Array) => { } if (externalTask) { - const isFinishedStatus = jiraService.checkStatusIsFinished(externalTask.stateCategoryId); + const isFinishedStatus = jiraService.checkCompletedStatus({ + statusCategory: externalTask.stateCategoryId, + statusName: externalTask.state, + resolutionName: externalTask.resolution, + }); return { ...baseCriteria, diff --git a/src/utils/integration/jira.ts b/src/utils/integration/jira.ts index a2cfc6b1a..eef380278 100644 --- a/src/utils/integration/jira.ts +++ b/src/utils/integration/jira.ts @@ -64,6 +64,12 @@ export interface JiraPriority { name: string; id: string; } +export interface JiraResolution { + self: string; + id: string; + description: string; + name: string; +} export interface JiraIssue { id: string; @@ -78,6 +84,7 @@ export interface JiraIssue { project: JiraProject; priority: JiraProject; issuetype: JiraIssueType; + resolution?: JiraResolution; } interface JiraServiceConfig { @@ -86,6 +93,7 @@ interface JiraServiceConfig { password: string; apiVersion: string; positiveStatusNames: string; + positiveResolutionNames: string; finishedCategory: JiraIssueStatus['statusCategory'] | null; mapStatusKey: Record; mapStatusIdToColor: Record; @@ -153,9 +161,25 @@ const initJiraClient = () => { return false; } + function checkCompletedStatus(data: { + statusName: string; + statusCategory: number; + resolutionName?: string | null; + }) { + if (config.finishedCategory?.id === data.statusCategory) { + return ( + config.positiveStatusNames.includes(data.statusName) && + Boolean(data.resolutionName && config.positiveResolutionNames.includes(data.resolutionName)) + ); + } + + return false; + } + return { instance, checkStatusIsFinished, + checkCompletedStatus, get positiveStatuses() { return config.positiveStatusNames; }, diff --git a/trpc/queries/external.ts b/trpc/queries/external.ts index 62218bff2..f82d01532 100644 --- a/trpc/queries/external.ts +++ b/trpc/queries/external.ts @@ -27,7 +27,16 @@ export const getOrCreateExternalTask = async ({ id }: { id: string }) => { const [externalIssue] = await searchIssue({ value: id, limit: 1 }); - const { summary: title, id: externalId, key, issuetype, status: state, project, reporter } = externalIssue; + const { + summary: title, + id: externalId, + key, + issuetype, + status: state, + project, + reporter, + resolution, + } = externalIssue; return insertExternalTask({ title, @@ -47,5 +56,7 @@ export const getOrCreateExternalTask = async ({ id }: { id: string }) => { ownerName: reporter.displayName, ownerEmail: reporter.emailAddress, ownerId: reporter.key, + resolution: resolution?.name ?? null, + resolutionId: resolution?.id ?? null, }).executeTakeFirstOrThrow(); }; diff --git a/trpc/router/goal.ts b/trpc/router/goal.ts index 05b9a8c39..15917893a 100644 --- a/trpc/router/goal.ts +++ b/trpc/router/goal.ts @@ -1117,9 +1117,13 @@ export const goal = router({ }); if (externalTask) { - isDoneByConnect = jiraService.checkStatusIsFinished( - (await searchIssue({ value: externalTask.externalKey, limit: 1 }))[0].status, - ); + const issue = (await searchIssue({ value: externalTask.externalKey, limit: 1 }))[0]; + + isDoneByConnect = jiraService.checkCompletedStatus({ + statusCategory: issue.status.statusCategory.id, + statusName: issue.status.name, + resolutionName: issue.resolution?.name, + }); criteriaTitle = externalTask?.title; } } diff --git a/trpc/router/jira.ts b/trpc/router/jira.ts index ee41ba4ab..818f6a4d9 100644 --- a/trpc/router/jira.ts +++ b/trpc/router/jira.ts @@ -26,6 +26,8 @@ const jiraIssueToExternalTask = ( ownerEmail: issue.reporter.emailAddress, ownerId: issue.reporter.key, ownerName: issue.reporter.displayName || issue.reporter.name, + resolution: issue.resolution?.name ?? null, + resolutionId: issue.resolution?.id ?? null, }; };