Spaces:
Build error
Build error
| import { and, desc, eq, inArray } from "drizzle-orm"; | |
| import type { Db } from "@paperclipai/db"; | |
| import { executionWorkspaces } from "@paperclipai/db"; | |
| import type { ExecutionWorkspace } from "@paperclipai/shared"; | |
| type ExecutionWorkspaceRow = typeof executionWorkspaces.$inferSelect; | |
| function toExecutionWorkspace(row: ExecutionWorkspaceRow): ExecutionWorkspace { | |
| return { | |
| id: row.id, | |
| companyId: row.companyId, | |
| projectId: row.projectId, | |
| projectWorkspaceId: row.projectWorkspaceId ?? null, | |
| sourceIssueId: row.sourceIssueId ?? null, | |
| mode: row.mode as ExecutionWorkspace["mode"], | |
| strategyType: row.strategyType as ExecutionWorkspace["strategyType"], | |
| name: row.name, | |
| status: row.status as ExecutionWorkspace["status"], | |
| cwd: row.cwd ?? null, | |
| repoUrl: row.repoUrl ?? null, | |
| baseRef: row.baseRef ?? null, | |
| branchName: row.branchName ?? null, | |
| providerType: row.providerType as ExecutionWorkspace["providerType"], | |
| providerRef: row.providerRef ?? null, | |
| derivedFromExecutionWorkspaceId: row.derivedFromExecutionWorkspaceId ?? null, | |
| lastUsedAt: row.lastUsedAt, | |
| openedAt: row.openedAt, | |
| closedAt: row.closedAt ?? null, | |
| cleanupEligibleAt: row.cleanupEligibleAt ?? null, | |
| cleanupReason: row.cleanupReason ?? null, | |
| metadata: (row.metadata as Record<string, unknown> | null) ?? null, | |
| createdAt: row.createdAt, | |
| updatedAt: row.updatedAt, | |
| }; | |
| } | |
| export function executionWorkspaceService(db: Db) { | |
| return { | |
| list: async (companyId: string, filters?: { | |
| projectId?: string; | |
| projectWorkspaceId?: string; | |
| issueId?: string; | |
| status?: string; | |
| reuseEligible?: boolean; | |
| }) => { | |
| const conditions = [eq(executionWorkspaces.companyId, companyId)]; | |
| if (filters?.projectId) conditions.push(eq(executionWorkspaces.projectId, filters.projectId)); | |
| if (filters?.projectWorkspaceId) { | |
| conditions.push(eq(executionWorkspaces.projectWorkspaceId, filters.projectWorkspaceId)); | |
| } | |
| if (filters?.issueId) conditions.push(eq(executionWorkspaces.sourceIssueId, filters.issueId)); | |
| if (filters?.status) { | |
| const statuses = filters.status.split(",").map((value) => value.trim()).filter(Boolean); | |
| if (statuses.length === 1) conditions.push(eq(executionWorkspaces.status, statuses[0]!)); | |
| else if (statuses.length > 1) conditions.push(inArray(executionWorkspaces.status, statuses)); | |
| } | |
| if (filters?.reuseEligible) { | |
| conditions.push(inArray(executionWorkspaces.status, ["active", "idle", "in_review"])); | |
| } | |
| const rows = await db | |
| .select() | |
| .from(executionWorkspaces) | |
| .where(and(...conditions)) | |
| .orderBy(desc(executionWorkspaces.lastUsedAt), desc(executionWorkspaces.createdAt)); | |
| return rows.map(toExecutionWorkspace); | |
| }, | |
| getById: async (id: string) => { | |
| const row = await db | |
| .select() | |
| .from(executionWorkspaces) | |
| .where(eq(executionWorkspaces.id, id)) | |
| .then((rows) => rows[0] ?? null); | |
| return row ? toExecutionWorkspace(row) : null; | |
| }, | |
| create: async (data: typeof executionWorkspaces.$inferInsert) => { | |
| const row = await db | |
| .insert(executionWorkspaces) | |
| .values(data) | |
| .returning() | |
| .then((rows) => rows[0] ?? null); | |
| return row ? toExecutionWorkspace(row) : null; | |
| }, | |
| update: async (id: string, patch: Partial<typeof executionWorkspaces.$inferInsert>) => { | |
| const row = await db | |
| .update(executionWorkspaces) | |
| .set({ ...patch, updatedAt: new Date() }) | |
| .where(eq(executionWorkspaces.id, id)) | |
| .returning() | |
| .then((rows) => rows[0] ?? null); | |
| return row ? toExecutionWorkspace(row) : null; | |
| }, | |
| }; | |
| } | |
| export { toExecutionWorkspace }; | |