diff --git a/server/src/__tests__/issues-service.test.ts b/server/src/__tests__/issues-service.test.ts index ef328416d01..150625c3d0f 100644 --- a/server/src/__tests__/issues-service.test.ts +++ b/server/src/__tests__/issues-service.test.ts @@ -773,6 +773,8 @@ describeEmbeddedPostgres("issueService.list participantAgentId", () => { const normalIssueId = randomUUID(); const pluginVisibleIssueId = randomUUID(); const operationIssueId = randomUUID(); + const typedOperationIssueId = randomUUID(); + const legacyContentMachineOperationIssueId = randomUUID(); await db.insert(companies).values({ id: companyId, @@ -826,12 +828,36 @@ describeEmbeddedPostgres("issueService.list participantAgentId", () => { originKind: "plugin:paperclip.missions:operation", originId: "mission-alpha:operation-1", }, + { + id: typedOperationIssueId, + companyId, + projectId, + title: "Typed plugin operation issue", + status: "todo", + priority: "medium", + assigneeAgentId: agentId, + originKind: "plugin:paperclip.missions:operation:evaluation", + originId: "mission-alpha:operation-2", + }, + { + id: legacyContentMachineOperationIssueId, + companyId, + projectId, + title: "Legacy Content Machine operation issue", + status: "todo", + priority: "medium", + assigneeAgentId: agentId, + originKind: "plugin:paperclipai.content-machine:evaluation", + originId: "content-machine-operation-1", + }, ]); const defaultIssueIds = (await svc.list(companyId)).map((issue) => issue.id); expect(defaultIssueIds).toContain(normalIssueId); expect(defaultIssueIds).toContain(pluginVisibleIssueId); expect(defaultIssueIds).not.toContain(operationIssueId); + expect(defaultIssueIds).not.toContain(typedOperationIssueId); + expect(defaultIssueIds).not.toContain(legacyContentMachineOperationIssueId); const inboxIssueIds = (await svc.list(companyId, { assigneeAgentId: agentId, @@ -840,17 +866,28 @@ describeEmbeddedPostgres("issueService.list participantAgentId", () => { })).map((issue) => issue.id); expect(inboxIssueIds).toContain(normalIssueId); expect(inboxIssueIds).not.toContain(operationIssueId); + expect(inboxIssueIds).not.toContain(typedOperationIssueId); + expect(inboxIssueIds).not.toContain(legacyContentMachineOperationIssueId); await expect(svc.list(companyId, { originKind: "plugin:paperclip.missions:operation" })) .resolves.toEqual([expect.objectContaining({ id: operationIssueId })]); await expect(svc.list(companyId, { originId: "mission-alpha:operation-1" })) .resolves.toEqual([expect.objectContaining({ id: operationIssueId })]); + await expect(svc.list(companyId, { originKindPrefix: "plugin:paperclip.missions:operation" })) + .resolves.toEqual(expect.arrayContaining([ + expect.objectContaining({ id: operationIssueId }), + expect.objectContaining({ id: typedOperationIssueId }), + ])); const projectIssueIds = (await svc.list(companyId, { projectId })).map((issue) => issue.id); expect(projectIssueIds).toContain(operationIssueId); + expect(projectIssueIds).toContain(typedOperationIssueId); + expect(projectIssueIds).toContain(legacyContentMachineOperationIssueId); const advancedIssueIds = (await svc.list(companyId, { includePluginOperations: true })).map((issue) => issue.id); expect(advancedIssueIds).toContain(operationIssueId); + expect(advancedIssueIds).toContain(typedOperationIssueId); + expect(advancedIssueIds).toContain(legacyContentMachineOperationIssueId); }); it("excludes plugin operation issues from unread inbox counts", async () => { diff --git a/server/src/services/issues.ts b/server/src/services/issues.ts index 0ab88d3eebc..a61d7f2b892 100644 --- a/server/src/services/issues.ts +++ b/server/src/services/issues.ts @@ -683,14 +683,25 @@ function inboxVisibleForUserCondition(companyId: string, userId: string) { `; } +const LEGACY_PLUGIN_OPERATION_ORIGIN_KINDS = [ + "plugin:paperclipai.content-machine:case", + "plugin:paperclipai.content-machine:evaluation", + "plugin:paperclipai.content-machine:source-sync", +] as const; + function nonPluginOperationIssueCondition() { - return sql`NOT (${issues.originKind} LIKE 'plugin:%:operation' OR ${issues.originKind} LIKE 'plugin:%:operation:%')`; + return sql`NOT ( + ${issues.originKind} LIKE 'plugin:%:operation' + OR ${issues.originKind} LIKE 'plugin:%:operation:%' + OR ${inArray(issues.originKind, LEGACY_PLUGIN_OPERATION_ORIGIN_KINDS)} + )`; } function shouldIncludePluginOperationIssues(filters: IssueFilters | undefined) { return Boolean( filters?.includePluginOperations || filters?.originKind || + filters?.originKindPrefix || filters?.originId || filters?.projectId, );