mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-14 18:10:39 +09:00
Fix workspace runtime state reconciliation
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
parent
5a9a2a9112
commit
f515f2aa12
9 changed files with 477 additions and 64 deletions
|
|
@ -14,6 +14,10 @@ import type {
|
|||
WorkspaceRuntimeService,
|
||||
} from "@paperclipai/shared";
|
||||
import { parseProjectExecutionWorkspacePolicy } from "./execution-workspace-policy.js";
|
||||
import {
|
||||
listCurrentRuntimeServicesForExecutionWorkspaces,
|
||||
listCurrentRuntimeServicesForProjectWorkspaces,
|
||||
} from "./workspace-runtime-read-model.js";
|
||||
|
||||
type ExecutionWorkspaceRow = typeof executionWorkspaces.$inferSelect;
|
||||
type WorkspaceRuntimeServiceRow = typeof workspaceRuntimeServices.$inferSelect;
|
||||
|
|
@ -317,6 +321,41 @@ function toExecutionWorkspace(
|
|||
};
|
||||
}
|
||||
|
||||
function usesInheritedProjectRuntimeServices(row: ExecutionWorkspaceRow) {
|
||||
if (row.mode !== "shared_workspace" || !row.projectWorkspaceId) return false;
|
||||
return !readExecutionWorkspaceConfig((row.metadata as Record<string, unknown> | null) ?? null)?.workspaceRuntime;
|
||||
}
|
||||
|
||||
async function loadEffectiveRuntimeServicesByExecutionWorkspace(
|
||||
db: Db,
|
||||
companyId: string,
|
||||
rows: ExecutionWorkspaceRow[],
|
||||
) {
|
||||
const executionRuntimeServices = await listCurrentRuntimeServicesForExecutionWorkspaces(
|
||||
db,
|
||||
companyId,
|
||||
rows.map((row) => row.id),
|
||||
);
|
||||
const projectWorkspaceIds = rows
|
||||
.filter((row) => usesInheritedProjectRuntimeServices(row))
|
||||
.map((row) => row.projectWorkspaceId)
|
||||
.filter((value): value is string => Boolean(value));
|
||||
const projectRuntimeServices = await listCurrentRuntimeServicesForProjectWorkspaces(
|
||||
db,
|
||||
companyId,
|
||||
[...new Set(projectWorkspaceIds)],
|
||||
);
|
||||
|
||||
return new Map(
|
||||
rows.map((row) => [
|
||||
row.id,
|
||||
usesInheritedProjectRuntimeServices(row)
|
||||
? (projectRuntimeServices.get(row.projectWorkspaceId!) ?? [])
|
||||
: (executionRuntimeServices.get(row.id) ?? []),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
export function executionWorkspaceService(db: Db) {
|
||||
return {
|
||||
list: async (companyId: string, filters?: {
|
||||
|
|
@ -346,7 +385,13 @@ export function executionWorkspaceService(db: Db) {
|
|||
.from(executionWorkspaces)
|
||||
.where(and(...conditions))
|
||||
.orderBy(desc(executionWorkspaces.lastUsedAt), desc(executionWorkspaces.createdAt));
|
||||
return rows.map((row) => toExecutionWorkspace(row));
|
||||
const runtimeServicesByWorkspaceId = await loadEffectiveRuntimeServicesByExecutionWorkspace(db, companyId, rows);
|
||||
return rows.map((row) =>
|
||||
toExecutionWorkspace(
|
||||
row,
|
||||
(runtimeServicesByWorkspaceId.get(row.id) ?? []).map(toRuntimeService),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
getById: async (id: string) => {
|
||||
|
|
@ -356,12 +401,11 @@ export function executionWorkspaceService(db: Db) {
|
|||
.where(eq(executionWorkspaces.id, id))
|
||||
.then((rows) => rows[0] ?? null);
|
||||
if (!row) return null;
|
||||
const runtimeServiceRows = await db
|
||||
.select()
|
||||
.from(workspaceRuntimeServices)
|
||||
.where(eq(workspaceRuntimeServices.executionWorkspaceId, row.id))
|
||||
.orderBy(desc(workspaceRuntimeServices.updatedAt), desc(workspaceRuntimeServices.createdAt));
|
||||
return toExecutionWorkspace(row, runtimeServiceRows.map(toRuntimeService));
|
||||
const runtimeServicesByWorkspaceId = await loadEffectiveRuntimeServicesByExecutionWorkspace(db, row.companyId, [row]);
|
||||
return toExecutionWorkspace(
|
||||
row,
|
||||
(runtimeServicesByWorkspaceId.get(row.id) ?? []).map(toRuntimeService),
|
||||
);
|
||||
},
|
||||
|
||||
getCloseReadiness: async (id: string): Promise<ExecutionWorkspaceCloseReadiness | null> => {
|
||||
|
|
@ -372,12 +416,8 @@ export function executionWorkspaceService(db: Db) {
|
|||
.then((rows) => rows[0] ?? null);
|
||||
if (!workspace) return null;
|
||||
|
||||
const runtimeServiceRows = await db
|
||||
.select()
|
||||
.from(workspaceRuntimeServices)
|
||||
.where(eq(workspaceRuntimeServices.executionWorkspaceId, workspace.id))
|
||||
.orderBy(desc(workspaceRuntimeServices.updatedAt), desc(workspaceRuntimeServices.createdAt));
|
||||
const runtimeServices = runtimeServiceRows.map(toRuntimeService);
|
||||
const runtimeServicesByWorkspaceId = await loadEffectiveRuntimeServicesByExecutionWorkspace(db, workspace.companyId, [workspace]);
|
||||
const runtimeServices = (runtimeServicesByWorkspaceId.get(workspace.id) ?? []).map(toRuntimeService);
|
||||
|
||||
const linkedIssues = await db
|
||||
.select({
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue