mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-11 05:11:49 +01:00
Address Greptile review feedback for decomposition PR
This commit is contained in:
1 parent
32dbcc1da4
commit
ac4dee8579
8 files changed
+174
-3
No files matched your search
@@ -23,4 +23,5 @@ ALTER TABLE "issue_plan_decompositions" ADD CONSTRAINT "issue_plan_decomposition
|
||||
ALTER TABLE "issue_plan_decompositions" ADD CONSTRAINT "issue_plan_decompositions_owner_agent_id_agents_id_fk" FOREIGN KEY ("owner_agent_id") REFERENCES "public"."agents"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "issue_plan_decompositions" ADD CONSTRAINT "issue_plan_decompositions_owner_run_id_heartbeat_runs_id_fk" FOREIGN KEY ("owner_run_id") REFERENCES "public"."heartbeat_runs"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX "issue_plan_decompositions_company_source_status_idx" ON "issue_plan_decompositions" USING btree ("company_id","source_issue_id","status");--> statement-breakpoint
|
||||
CREATE INDEX "issue_plan_decompositions_active_owner_idx" ON "issue_plan_decompositions" USING btree ("company_id","owner_agent_id") WHERE "issue_plan_decompositions"."status" = 'in_flight';--> statement-breakpoint
|
||||
CREATE UNIQUE INDEX "issue_plan_decompositions_source_revision_uq" ON "issue_plan_decompositions" USING btree ("company_id","source_issue_id","accepted_plan_revision_id");
|
||||
@@ -10302,6 +10302,28 @@
|
||||
"method": "btree",
|
||||
"with": {}
|
||||
},
|
||||
"issue_plan_decompositions_active_owner_idx": {
|
||||
"name": "issue_plan_decompositions_active_owner_idx",
|
||||
"columns": [
|
||||
{
|
||||
"expression": "company_id",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
},
|
||||
{
|
||||
"expression": "owner_agent_id",
|
||||
"isExpression": false,
|
||||
"asc": true,
|
||||
"nulls": "last"
|
||||
}
|
||||
],
|
||||
"isUnique": false,
|
||||
"concurrently": false,
|
||||
"method": "btree",
|
||||
"where": "\"issue_plan_decompositions\".\"status\" = 'in_flight'",
|
||||
"with": {}
|
||||
},
|
||||
"issue_plan_decompositions_source_revision_uq": {
|
||||
"name": "issue_plan_decompositions_source_revision_uq",
|
||||
"columns": [
|
||||
@@ -18349,4 +18371,4 @@
|
||||
"schemas": {},
|
||||
"tables": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,9 @@ export const issuePlanDecompositions = pgTable(
|
||||
table.sourceIssueId,
|
||||
table.status,
|
||||
),
|
||||
activeOwnerIdx: index("issue_plan_decompositions_active_owner_idx")
|
||||
.on(table.companyId, table.ownerAgentId)
|
||||
.where(sql`${table.status} = 'in_flight'`),
|
||||
sourceRevisionUq: uniqueIndex("issue_plan_decompositions_source_revision_uq").on(
|
||||
table.companyId,
|
||||
table.sourceIssueId,
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 5.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.1 KiB |
@@ -3740,6 +3740,7 @@ describeEmbeddedPostgres("accepted plan decomposition", () => {
|
||||
expect(record?.childIssues.map((child) => child.id).sort()).toEqual(
|
||||
[...result.childIssueIds].sort(),
|
||||
);
|
||||
expect(record).not.toHaveProperty("requestedChildren");
|
||||
expect(record?.childIssues.every((child) => typeof child.title === "string")).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -4414,9 +4414,24 @@ export function issueService(db: Db) {
|
||||
const childIssueMap = new Map(childIssueRows.map((row) => [row.id, row]));
|
||||
|
||||
return rows.map((row) => {
|
||||
const childIds = normalizeIssuePlanDecompositionChildIds(row.decomposition.childIssueIds);
|
||||
const decomposition = row.decomposition;
|
||||
const childIds = normalizeIssuePlanDecompositionChildIds(decomposition.childIssueIds);
|
||||
return {
|
||||
...row.decomposition,
|
||||
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,
|
||||
acceptedPlanRevisionNumber: row.revisionNumber ?? null,
|
||||
childIssues: childIds
|
||||
.map((childId) => childIssueMap.get(childId) ?? null)
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
import { useState } from "react";
|
||||
import type { Meta, StoryObj } from "@storybook/react-vite";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import type { AcceptedPlanDecompositionSummary } from "@paperclipai/shared";
|
||||
import { IssuePlanDecompositionsSection } from "@/components/IssuePlanDecompositionsSection";
|
||||
import { queryKeys } from "@/lib/queryKeys";
|
||||
import { storybookAgentMap } from "../fixtures/paperclipData";
|
||||
|
||||
const issueId = "issue-plan-decomposition-story";
|
||||
const issueIdentifier = "PAP-6831";
|
||||
|
||||
function buildDecomposition(
|
||||
overrides: Partial<AcceptedPlanDecompositionSummary>,
|
||||
): AcceptedPlanDecompositionSummary {
|
||||
return {
|
||||
id: "decomposition-story-1",
|
||||
companyId: "company-storybook",
|
||||
sourceIssueId: issueId,
|
||||
acceptedPlanRevisionId: "revision-story-1",
|
||||
acceptedInteractionId: "interaction-story-1",
|
||||
status: "completed",
|
||||
requestFingerprint: "fingerprint-story-1",
|
||||
requestedChildCount: 2,
|
||||
childIssueIds: ["issue-child-1", "issue-child-2"],
|
||||
ownerAgentId: "agent-codex",
|
||||
ownerUserId: null,
|
||||
ownerRunId: "run-story-1",
|
||||
completedAt: "2026-05-28T06:22:00.000Z",
|
||||
createdAt: "2026-05-28T06:18:00.000Z",
|
||||
updatedAt: "2026-05-28T06:22:00.000Z",
|
||||
acceptedPlanRevisionNumber: 7,
|
||||
childIssues: [
|
||||
{
|
||||
id: "issue-child-1",
|
||||
identifier: "PAP-6840",
|
||||
title: "Harden accepted-plan wake routing",
|
||||
status: "done",
|
||||
priority: "medium",
|
||||
assigneeAgentId: "agent-codex",
|
||||
assigneeUserId: null,
|
||||
},
|
||||
{
|
||||
id: "issue-child-2",
|
||||
identifier: "PAP-6841",
|
||||
title: "Add decomposition regression coverage",
|
||||
status: "in_progress",
|
||||
priority: "medium",
|
||||
assigneeAgentId: "agent-qa",
|
||||
assigneeUserId: null,
|
||||
},
|
||||
],
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
function HydratedSection({
|
||||
decompositions,
|
||||
}: {
|
||||
decompositions: AcceptedPlanDecompositionSummary[];
|
||||
}) {
|
||||
const queryClient = useQueryClient();
|
||||
const [ready] = useState(() => {
|
||||
queryClient.setQueryData(queryKeys.issues.acceptedPlanDecompositions(issueId), decompositions);
|
||||
return true;
|
||||
});
|
||||
|
||||
if (!ready) return null;
|
||||
|
||||
return (
|
||||
<div className="paperclip-story">
|
||||
<main className="paperclip-story__inner">
|
||||
<div className="mx-auto max-w-3xl rounded-2xl border border-border bg-background/95 p-6 shadow-sm">
|
||||
<IssuePlanDecompositionsSection
|
||||
issueId={issueId}
|
||||
issueIdentifier={issueIdentifier}
|
||||
agentMap={storybookAgentMap}
|
||||
/>
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
const meta = {
|
||||
title: "Issue Detail/Plan Decompositions",
|
||||
component: HydratedSection,
|
||||
args: {
|
||||
decompositions: [],
|
||||
},
|
||||
parameters: {
|
||||
layout: "fullscreen",
|
||||
},
|
||||
} satisfies Meta<typeof HydratedSection>;
|
||||
|
||||
export default meta;
|
||||
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const InFlight: Story = {
|
||||
args: {
|
||||
decompositions: [
|
||||
buildDecomposition({
|
||||
status: "in_flight",
|
||||
completedAt: null,
|
||||
updatedAt: "2026-05-28T06:20:00.000Z",
|
||||
childIssueIds: ["issue-child-1"],
|
||||
childIssues: [
|
||||
{
|
||||
id: "issue-child-1",
|
||||
identifier: "PAP-6840",
|
||||
title: "Harden accepted-plan wake routing",
|
||||
status: "done",
|
||||
priority: "medium",
|
||||
assigneeAgentId: "agent-codex",
|
||||
assigneeUserId: null,
|
||||
},
|
||||
],
|
||||
}),
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export const Completed: Story = {
|
||||
args: {
|
||||
decompositions: [
|
||||
buildDecomposition({}),
|
||||
],
|
||||
},
|
||||
};
|
||||
Reference in new issue
Block a user