mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-15 18:30: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
96
server/src/services/workspace-runtime-read-model.ts
Normal file
96
server/src/services/workspace-runtime-read-model.ts
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
import type { Db } from "@paperclipai/db";
|
||||
import { workspaceRuntimeServices } from "@paperclipai/db";
|
||||
import { and, desc, eq, inArray } from "drizzle-orm";
|
||||
|
||||
type WorkspaceRuntimeServiceRow = typeof workspaceRuntimeServices.$inferSelect;
|
||||
|
||||
function runtimeServiceIdentityKey(row: WorkspaceRuntimeServiceRow) {
|
||||
if (row.reuseKey) return row.reuseKey;
|
||||
return [
|
||||
row.scopeType,
|
||||
row.scopeId ?? "",
|
||||
row.projectWorkspaceId ?? "",
|
||||
row.executionWorkspaceId ?? "",
|
||||
row.serviceName,
|
||||
row.command ?? "",
|
||||
row.cwd ?? "",
|
||||
].join(":");
|
||||
}
|
||||
|
||||
export function selectCurrentRuntimeServiceRows(rows: WorkspaceRuntimeServiceRow[]) {
|
||||
const current = new Map<string, WorkspaceRuntimeServiceRow>();
|
||||
for (const row of rows) {
|
||||
const identity = runtimeServiceIdentityKey(row);
|
||||
if (!current.has(identity)) current.set(identity, row);
|
||||
}
|
||||
return [...current.values()];
|
||||
}
|
||||
|
||||
export async function listCurrentRuntimeServicesForProjectWorkspaces(
|
||||
db: Db,
|
||||
companyId: string,
|
||||
projectWorkspaceIds: string[],
|
||||
) {
|
||||
if (projectWorkspaceIds.length === 0) return new Map<string, WorkspaceRuntimeServiceRow[]>();
|
||||
|
||||
const rows = await db
|
||||
.select()
|
||||
.from(workspaceRuntimeServices)
|
||||
.where(
|
||||
and(
|
||||
eq(workspaceRuntimeServices.companyId, companyId),
|
||||
inArray(workspaceRuntimeServices.projectWorkspaceId, projectWorkspaceIds),
|
||||
eq(workspaceRuntimeServices.scopeType, "project_workspace"),
|
||||
),
|
||||
)
|
||||
.orderBy(desc(workspaceRuntimeServices.updatedAt), desc(workspaceRuntimeServices.createdAt));
|
||||
|
||||
const grouped = new Map<string, WorkspaceRuntimeServiceRow[]>();
|
||||
for (const row of rows) {
|
||||
if (!row.projectWorkspaceId) continue;
|
||||
const existing = grouped.get(row.projectWorkspaceId) ?? [];
|
||||
existing.push(row);
|
||||
grouped.set(row.projectWorkspaceId, existing);
|
||||
}
|
||||
|
||||
return new Map(
|
||||
Array.from(grouped.entries()).map(([workspaceId, workspaceRows]) => [
|
||||
workspaceId,
|
||||
selectCurrentRuntimeServiceRows(workspaceRows),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
export async function listCurrentRuntimeServicesForExecutionWorkspaces(
|
||||
db: Db,
|
||||
companyId: string,
|
||||
executionWorkspaceIds: string[],
|
||||
) {
|
||||
if (executionWorkspaceIds.length === 0) return new Map<string, WorkspaceRuntimeServiceRow[]>();
|
||||
|
||||
const rows = await db
|
||||
.select()
|
||||
.from(workspaceRuntimeServices)
|
||||
.where(
|
||||
and(
|
||||
eq(workspaceRuntimeServices.companyId, companyId),
|
||||
inArray(workspaceRuntimeServices.executionWorkspaceId, executionWorkspaceIds),
|
||||
),
|
||||
)
|
||||
.orderBy(desc(workspaceRuntimeServices.updatedAt), desc(workspaceRuntimeServices.createdAt));
|
||||
|
||||
const grouped = new Map<string, WorkspaceRuntimeServiceRow[]>();
|
||||
for (const row of rows) {
|
||||
if (!row.executionWorkspaceId) continue;
|
||||
const existing = grouped.get(row.executionWorkspaceId) ?? [];
|
||||
existing.push(row);
|
||||
grouped.set(row.executionWorkspaceId, existing);
|
||||
}
|
||||
|
||||
return new Map(
|
||||
Array.from(grouped.entries()).map(([workspaceId, workspaceRows]) => [
|
||||
workspaceId,
|
||||
selectCurrentRuntimeServiceRows(workspaceRows),
|
||||
]),
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue