The project uses @nestjs/config and Joi for environment validation.
The .env file must be at the project root.
NODE_ENV:development,production, ortest. Default:developmentPORT: Server port. Default:3000APP_NAME: Application name (optional)
DB_HOST,DB_PORT,DB_USERNAME,DB_PASSWORD,DB_DATABASEDB_SSL:truefor TLS (required in production)DB_POOL_MAX: Connection pool max. Default:20DATABASE_URL: optional connection string for Drizzle tooling (db:generate,db:migrate,db:studio)
In production, schema sync is disabled; use Drizzle migrations only.
PRIVATE_KEY: RSA private key in PEM format (signs tokens)PUBLIC_KEY: RSA public key in PEM format (verifies tokens)
Generate keys:
openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -pubout -out public.pemIn .env, paste PEM content as a single line, replacing newlines with \n. Both required in production.
ALLOWED_ORIGINS: Comma-separated URLs (e.g.https://admin.example.com). Required in production.
REDIS_HOST: DefaultlocalhostREDIS_PORT: Default6379REDIS_PASSWORD: OptionalDISABLE_REDIS: Set totrueto skip BullMQ initialization (webhook CRUD remains available; async delivery queue is disabled). Useful for local development without Redis.
PERMISSION_GUARD_STRICT: Set totrueto makePermissionGuardfail-closed (HTTP 403) when@RequirePermissionsis absent. Default:false(fail-open with WARN log — allows routes protected by other means).
RESEND_API_KEY,RESEND_FROM_EMAIL,RESEND_FROM_NAME(optional)
The Joi schema in src/config/validation.schema.ts:
- Fails fast on startup with all validation errors
- Requires
PRIVATE_KEYandPUBLIC_KEYwhenNODE_ENV=production - Requires
DB_SSL=truein production - Requires
ALLOWED_ORIGINSin production (URL format)
npm run db:generate— generate migration files from schema changesnpm run db:migrate— apply migrationsnpm run db:studio— inspect the database via Drizzle Studio