import "dotenv/config"; import { z } from "zod"; /** * Schema for every environment variable the API reads. Parsing (below) * fails fast at startup if something required is missing/invalid, instead * of surfacing as a confusing runtime error later. */ const envSchema = z.object({ /** Runtime mode — also toggles test-only behavior (e.g. cheaper argon2 cost, see auth.service.ts). */ NODE_ENV: z.enum(["development", "test", "production"]).default("development"), /** Port the HTTP server listens on. */ PORT: z.coerce.number().int().positive().default(3000), /** Postgres connection string, consumed by Prisma. */ DATABASE_URL: z.string().url().optional(), // Auth — no default on purpose, same reasoning as docker-compose.yml's // POSTGRES_USER/PASSWORD: a secret must never have a working fallback // baked into committed code. /** Secret used to sign/verify session JWTs. Required, no default — see comment above. */ JWT_SECRET: z.string().min(32, "JWT_SECRET must be at least 32 characters"), /** JWT expiry, in `jsonwebtoken`'s duration string format (e.g. "7d"). */ JWT_EXPIRES_IN: z.string().default("7d"), /** Name of the httpOnly cookie carrying the session JWT. */ AUTH_COOKIE_NAME: z.string().default("session"), /** Origin allowed by CORS — must match wherever apps/web is served from. */ CORS_ORIGIN: z.string().default("http://localhost:5173"), }); /** Parsed, validated environment — import this instead of reading `process.env` directly anywhere else. */ export const env = envSchema.parse(process.env);