From 01f5fd4d08deb73da4c2880cc276142917ed59bf Mon Sep 17 00:00:00 2001 From: Dotta Date: Thu, 30 Apr 2026 11:29:24 -0500 Subject: [PATCH] Fix PR review findings for workflow costs --- server/src/services/costs.ts | 12 +++++++----- ui/src/components/IssueRunLedger.tsx | 4 +++- ui/src/components/NewIssueDialog.test.tsx | 4 +++- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/server/src/services/costs.ts b/server/src/services/costs.ts index 3cdb88a1b5a..5f4d5fa3c15 100644 --- a/server/src/services/costs.ts +++ b/server/src/services/costs.ts @@ -1,4 +1,5 @@ import { and, desc, eq, gte, isNotNull, isNull, lt, lte, sql } from "drizzle-orm"; +import { alias } from "drizzle-orm/pg-core"; import type { Db } from "@paperclipai/db"; import { activityLog, agents, companies, costEvents, issues, projects } from "@paperclipai/db"; import { notFound, unprocessable } from "../errors.js"; @@ -135,6 +136,7 @@ export function costService(db: Db, budgetHooks: BudgetServiceHooks = {}) { }, issueTreeSummary: async (companyId: string, issueId: string) => { + const childIssues = alias(issues, "child"); const issueTreeCondition = sql` ${issues.id} IN ( WITH RECURSIVE issue_tree(id) AS ( @@ -144,11 +146,11 @@ export function costService(db: Db, budgetHooks: BudgetServiceHooks = {}) { AND ${issues.id} = ${issueId} AND ${issues.hiddenAt} IS NULL UNION - SELECT child.id - FROM ${issues} child - JOIN issue_tree ON child.parent_id = issue_tree.id - WHERE child.company_id = ${companyId} - AND child.hidden_at IS NULL + SELECT ${childIssues.id} + FROM ${issues} ${childIssues} + JOIN issue_tree ON ${childIssues.parentId} = issue_tree.id + WHERE ${childIssues.companyId} = ${companyId} + AND ${childIssues.hiddenAt} IS NULL ) SELECT id FROM issue_tree ) diff --git a/ui/src/components/IssueRunLedger.tsx b/ui/src/components/IssueRunLedger.tsx index 9a28e389c25..17a197d1611 100644 --- a/ui/src/components/IssueRunLedger.tsx +++ b/ui/src/components/IssueRunLedger.tsx @@ -475,7 +475,9 @@ export function IssueRunLedgerContent({ items.push({ kind: "activity", id: event.id, - timestamp: String(event.createdAt), + timestamp: event.createdAt instanceof Date + ? event.createdAt.toISOString() + : String(event.createdAt), event, }); } diff --git a/ui/src/components/NewIssueDialog.test.tsx b/ui/src/components/NewIssueDialog.test.tsx index f938af87e53..151ce9c7e63 100644 --- a/ui/src/components/NewIssueDialog.test.tsx +++ b/ui/src/components/NewIssueDialog.test.tsx @@ -404,7 +404,9 @@ describe("NewIssueDialog", () => { const submitButton = Array.from(container.querySelectorAll("button")) .find((button) => button.textContent?.includes("Create Issue")); expect(submitButton).not.toBeUndefined(); - expect(submitButton?.hasAttribute("disabled")).toBe(false); + await vi.waitFor(() => { + expect(submitButton?.hasAttribute("disabled")).toBe(false); + }); await act(async () => { submitButton!.dispatchEvent(new MouseEvent("click", { bubbles: true }));