diff --git a/server/src/__tests__/issues-service.test.ts b/server/src/__tests__/issues-service.test.ts index 68fe6338ef0..052ccb97ae4 100644 --- a/server/src/__tests__/issues-service.test.ts +++ b/server/src/__tests__/issues-service.test.ts @@ -3456,6 +3456,7 @@ describeEmbeddedPostgres("accepted plan decomposition", () => { actorAgentId: assigneeAgentId, }); + expect(first.decomposition).not.toHaveProperty("requestedChildren"); expect(first.childIssueIds).toHaveLength(2); expect(first.newlyCreatedIssues).toHaveLength(2); expect(first.decomposition.status).toBe("completed"); diff --git a/server/src/services/issues.ts b/server/src/services/issues.ts index adf1c9c36bd..2f1f2dc44f6 100644 --- a/server/src/services/issues.ts +++ b/server/src/services/issues.ts @@ -32,6 +32,7 @@ import { projects, } from "@paperclipai/db"; import type { + AcceptedPlanDecomposition, IssueCommentAuthorType, IssueCommentMetadata, IssueCommentPresentation, @@ -288,6 +289,28 @@ type IssueLastActivityStat = { latestCommentAt: Date | null; latestLogAt: Date | null; }; + +function serializeAcceptedPlanDecomposition( + decomposition: IssuePlanDecompositionRow, +): AcceptedPlanDecomposition { + return { + id: decomposition.id, + companyId: decomposition.companyId, + sourceIssueId: decomposition.sourceIssueId, + acceptedPlanRevisionId: decomposition.acceptedPlanRevisionId, + acceptedInteractionId: decomposition.acceptedInteractionId, + status: decomposition.status as AcceptedPlanDecomposition["status"], + requestFingerprint: decomposition.requestFingerprint, + requestedChildCount: decomposition.requestedChildCount, + childIssueIds: normalizeIssuePlanDecompositionChildIds(decomposition.childIssueIds), + ownerAgentId: decomposition.ownerAgentId, + ownerUserId: decomposition.ownerUserId, + ownerRunId: decomposition.ownerRunId, + completedAt: decomposition.completedAt, + createdAt: decomposition.createdAt, + updatedAt: decomposition.updatedAt, + }; +} type IssueUserContextInput = { createdByUserId: string | null; assigneeUserId: string | null; @@ -4356,9 +4379,11 @@ export function issueService(db: Db) { .map((childIssueId) => childIssueMap.get(childIssueId)) .filter((row): row is typeof issues.$inferSelect => Boolean(row)); + const decomposition = serializeAcceptedPlanDecomposition(currentClaim); + return { - decomposition: currentClaim, - childIssueIds, + decomposition, + childIssueIds: decomposition.childIssueIds, childIssues: orderedChildIssues, newlyCreatedIssues, }; @@ -4414,24 +4439,10 @@ export function issueService(db: Db) { const childIssueMap = new Map(childIssueRows.map((row) => [row.id, row])); return rows.map((row) => { - const decomposition = row.decomposition; - const childIds = normalizeIssuePlanDecompositionChildIds(decomposition.childIssueIds); + const decomposition = serializeAcceptedPlanDecomposition(row.decomposition); + const childIds = decomposition.childIssueIds; return { - id: decomposition.id, - companyId: decomposition.companyId, - sourceIssueId: decomposition.sourceIssueId, - acceptedPlanRevisionId: decomposition.acceptedPlanRevisionId, - acceptedInteractionId: decomposition.acceptedInteractionId, - status: decomposition.status, - requestFingerprint: decomposition.requestFingerprint, - requestedChildCount: decomposition.requestedChildCount, - childIssueIds: childIds, - ownerAgentId: decomposition.ownerAgentId, - ownerUserId: decomposition.ownerUserId, - ownerRunId: decomposition.ownerRunId, - completedAt: decomposition.completedAt, - createdAt: decomposition.createdAt, - updatedAt: decomposition.updatedAt, + ...decomposition, acceptedPlanRevisionNumber: row.revisionNumber ?? null, childIssues: childIds .map((childId) => childIssueMap.get(childId) ?? null) diff --git a/ui/src/components/IssuePlanDecompositionsSection.tsx b/ui/src/components/IssuePlanDecompositionsSection.tsx index 9ba29a10540..dd17d19a4d2 100644 --- a/ui/src/components/IssuePlanDecompositionsSection.tsx +++ b/ui/src/components/IssuePlanDecompositionsSection.tsx @@ -55,7 +55,7 @@ export function IssuePlanDecompositionsSection({