/
opt
/
mawid
/
apps
/
api
/
src
/
config
/
/opt/mawid/apps/api/src/config
mkdir
upload
Name
Size
Mode
Actions
env.spec.ts
1366
0644
edit
dl
rm
env.ts
2072
0644
edit
dl
rm
Edit:
/opt/mawid/apps/api/src/config/env.ts
(2072B)
import { z } from 'zod'; // WhatsApp / OpenAI credentials are only exercised from Phase 2/3 onward, // so they may be empty in development and test — production requires them. const PRODUCTION_REQUIRED = [ 'OPENAI_API_KEY', 'WA_PHONE_NUMBER_ID', 'WA_BUSINESS_ACCOUNT_ID', 'WA_ACCESS_TOKEN', 'WA_WEBHOOK_VERIFY_TOKEN', 'WA_APP_SECRET', ] as const; export const envSchema = z .object({ NODE_ENV: z.enum(['development', 'test', 'production']).default('development'), API_PORT: z.coerce.number().int().positive().default(3001), DATABASE_URL: z.string().min(1), REDIS_URL: z.string().min(1), JWT_SECRET: z.string().min(16, 'JWT_SECRET must be at least 16 characters'), OPENAI_API_KEY: z.string().default(''), WA_PHONE_NUMBER_ID: z.string().default(''), WA_BUSINESS_ACCOUNT_ID: z.string().default(''), WA_ACCESS_TOKEN: z.string().default(''), WA_WEBHOOK_VERIFY_TOKEN: z.string().default(''), WA_APP_SECRET: z.string().default(''), SENTRY_DSN: z.string().default(''), APP_BASE_URL: z.string().url(), DASHBOARD_BASE_URL: z.string().url(), TZ: z.string().default('Europe/Istanbul'), FEATURE_ECHO_MODE: z .enum(['true', 'false']) .default('false') .transform((v) => v === 'true'), }) .superRefine((env, ctx) => { if (env.NODE_ENV !== 'production') return; for (const key of PRODUCTION_REQUIRED) { if (!env[key]) { ctx.addIssue({ code: z.ZodIssueCode.custom, path: [key], message: `${key} is required in production`, }); } } }); export type Env = z.infer<typeof envSchema>; /** Throws (refusing boot) when the environment is invalid. */ export function validateEnv(config: Record<string, unknown>): Env { const parsed = envSchema.safeParse(config); if (!parsed.success) { const details = parsed.error.issues .map((i) => ` - ${i.path.join('.') || '(root)'}: ${i.message}`) .join('\n'); throw new Error(`Invalid environment configuration:\n${details}`); } return parsed.data; }
Save
cmd:
run