fix(confidence-engine): propagate start outage classification

This commit is contained in:
2026-09-09 19:36:29 +01:00
parent 707fe1b3c0
commit 60c90bdd6a
3 changed files with 28 additions and 10 deletions
+3 -1
View File
@@ -100,6 +100,7 @@ export async function analyseScenario(scenario, opts = {}) {
"500", "500",
e.providerApiPath, e.providerApiPath,
e.providerExecution, e.providerExecution,
e.code,
); );
} }
@@ -175,7 +176,7 @@ function tryValidateAgainstSchema(data, schema) {
// ── Result builders ────────────────────────────────── // ── Result builders ──────────────────────────────────
function buildErrorResponse(message, elapsed, statusCode = 500, providerApiPath, providerExecution) { function buildErrorResponse(message, elapsed, statusCode = 500, providerApiPath, providerExecution, code) {
return { return {
success: false, success: false,
error: message, error: message,
@@ -187,6 +188,7 @@ function buildErrorResponse(message, elapsed, statusCode = 500, providerApiPath,
statusCode, statusCode,
providerApiPath, providerApiPath,
providerExecution, providerExecution,
code,
}; };
} }
+1
View File
@@ -382,6 +382,7 @@ export async function startCase(body, dependencies = {}) {
providerApiPath: analysis.providerApiPath ?? undefined, providerApiPath: analysis.providerApiPath ?? undefined,
providerExecution: analysis.providerExecution ?? undefined, providerExecution: analysis.providerExecution ?? undefined,
rawResponse: analysis.rawResponse ?? undefined, rawResponse: analysis.rawResponse ?? undefined,
code: analysis.code ?? undefined,
statusCode: Number(analysis.statusCode) || 502, statusCode: Number(analysis.statusCode) || 502,
}; };
} }
+24 -9
View File
@@ -1,13 +1,20 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
const mockStartCase = vi.fn(); const mockStartCase = vi.fn();
let realStartCase;
let warnSpy; let warnSpy;
let errorSpy; let errorSpy;
vi.mock("@/lib/graph/orchestrator.js", () => ({ vi.mock("@/lib/config.js", () => ({
startCase: (...args) => mockStartCase(...args), getConfig: () => ({ ok: true }),
})); }));
vi.mock("@/lib/graph/orchestrator.js", async (importOriginal) => {
const actual = await importOriginal();
realStartCase = actual.startCase;
return { ...actual, startCase: (...args) => mockStartCase(...args) };
});
vi.mock("@/lib/supabase/api-auth.js", () => ({ vi.mock("@/lib/supabase/api-auth.js", () => ({
withAuthenticatedApi: (handler) => handler, withAuthenticatedApi: (handler) => handler,
})); }));
@@ -128,13 +135,21 @@ describe("app/api/cases/start route", () => {
}); });
it("returns a sanitized 503 when the provider is unavailable", async () => { it("returns a sanitized 503 when the provider is unavailable", async () => {
mockStartCase.mockResolvedValue({ const unavailableError = Object.assign(
success: false, new Error("Ollama /api/generate request timed out after 5 minutes"),
code: "PROVIDER_UNAVAILABLE", {
error: "Ollama /api/generate request timed out after 5 minutes", code: "PROVIDER_UNAVAILABLE",
providerApiPath: "/api/generate", providerApiPath: "/api/generate",
providerExecution: { generateRequestAttempted: true }, providerExecution: { generateRequestAttempted: true },
}); },
);
const reconstructionProvider = {
generateReconstruction: vi.fn().mockRejectedValue(unavailableError),
};
mockStartCase.mockImplementation((body) => realStartCase(body, {
reconstructionProvider,
reconstructionModelName: "configured-model",
}));
const { POST } = await import("@/app/api/cases/start/route.js"); const { POST } = await import("@/app/api/cases/start/route.js");
const response = await POST( const response = await POST(