import { z } from 'zod'; const configSchema = z.object({ NODE_ENV: z.enum(['development', 'test', 'production']).default('development'), PORT: z.coerce.number().int().min(1).max(65535).default(8080), LOG_LEVEL: z.enum(['fatal', 'error', 'warn', 'info', 'debug', 'trace', 'silent']).default('info'), STAFF_RUNTIME_MODE: z.enum(['standalone', 'platform']).default('standalone'), DATABASE_URL: z.string().url(), REDIS_URL: z.string().url().optional(), PLATFORM_GATEWAY_URL: z.string().url().optional(), PLATFORM_JWT_ISSUER: z.string().url().optional(), PLATFORM_JWT_AUDIENCE: z.string().optional(), PLATFORM_JWKS_URL: z.string().url().optional(), STANDALONE_TENANT_ID: z.string().regex(/^[0-9A-HJKMNP-TV-Z]{26}$/), STANDALONE_ACTOR_ID: z.string().regex(/^[0-9A-HJKMNP-TV-Z]{26}$/), }); export type AppConfig = z.infer; export function loadConfig(env: NodeJS.ProcessEnv = process.env): AppConfig { const config = configSchema.parse(env); if (config.NODE_ENV === 'production' && config.STAFF_RUNTIME_MODE === 'standalone') { throw new Error('STAFF_RUNTIME_MODE=standalone is not allowed in production'); } if (config.STAFF_RUNTIME_MODE === 'platform') { const required = [ 'PLATFORM_GATEWAY_URL', 'PLATFORM_JWT_ISSUER', 'PLATFORM_JWT_AUDIENCE', 'PLATFORM_JWKS_URL', ] as const; for (const key of required) if (!config[key]) throw new Error(`${key} is required in platform mode`); } return config; }