fix: render registry workspaces for harness

This commit is contained in:
2026-08-05 16:03:45 +02:00
parent ece9cfda50
commit bd798b1c96
21 changed files with 659 additions and 69 deletions
+40 -11
View File
@@ -3,22 +3,49 @@ import type { ThtRunner } from "../tht/tht-runner.js";
import { getPrincipal } from "../auth/auth.js";
import type { PrincipalContext } from "../auth/principal.js";
import type { Settings } from "../settings/settings-store.js";
import type { WorkspaceRegistry } from "../workspaces/registry.js";
export function sqlRoutes(app: FastifyInstance, deps: {
tht: ThtRunner; getSettings: (principal: PrincipalContext) => Promise<Settings>;
workspaceRegistry: WorkspaceRegistry;
}): void {
const runnerFor = (principal: PrincipalContext): any => {
const runner = deps.tht as any;
return typeof runner.withPrincipal === "function" ? runner.withPrincipal(principal) : runner;
};
const authorize = async (principal: PrincipalContext, id: string, workspace?: string) => {
try {
const runner = runnerFor(principal);
if (typeof runner.sessionShow !== "function") return {};
return await runner.sessionShow(id, workspace);
const isNotFound = (error: unknown) => /not found|non trovata|inesistente|404/i.test(
error instanceof Error ? error.message : String(error),
);
const locate = async (principal: PrincipalContext, id: string, legacyWorkspace?: string) => {
const runner = runnerFor(principal);
if (typeof runner.sessionShow !== "function") return { manifest: {}, workspace: legacyWorkspace };
const registry = deps.workspaceRegistry as Partial<WorkspaceRegistry>;
const revisions = typeof registry.listRetainedSnapshots === "function"
? await registry.listRetainedSnapshots.call(deps.workspaceRegistry)
: await deps.workspaceRegistry.list();
for (const revision of revisions) {
if (revision.state !== "operational") continue;
try {
const manifest = await runner.sessionShow(id, revision.snapshotPath);
if (!manifest) continue;
const saved = manifest as { workspace_id?: string; workspace_revision?: string };
if (saved.workspace_id && saved.workspace_revision) {
const pinned = await deps.workspaceRegistry.readPinned(saved.workspace_id, saved.workspace_revision);
return {
manifest,
workspace: pinned.workspaceConfigPath ?? (pinned as any).revision?.snapshotPath,
};
}
return { manifest, workspace: revision.snapshotPath };
} catch (error) {
if (!isNotFound(error)) throw error;
}
}
catch (error) {
if (/not found|non trovata|inesistente|404/i.test(error instanceof Error ? error.message : String(error))) return undefined;
try {
const manifest = await runner.sessionShow(id, legacyWorkspace);
return manifest ? { manifest, workspace: legacyWorkspace } : undefined;
} catch (error) {
if (isNotFound(error)) return undefined;
throw error;
}
};
@@ -30,8 +57,9 @@ export function sqlRoutes(app: FastifyInstance, deps: {
try {
principal = getPrincipal(req);
const settings = await deps.getSettings(principal);
workspace = settings.workspace;
if (!await authorize(principal, id, settings.workspace)) return reply.code(404).send({ error: "session not found" });
const located = await locate(principal, id, settings.workspace);
if (!located) return reply.code(404).send({ error: "session not found" });
workspace = located.workspace;
} catch {
return reply.code(503).send({ error: "session storage is unavailable" });
}
@@ -49,8 +77,9 @@ export function sqlRoutes(app: FastifyInstance, deps: {
try {
principal = getPrincipal(req);
const settings = await deps.getSettings(principal);
workspace = settings.workspace;
if (!await authorize(principal, id, settings.workspace)) return reply.code(404).send({ error: "session not found" });
const located = await locate(principal, id, settings.workspace);
if (!located) return reply.code(404).send({ error: "session not found" });
workspace = located.workspace;
} catch {
return reply.code(503).send({ error: "session storage is unavailable" });
}