Fix Greptile findings on extracted work

This commit is contained in:
Dotta committed 2026-07-06 13:06:58 +00:00
1 parent 1a9dc88279
commit 8074c5bd11
7 files changed
+78 -13

No files matched your search

@@ -0,0 +1,16 @@
DELETE FROM "issue_work_products" loser
USING "issue_work_products" keeper
WHERE loser."company_id" = keeper."company_id"
AND loser."issue_id" = keeper."issue_id"
AND loser."type" = keeper."type"
AND loser."provider" = keeper."provider"
AND loser."external_id" = keeper."external_id"
AND (
keeper."updated_at" > loser."updated_at"
OR (
keeper."updated_at" = loser."updated_at"
AND keeper."id"::text > loser."id"::text
)
);--> statement-breakpoint
CREATE UNIQUE INDEX IF NOT EXISTS "issue_work_products_company_issue_identity_uq"
ON "issue_work_products" USING btree ("company_id", "issue_id", "type", "provider", "external_id");
@@ -918,6 +918,13 @@
"when": 1783025224120,
"tag": "0130_run_responsible_user_invariant",
"breakpoints": true
},
{
"idx": 131,
"version": "7",
"when": 1783343000000,
"tag": "0131_issue_work_product_identity_unique",
"breakpoints": true
}
]
}
@@ -5,6 +5,7 @@ import {
pgTable,
text,
timestamp,
uniqueIndex,
uuid,
} from "drizzle-orm/pg-core";
import type { SourceTrustMetadata } from "@paperclipai/shared";
@@ -58,6 +59,13 @@ export const issueWorkProducts = pgTable(
table.provider,
table.externalId,
),
companyIssueProviderExternalUq: uniqueIndex("issue_work_products_company_issue_identity_uq").on(
table.companyId,
table.issueId,
table.type,
table.provider,
table.externalId,
),
companyUpdatedIdx: index("issue_work_products_company_updated_idx").on(
table.companyId,
table.updatedAt,
@@ -394,7 +394,7 @@ describeEmbeddedPostgres("heartbeat stale queued-run invalidation", () => {
expect(countExecuteCallsForRun(run!.id)).toBe(1);
});
it("skips generic timer wakes by default when there is no assigned issue work", async () => {
it("allows legacy generic timer wakes by default when no skip policy is set", async () => {
const { agentId } = await seedCompanyAndAgent({
heartbeatConfig: {
enabled: true,
@@ -406,8 +406,9 @@ describeEmbeddedPostgres("heartbeat stale queued-run invalidation", () => {
triggerDetail: "schedule",
});
expect(run).toBeNull();
expect(mockAdapterExecute).not.toHaveBeenCalled();
expect(run).not.toBeNull();
await waitForCondition(async () => countExecuteCallsForRun(run!.id) > 0);
expect(countExecuteCallsForRun(run!.id)).toBe(1);
});
it("allows explicit proactive generic timer wakes without assigned issue work", async () => {
@@ -251,4 +251,34 @@ describeEmbeddedPostgres("work product adoption", () => {
reviewState: "needs_board_review",
});
});
it("deduplicates concurrent adoption for the same external work product", async () => {
await seedBase();
const input = {
db,
companyId,
issueId,
runId,
projectId,
executionWorkspaceId,
resultJson: {
pullRequestUrl: "https://github.com/paperclipai/paperclip/pull/11218",
},
};
await Promise.all([
adoptWorkProductsForRun(input),
adoptWorkProductsForRun(input),
]);
const rows = await db.select().from(issueWorkProducts).where(eq(issueWorkProducts.issueId, issueId));
expect(rows).toHaveLength(1);
expect(rows[0]).toMatchObject({
type: "pull_request",
provider: "github",
externalId: "paperclipai/paperclip#11218",
isPrimary: true,
});
});
});
+1 -1
View File
@@ -8672,7 +8672,7 @@ export function heartbeatService(db: Db, options: HeartbeatServiceOptions = {})
heartbeat.skipTimerWhenNoActionableWork ??
heartbeat.requireActionableTimerWork ??
heartbeat.issueOnlyTimer,
true,
false,
),
maxDailyRuns: normalizeOptionalNonNegativeInteger(
heartbeat.maxDailyRuns ?? heartbeat.dailyRunLimit ?? heartbeat.dailyRunCap ?? heartbeat.maxRunsPerDay,
+12 -9
View File
@@ -472,22 +472,25 @@ export async function adoptWorkProductsForRun(input: {
));
}
if (existing) {
await tx
.update(issueWorkProducts)
.set(values)
.where(eq(issueWorkProducts.id, existing.id));
return "updated" as const;
}
await tx
.insert(issueWorkProducts)
.values({
...values,
createdByRunId: input.runId,
createdAt: now,
})
.onConflictDoUpdate({
target: [
issueWorkProducts.companyId,
issueWorkProducts.issueId,
issueWorkProducts.type,
issueWorkProducts.provider,
issueWorkProducts.externalId,
],
set: values,
});
return "created" as const;
return existing ? "updated" as const : "created" as const;
});
if (outcome === "created") created += 1;