fix(frontend): accept catalog-owned workspace descriptors
This commit is contained in:
@@ -10,6 +10,12 @@ test("workspace module exposes validation and in-memory coordination but no draf
|
|||||||
expect(workspaceModule).not.toHaveProperty("workspaceDeletionDrafts");
|
expect(workspaceModule).not.toHaveProperty("workspaceDeletionDrafts");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("canonical sanitizer accepts schema-v4 workspaces without an authored dwh block", () => {
|
||||||
|
const { dwh: _catalogOwnedDwh, ...workspace } = canonicalWorkspaceFixture("psd-clinical");
|
||||||
|
|
||||||
|
expect(workspaceModule.sanitizeCanonicalWorkspace(workspace)).toEqual(workspace);
|
||||||
|
});
|
||||||
|
|
||||||
test("canonical sanitizer rejects unknown fields rather than persisting them", () => {
|
test("canonical sanitizer rejects unknown fields rather than persisting them", () => {
|
||||||
expect(workspaceModule.sanitizeCanonicalWorkspace({
|
expect(workspaceModule.sanitizeCanonicalWorkspace({
|
||||||
...canonicalWorkspaceFixture("psd-clinical"),
|
...canonicalWorkspaceFixture("psd-clinical"),
|
||||||
|
|||||||
@@ -375,26 +375,48 @@ function copyDiagnostics(value: unknown): CanonicalDiagnostics | undefined {
|
|||||||
export function sanitizeCanonicalWorkspace(value: unknown): CanonicalWorkspace | undefined {
|
export function sanitizeCanonicalWorkspace(value: unknown): CanonicalWorkspace | undefined {
|
||||||
const source = exactRecord(value, ["workspace", "dwh", "diagnostics", "evidence"]);
|
const source = exactRecord(value, ["workspace", "dwh", "diagnostics", "evidence"]);
|
||||||
const metadata = exactRecord(source?.workspace, ["schema_version", "id", "name", "description", "language"]);
|
const metadata = exactRecord(source?.workspace, ["schema_version", "id", "name", "description", "language"]);
|
||||||
const dwh = exactRecord(source?.dwh, ["engine", "database", "schema", "port", "timeout_ms", "supported_transports"]);
|
|
||||||
const diagnostics = source?.diagnostics === undefined ? undefined : copyDiagnostics(source.diagnostics);
|
const diagnostics = source?.diagnostics === undefined ? undefined : copyDiagnostics(source.diagnostics);
|
||||||
if (!metadata || !dwh) return undefined;
|
if (!metadata) return undefined;
|
||||||
const id = workspaceId(metadata.id);
|
const id = workspaceId(metadata.id);
|
||||||
const evidence = id && source?.evidence !== undefined ? copyEvidence(source.evidence, id) : undefined;
|
const evidence = id && source?.evidence !== undefined ? copyEvidence(source.evidence, id) : undefined;
|
||||||
const name = text(metadata.name);
|
const name = text(metadata.name);
|
||||||
const language = oneOf(metadata.language, ["en", "it"] as const);
|
const language = oneOf(metadata.language, ["en", "it"] as const);
|
||||||
const description = metadata.description === undefined ? undefined : text(metadata.description);
|
const description = metadata.description === undefined ? undefined : text(metadata.description);
|
||||||
const database = identifier(dwh.database);
|
|
||||||
const schema = identifier(dwh.schema);
|
|
||||||
const dwhPort = dwh.port === undefined ? undefined : positiveInteger(dwh.port, 65_535);
|
|
||||||
const dwhTimeout = dwh.timeout_ms === undefined ? undefined : positiveInteger(dwh.timeout_ms);
|
|
||||||
const dwhTransports = uniqueChoices(dwh.supported_transports, ["postgres_direct", "rest_api", "ssh_tunnel"] as const);
|
|
||||||
if (
|
if (
|
||||||
metadata.schema_version !== 4 || !id || !name || !language || (metadata.description !== undefined && !description)
|
metadata.schema_version !== 4 || !id || !name || !language
|
||||||
|| dwh.engine !== "postgres" || !database || !schema || (dwh.port !== undefined && !dwhPort) || (dwh.timeout_ms !== undefined && !dwhTimeout) || !dwhTransports
|
|| (metadata.description !== undefined && !description)
|
||||||
) return undefined;
|
) return undefined;
|
||||||
if (source?.diagnostics !== undefined && !diagnostics) return undefined;
|
if (source?.diagnostics !== undefined && !diagnostics) return undefined;
|
||||||
if (source?.evidence !== undefined && !evidence) return undefined;
|
if (source?.evidence !== undefined && !evidence) return undefined;
|
||||||
if (diagnostics?.dwh_rest && !dwhTransports.includes("rest_api")) return undefined;
|
|
||||||
|
let dwh: CanonicalWorkspace["dwh"];
|
||||||
|
if (source?.dwh !== undefined) {
|
||||||
|
const rawDwh = exactRecord(
|
||||||
|
source.dwh,
|
||||||
|
["engine", "database", "schema", "port", "timeout_ms", "supported_transports"],
|
||||||
|
);
|
||||||
|
if (!rawDwh) return undefined;
|
||||||
|
const database = identifier(rawDwh.database);
|
||||||
|
const schema = identifier(rawDwh.schema);
|
||||||
|
const port = rawDwh.port === undefined ? undefined : positiveInteger(rawDwh.port, 65_535);
|
||||||
|
const timeout = rawDwh.timeout_ms === undefined ? undefined : positiveInteger(rawDwh.timeout_ms);
|
||||||
|
const transports = uniqueChoices(
|
||||||
|
rawDwh.supported_transports,
|
||||||
|
["postgres_direct", "rest_api", "ssh_tunnel"] as const,
|
||||||
|
);
|
||||||
|
if (
|
||||||
|
rawDwh.engine !== "postgres" || !database || !schema || !transports
|
||||||
|
|| (rawDwh.port !== undefined && !port)
|
||||||
|
|| (rawDwh.timeout_ms !== undefined && !timeout)
|
||||||
|
) return undefined;
|
||||||
|
dwh = {
|
||||||
|
engine: "postgres", database, schema,
|
||||||
|
...(port ? { port } : {}),
|
||||||
|
...(timeout ? { timeout_ms: timeout } : {}),
|
||||||
|
supported_transports: transports,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (diagnostics?.dwh_rest && !dwh?.supported_transports.includes("rest_api")) return undefined;
|
||||||
return {
|
return {
|
||||||
workspace: {
|
workspace: {
|
||||||
schema_version: 4,
|
schema_version: 4,
|
||||||
@@ -403,12 +425,7 @@ export function sanitizeCanonicalWorkspace(value: unknown): CanonicalWorkspace |
|
|||||||
...(description ? { description } : {}),
|
...(description ? { description } : {}),
|
||||||
language,
|
language,
|
||||||
},
|
},
|
||||||
dwh: {
|
...(dwh ? { dwh } : {}),
|
||||||
engine: "postgres", database, schema,
|
|
||||||
...(dwhPort ? { port: dwhPort } : {}),
|
|
||||||
...(dwhTimeout ? { timeout_ms: dwhTimeout } : {}),
|
|
||||||
supported_transports: dwhTransports,
|
|
||||||
},
|
|
||||||
...(diagnostics ? { diagnostics } : {}),
|
...(diagnostics ? { diagnostics } : {}),
|
||||||
...(evidence ? { evidence } : {}),
|
...(evidence ? { evidence } : {}),
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user