export type ApiPersistence = 'postgres' | 'inmemory'; function isTruthyEnv(value: string | undefined): boolean { if (!value) return false; return value !== '0' && value.toLowerCase() !== 'false'; } function isSet(value: string | undefined): boolean { return value !== undefined; } function readLower(name: string): string | undefined { const raw = process.env[name]; if (raw === undefined) return undefined; return raw.toLowerCase(); } function requireOneOf(name: string, value: string, allowed: readonly T[]): T { if ((allowed as readonly string[]).includes(value)) { return value as T; } const valid = allowed.join(', '); throw new Error(`Invalid ${name}: "${value}". Must be one of: ${valid}`); } /** * Controls whether the API uses Postgres or runs in-memory. * * If `GRIDPILOT_API_PERSISTENCE` is set, it must be `postgres|inmemory`. * Otherwise, it falls back to: `postgres` when `DATABASE_URL` exists, else `inmemory`. */ export function getApiPersistence(): ApiPersistence { const configured = readLower('GRIDPILOT_API_PERSISTENCE'); if (configured) { return requireOneOf('GRIDPILOT_API_PERSISTENCE', configured, ['postgres', 'inmemory'] as const); } // Tests should default to in-memory even when DATABASE_URL exists, unless explicitly overridden. if (process.env.NODE_ENV === 'test') { return 'inmemory'; } return process.env.DATABASE_URL ? 'postgres' : 'inmemory'; } /** * Keep bootstrap on by default; tests can disable explicitly. * * `GRIDPILOT_API_BOOTSTRAP` uses "truthy" parsing: * - false when unset / "0" / "false" * - true otherwise */ export function getEnableBootstrap(): boolean { const raw = process.env.GRIDPILOT_API_BOOTSTRAP; if (raw === undefined) return true; return isTruthyEnv(raw); } /** * Force reseeding of racing data in development mode. * * `GRIDPILOT_API_FORCE_RESEED` uses "truthy" parsing: * - false when unset / "0" / "false" * - true otherwise * * Only works in non-production environments. */ export function getForceReseed(): boolean { const raw = process.env.GRIDPILOT_API_FORCE_RESEED; if (raw === undefined) return false; return isTruthyEnv(raw); } /** * When set, the API will generate `openapi.json` and optionally reduce logging noise. * * Matches previous behavior: unknown value (even "0") counts as enabled if the var is present. */ export function getGenerateOpenapi(): boolean { return isSet(process.env.GENERATE_OPENAPI); }