Files
PaperClipAI/server/src/services/issue-dependency-wakeups.ts
T

73 lines
1.9 KiB
TypeScript

import { and, eq, inArray } from "drizzle-orm";
import type { Db } from "@paperclipai/db";
import { agentWakeupRequests } from "@paperclipai/db";
export const ISSUE_BLOCKERS_RESOLVED_WAKE_REASON = "issue_blockers_resolved";
const IDEMPOTENT_DEPENDENCY_WAKE_STATUSES = [
"queued",
"deferred_issue_execution",
"claimed",
"completed",
] as const;
export function buildIssueBlockersResolvedWakeIdempotencyKey(input: {
dependentIssueId: string;
resolvedBlockerIssueId: string;
}) {
return [
ISSUE_BLOCKERS_RESOLVED_WAKE_REASON,
input.dependentIssueId,
input.resolvedBlockerIssueId,
].join(":");
}
export async function findExistingIssueBlockersResolvedWake(
db: Db,
input: {
companyId: string;
idempotencyKey: string;
},
) {
return db
.select({ id: agentWakeupRequests.id, status: agentWakeupRequests.status })
.from(agentWakeupRequests)
.where(
and(
eq(agentWakeupRequests.companyId, input.companyId),
eq(agentWakeupRequests.idempotencyKey, input.idempotencyKey),
inArray(agentWakeupRequests.status, [...IDEMPOTENT_DEPENDENCY_WAKE_STATUSES]),
),
)
.limit(1)
.then((rows) => rows[0] ?? null);
}
export async function findExistingIssueBlockersResolvedWakeForAnyKey(
db: Db,
input: {
companyId: string;
idempotencyKeys: string[];
},
) {
const idempotencyKeys = [...new Set(input.idempotencyKeys.filter(Boolean))];
if (idempotencyKeys.length === 0) return null;
return db
.select({
id: agentWakeupRequests.id,
status: agentWakeupRequests.status,
idempotencyKey: agentWakeupRequests.idempotencyKey,
})
.from(agentWakeupRequests)
.where(
and(
eq(agentWakeupRequests.companyId, input.companyId),
inArray(agentWakeupRequests.idempotencyKey, idempotencyKeys),
inArray(agentWakeupRequests.status, [...IDEMPOTENT_DEPENDENCY_WAKE_STATUSES]),
),
)
.limit(1)
.then((rows) => rows[0] ?? null);
}