mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-25 09:41:04 +01:00
fix workspace finalize blocker attribution
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
9cf661cc22
commit
2634ccbe44
2 files changed
+39
-13
No files matched your search
@@ -3215,7 +3215,7 @@ describeEmbeddedPostgres("issueService blockers and dependency wake readiness",
|
||||
});
|
||||
});
|
||||
|
||||
it("ignores unattributed pre-backfill workspace operations when checking blocker readiness", async () => {
|
||||
it("keeps dependents blocked on unattributed workspace operations for the blocker workspace", async () => {
|
||||
const {
|
||||
companyId,
|
||||
executionWorkspaceId,
|
||||
@@ -3232,6 +3232,22 @@ describeEmbeddedPostgres("issueService blockers and dependency wake readiness",
|
||||
startedAt: new Date("2026-05-23T22:00:00.000Z"),
|
||||
});
|
||||
|
||||
await expect(svc.listWakeableBlockedDependents(blockerId)).resolves.toEqual([]);
|
||||
await expect(svc.getDependencyReadiness(dependentId)).resolves.toMatchObject({
|
||||
isDependencyReady: false,
|
||||
pendingFinalizeBlockerIssueIds: [blockerId],
|
||||
unresolvedBlockerIssueIds: [blockerId],
|
||||
});
|
||||
|
||||
await db.insert(workspaceOperations).values({
|
||||
companyId,
|
||||
executionWorkspaceId,
|
||||
issueId: null,
|
||||
phase: "workspace_finalize",
|
||||
status: "succeeded",
|
||||
startedAt: new Date("2026-05-23T22:05:00.000Z"),
|
||||
});
|
||||
|
||||
await expect(svc.listWakeableBlockedDependents(blockerId)).resolves.toEqual([
|
||||
expect.objectContaining({
|
||||
id: dependentId,
|
||||
@@ -3241,7 +3257,6 @@ describeEmbeddedPostgres("issueService blockers and dependency wake readiness",
|
||||
await expect(svc.getDependencyReadiness(dependentId)).resolves.toMatchObject({
|
||||
isDependencyReady: true,
|
||||
pendingFinalizeBlockerIssueIds: [],
|
||||
unresolvedBlockerIssueIds: [],
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -686,6 +686,9 @@ async function listPendingFinalizeBlockerIssueIds(
|
||||
const blockerIssueIds = [...new Set(blockerWorkspacePairs.map((pair) => pair.blockerIssueId))];
|
||||
const executionWorkspaceIds = [...new Set(blockerWorkspacePairs.map((pair) => pair.executionWorkspaceId))];
|
||||
if (blockerIssueIds.length === 0 || executionWorkspaceIds.length === 0) return pending;
|
||||
const blockerWorkspaceKeys = new Set(
|
||||
blockerWorkspacePairs.map((pair) => `${pair.blockerIssueId}:${pair.executionWorkspaceId}`),
|
||||
);
|
||||
|
||||
const rows = await dbOrTx
|
||||
.select({
|
||||
@@ -699,28 +702,36 @@ async function listPendingFinalizeBlockerIssueIds(
|
||||
.where(
|
||||
and(
|
||||
eq(workspaceOperations.companyId, companyId),
|
||||
inArray(workspaceOperations.issueId, blockerIssueIds),
|
||||
inArray(workspaceOperations.executionWorkspaceId, executionWorkspaceIds),
|
||||
or(inArray(workspaceOperations.issueId, blockerIssueIds), isNull(workspaceOperations.issueId)),
|
||||
),
|
||||
);
|
||||
|
||||
const latestByBlockerWorkspace = new Map<string, { phase: string; status: string; startedAt: Date }>();
|
||||
for (const row of rows) {
|
||||
if (!row.issueId || !row.executionWorkspaceId) continue;
|
||||
const key = `${row.issueId}:${row.executionWorkspaceId}`;
|
||||
const current = latestByBlockerWorkspace.get(key);
|
||||
if (!current || row.startedAt > current.startedAt) {
|
||||
latestByBlockerWorkspace.set(key, {
|
||||
phase: row.phase,
|
||||
status: row.status,
|
||||
startedAt: row.startedAt,
|
||||
});
|
||||
if (!row.executionWorkspaceId) continue;
|
||||
const keys = row.issueId
|
||||
? [`${row.issueId}:${row.executionWorkspaceId}`]
|
||||
: blockerWorkspacePairs
|
||||
.filter((pair) => pair.executionWorkspaceId === row.executionWorkspaceId)
|
||||
.map((pair) => `${pair.blockerIssueId}:${pair.executionWorkspaceId}`);
|
||||
|
||||
for (const key of keys) {
|
||||
if (!blockerWorkspaceKeys.has(key)) continue;
|
||||
const current = latestByBlockerWorkspace.get(key);
|
||||
if (!current || row.startedAt > current.startedAt) {
|
||||
latestByBlockerWorkspace.set(key, {
|
||||
phase: row.phase,
|
||||
status: row.status,
|
||||
startedAt: row.startedAt,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const pair of blockerWorkspacePairs) {
|
||||
const latest = latestByBlockerWorkspace.get(`${pair.blockerIssueId}:${pair.executionWorkspaceId}`);
|
||||
if (!latest) continue; // no attributed ops recorded -> nothing to finalize for this blocker
|
||||
if (!latest) continue; // no ops recorded -> nothing to finalize for this blocker
|
||||
if (latest.phase === "workspace_finalize" && latest.status === "succeeded") continue;
|
||||
pending.add(pair.blockerIssueId);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user