119 lines
4.2 KiB
JavaScript
119 lines
4.2 KiB
JavaScript
import { RUNTIME_DURABLE_ADAPTER_MISSING } from "../db/runtime-store.mjs";
|
|
|
|
export const CLOUD_API_HEALTH_CONTRACT_VERSION = "v2";
|
|
|
|
export function buildCloudApiReadiness({ db, codeAgent, runtime } = {}) {
|
|
const dbReady = isDbReady(db);
|
|
const codeAgentReady = isCodeAgentReady(codeAgent);
|
|
const runtimeReady = isRuntimeReady(runtime);
|
|
const blockers = [];
|
|
|
|
if (!dbReady) {
|
|
blockers.push(dbBlocker(db));
|
|
}
|
|
|
|
if (!codeAgentReady) {
|
|
blockers.push(codeAgentBlocker(codeAgent));
|
|
}
|
|
|
|
if (!runtimeReady) {
|
|
blockers.push(runtimeBlocker(runtime));
|
|
}
|
|
|
|
return {
|
|
contractVersion: CLOUD_API_HEALTH_CONTRACT_VERSION,
|
|
ready: blockers.length === 0,
|
|
status: blockers.length === 0 ? "ok" : "degraded",
|
|
blockerCodes: blockers.map((blocker) => blocker.code),
|
|
blockers,
|
|
components: {
|
|
db: dbReady ? "ready" : "blocked",
|
|
codeAgent: codeAgentReady ? "ready" : "blocked",
|
|
runtime: runtimeReady ? "ready" : dbReady ? "blocked" : "waiting_for_db"
|
|
}
|
|
};
|
|
}
|
|
|
|
function isDbReady(db) {
|
|
return Boolean(db?.ready && db?.connected && db?.liveConnected !== false && db?.liveDbEvidence);
|
|
}
|
|
|
|
function isCodeAgentReady(codeAgent) {
|
|
return Boolean(codeAgent?.ready && codeAgent?.status !== "blocked");
|
|
}
|
|
|
|
function isRuntimeReady(runtime) {
|
|
if (runtime?.durable !== true) {
|
|
return false;
|
|
}
|
|
return !["blocked", "degraded", "failed"].includes(runtime.status);
|
|
}
|
|
|
|
function dbBlocker(db) {
|
|
return {
|
|
code: db?.configReady ? "db_live_connection_blocked" : "db_runtime_config_blocked",
|
|
type: "runtime_blocker",
|
|
scope: "cloud-api-db",
|
|
status: "open",
|
|
sourceIssue: "pikasTech/HWLAB#49",
|
|
summary: db?.blocker ?? "cloud-api DB live readiness is not established",
|
|
evidence: {
|
|
configReady: Boolean(db?.configReady),
|
|
connected: Boolean(db?.connected),
|
|
liveConnected: Boolean(db?.liveConnected),
|
|
liveDbEvidence: Boolean(db?.liveDbEvidence),
|
|
connectionAttempted: Boolean(db?.connectionAttempted ?? db?.connectionChecked),
|
|
connectionResult: db?.connectionResult ?? db?.connection?.result ?? "unknown"
|
|
}
|
|
};
|
|
}
|
|
|
|
function codeAgentBlocker(codeAgent) {
|
|
return {
|
|
code: codeAgent?.reason ?? "code_agent_provider_unavailable",
|
|
type: "agent_blocker",
|
|
scope: "code-agent-provider",
|
|
status: "open",
|
|
sourceIssue: "pikasTech/HWLAB#143",
|
|
summary: codeAgent?.summary ?? "Code Agent provider readiness is not established",
|
|
evidence: {
|
|
provider: codeAgent?.provider ?? "unknown",
|
|
backend: codeAgent?.backend ?? "unknown",
|
|
missingEnv: Array.isArray(codeAgent?.missingEnv) ? [...codeAgent.missingEnv] : [],
|
|
secretsRedacted: true
|
|
}
|
|
};
|
|
}
|
|
|
|
function runtimeBlocker(runtime) {
|
|
const durable = runtime?.durable === true;
|
|
const unhealthy = durable && ["blocked", "degraded", "failed"].includes(runtime?.status);
|
|
const blocker = runtime?.blocker;
|
|
return {
|
|
code: durable && unhealthy ? blocker ?? "runtime_durable_adapter_unhealthy" : RUNTIME_DURABLE_ADAPTER_MISSING,
|
|
type: "runtime_blocker",
|
|
scope: "runtime-durable-adapter",
|
|
status: "open",
|
|
sourceIssue: "pikasTech/HWLAB#164",
|
|
summary: durable && unhealthy
|
|
? runtime?.reason ?? "cloud-api durable runtime adapter is configured but not ready"
|
|
: "cloud-api DB is live, but L1 runtime writes still use process-local memory because no DB-backed durable adapter is configured",
|
|
evidence: {
|
|
adapter: runtime?.adapter ?? "unknown",
|
|
durable: Boolean(runtime?.durable),
|
|
runtimeStatus: runtime?.status ?? "unknown",
|
|
runtimeReady: Boolean(runtime?.ready),
|
|
liveRuntimeEvidence: Boolean(runtime?.liveRuntimeEvidence),
|
|
schemaReady: Boolean(runtime?.schema?.ready),
|
|
schemaChecked: Boolean(runtime?.schema?.checked),
|
|
queryAttempted: Boolean(runtime?.connection?.queryAttempted),
|
|
queryResult: runtime?.connection?.queryResult ?? "unknown",
|
|
dbBackedAdapterRequired: true,
|
|
secretMaterialRead: false
|
|
},
|
|
nextTask: durable
|
|
? "Apply/repair the runtime DB schema or DB auth, then rerun /health/live without printing DB secret material."
|
|
: "Set HWLAB_CLOUD_RUNTIME_ADAPTER=postgres after the runtime DB schema is available; keep HWLAB_CLOUD_DB_URL injected from Secret."
|
|
};
|
|
}
|