115 lines
3.3 KiB
JavaScript
115 lines
3.3 KiB
JavaScript
import { ENVIRONMENT_DEV } from "../protocol/index.mjs";
|
|
|
|
export const DEV_DB_ENV_CONTRACT = Object.freeze({
|
|
contractVersion: "v1",
|
|
environment: ENVIRONMENT_DEV,
|
|
requiredEnv: Object.freeze([
|
|
"HWLAB_CLOUD_DB_URL",
|
|
"HWLAB_CLOUD_DB_SSL_MODE"
|
|
]),
|
|
secretRefs: Object.freeze([
|
|
Object.freeze({
|
|
env: "HWLAB_CLOUD_DB_URL",
|
|
secretName: "hwlab-cloud-api-dev-db",
|
|
secretKey: "database-url"
|
|
})
|
|
]),
|
|
nonSecretDefaults: Object.freeze({
|
|
HWLAB_CLOUD_DB_SSL_MODE: "require"
|
|
}),
|
|
forbidden: Object.freeze({
|
|
prodAllowed: false,
|
|
secretPlaintextAllowed: false,
|
|
liveDbEvidenceFromFixtures: false
|
|
})
|
|
});
|
|
|
|
const secretEnvNames = new Set(DEV_DB_ENV_CONTRACT.secretRefs.map((item) => item.env));
|
|
|
|
export function buildDbHealthContract(env = process.env) {
|
|
const fields = DEV_DB_ENV_CONTRACT.requiredEnv.map((name) => {
|
|
const present = hasEnvValue(env, name);
|
|
return {
|
|
name,
|
|
present,
|
|
redacted: secretEnvNames.has(name),
|
|
source: secretEnvNames.has(name) ? "k8s-secret-ref" : "runtime-env",
|
|
required: true
|
|
};
|
|
});
|
|
const missingEnv = fields.filter((field) => !field.present).map((field) => field.name);
|
|
const configReady = missingEnv.length === 0;
|
|
const connected = false;
|
|
const connectionChecked = false;
|
|
const status = configReady ? "degraded" : "blocked";
|
|
|
|
return {
|
|
contractVersion: DEV_DB_ENV_CONTRACT.contractVersion,
|
|
environment: DEV_DB_ENV_CONTRACT.environment,
|
|
connected,
|
|
connectionChecked,
|
|
configReady,
|
|
ready: connected,
|
|
status,
|
|
mode: configReady ? "configured_without_live_connection" : "not_configured",
|
|
fields,
|
|
missingEnv,
|
|
secretRefs: DEV_DB_ENV_CONTRACT.secretRefs.map(({ env: envName, secretName, secretKey }) => ({
|
|
env: envName,
|
|
secretName,
|
|
secretKey,
|
|
present: hasEnvValue(env, envName),
|
|
redacted: true
|
|
})),
|
|
safety: {
|
|
devOnly: true,
|
|
prodAllowed: DEV_DB_ENV_CONTRACT.forbidden.prodAllowed,
|
|
secretsRead: false,
|
|
valuesRedacted: true,
|
|
liveDbEvidence: false
|
|
},
|
|
evidence: configReady ? "env_presence_only_no_live_db" : "env_contract_blocked"
|
|
};
|
|
}
|
|
|
|
export function buildDbEnvManifestPlaceholder() {
|
|
return {
|
|
requiredEnv: [...DEV_DB_ENV_CONTRACT.requiredEnv],
|
|
secretRefs: DEV_DB_ENV_CONTRACT.secretRefs.map((item) => ({ ...item })),
|
|
nonSecretDefaults: { ...DEV_DB_ENV_CONTRACT.nonSecretDefaults },
|
|
fixtureEvidence: {
|
|
liveDbEvidence: false,
|
|
summary: "This manifest contract records only env and Secret reference names. It is not live DB evidence."
|
|
}
|
|
};
|
|
}
|
|
|
|
export function summarizeDbContract(db = buildDbHealthContract()) {
|
|
return {
|
|
status: db.status,
|
|
ready: db.ready,
|
|
configReady: db.configReady,
|
|
connected: db.connected,
|
|
connectionChecked: db.connectionChecked,
|
|
requiredEnv: db.fields.map((field) => ({
|
|
name: field.name,
|
|
present: field.present,
|
|
redacted: field.redacted
|
|
})),
|
|
missingEnv: [...db.missingEnv],
|
|
secretRefs: db.secretRefs.map(({ env: envName, secretName, secretKey, present, redacted }) => ({
|
|
env: envName,
|
|
secretName,
|
|
secretKey,
|
|
present,
|
|
redacted
|
|
})),
|
|
liveDbEvidence: db.safety.liveDbEvidence,
|
|
fixtureEvidence: false
|
|
};
|
|
}
|
|
|
|
function hasEnvValue(env, name) {
|
|
return typeof env?.[name] === "string" && env[name].trim().length > 0;
|
|
}
|