Variables de entorno
Se definen en .env (usar .env.example como base). bootstrap/load-env.ts lee .env del directorio de trabajo y no pisa variables ya presentes en el entorno del proceso. ConfigModule valida con Joi (src/config/env.validation.ts) al arrancar y no define validationOptions, por lo que las variables que el esquema no menciona se aceptan sin validar.
La columna Requerida indica lo que exige el esquema Joi; Default es el valor efectivo si falta (esquema o src/config/*.ts). No se documentan valores reales ni secretos.
Aplicación
| Variable | Requerida | Default | Descripción | Dónde se lee |
|---|---|---|---|---|
NODE_ENV | No | development | development, production o test. En production CORS restringe las cabeceras permitidas (CORS_ALLOWED_HEADERS_PROD); en otro caso acepta *. La imagen Docker la fija a production | bootstrap/cors.ts, config/app.config.ts (app.nodeEnv) |
HOST | No (no está en el esquema) | localhost | Host que se muestra en la URL del log de arranque y en la de Swagger. La imagen Docker la fija a 0.0.0.0 | config/app.config.ts, main.ts |
PORT | No | 3000 | Puerto HTTP | config/app.config.ts |
APP_NAME | Sí | — | Nombre de la aplicación (título de Swagger y logs) | config/app.config.ts, main.ts |
APP_ENV | No | development | development, staging o production. Con production se desactiva Swagger/Scalar y el seeder de demo se niega a ejecutarse | config/app.config.ts, main.ts, database/seeds/run-seed.ts |
NODE_ENV y APP_ENV son independientes: el primero afecta a CORS; el segundo a la documentación de la API y a los seeds.
Base de datos
| Variable | Requerida | Default | Descripción | Dónde se lee |
|---|---|---|---|---|
MONGODB_URI | Sí (URI válida) | — | URI de conexión MongoDB. Contiene credenciales: tratar como secreto | config/database.config.ts, app.module.ts, scripts/*.js |
JWT
| Variable | Requerida | Default | Descripción | Dónde se lee |
|---|---|---|---|---|
JWT_SECRET | Sí (mín. 32 caracteres) | — | Clave de firma de tokens (secreto) | config/jwt.config.ts, core/auth/auth.module.ts |
JWT_EXPIRES_IN | No | 1d | Duración del access token | config/jwt.config.ts, core/auth/auth.module.ts |
Almacenamiento (S3 / MinIO)
| Variable | Requerida | Default | Descripción | Dónde se lee |
|---|---|---|---|---|
STORAGE_ENDPOINT | Sí (URI) | — (el código usaría http://localhost:9000, pero el esquema la exige) | Endpoint interno del storage S3 compatible | config/storage.config.ts, core/storage/storage.service.ts, main.ts |
STORAGE_PUBLIC_URL | No (no está en el esquema ni en .env.example) | el valor de STORAGE_ENDPOINT | URL base accesible por los clientes. Se usa para firmar URLs prefirmadas y para construir las URLs públicas (<publicUrl>/<bucket>/<key>). Defínela cuando el endpoint interno (por ejemplo un nombre de servicio Docker) no es alcanzable desde el navegador o desde Meta | config/storage.config.ts, core/storage/storage.service.ts |
STORAGE_ACCESS_KEY | Sí | — (el código usaría minioadmin) | Access key (secreto) | config/storage.config.ts |
STORAGE_SECRET_KEY | Sí | — (el código usaría minioadmin) | Secret key (secreto) | config/storage.config.ts |
STORAGE_BUCKET | Sí | — (el código usaría crm-files) | Nombre del bucket | config/storage.config.ts, main.ts |
STORAGE_REGION | No | us-east-1 | Región S3 | config/storage.config.ts |
docker-compose.yml reutiliza STORAGE_ACCESS_KEY y STORAGE_SECRET_KEY como credenciales raíz de MinIO (MINIO_ROOT_USER / MINIO_ROOT_PASSWORD, con fallback minioadmin solo para desarrollo local).
Redis / colas (BullMQ)
| Variable | Requerida | Default | Descripción | Dónde se lee |
|---|---|---|---|---|
REDIS_HOST | No | redis | Host de Redis | config/redis.config.ts, modules/queue/queue.module.ts, main.ts |
REDIS_PORT | No | 6379 | Puerto | config/redis.config.ts |
REDIS_PASSWORD | No (admite vacío) | — | Contraseña (secreto) | config/redis.config.ts |
REDIS_DB | No | 0 | Base de datos | config/redis.config.ts |
BULL_PREFIX | No | crm-bull | Prefijo de las colas | config/redis.config.ts, queue.module.ts |
Redis lo usan la cola meta-webhook, la de mensajes programados y el lock de entrada. El docker-compose.yml levanta redis:7-alpine en 127.0.0.1:6379.
Cifrado en reposo
| Variable | Requerida | Descripción |
|---|---|---|
WHATSAPP_SESSION_ENCRYPTION_KEY | Sí | Clave AES-256 (base64, 32 bytes) para cifrar la sesión de WhatsApp |
META_TOKEN_ENCRYPTION_KEY | Sí | Clave AES-256 (base64, 32 bytes) para cifrar los tokens de Meta. Debe ser distinta de la anterior |
Generar con openssl rand -base64 32. Si faltan, tienen formato inválido o son iguales, la app no arranca. Ningún archivo src/config/*.ts las expone: se leen directamente de process.env mediante readEncryptionKey (core/crypto/secret-encryption.ts), desde connection/helpers/meta-token.helper.ts y whatsapp/auth/mongo-auth-state.ts. Ver Crypto.
Canales Meta (Instagram / Messenger)
Todas opcionales: sin ellas el webhook de Meta responde 404 y el OAuth de Instagram no está disponible. Detalle en Meta.
| Variable | Default | Descripción | Clave de config |
|---|---|---|---|
META_VERIFY_TOKEN | — | Token de verificación del webhook (mín. 16 caracteres) | meta.verifyToken |
META_APP_SECRET | — | Secreto de la app (firma del webhook de facebook, appsecret_proof) | meta.appSecret |
INSTAGRAM_APP_SECRET | — | Secreto de la app de Instagram (firma del webhook de instagram, OAuth) | meta.instagramAppSecret |
INSTAGRAM_APP_ID | — | App ID de Instagram (solo dígitos) | meta.instagramAppId |
META_OAUTH_REDIRECT_URI | — | Redirect URI registrado en Meta, exacto (http o https) | meta.oauthRedirectUri |
FRONTEND_URL | — | URL del frontend para redirigir tras el OAuth (http o https) | meta.frontendUrl |
META_GRAPH_API_VERSION | v25.0 (aplicado en meta-graph.client.ts; la config deja undefined) | Versión de Graph API (vNN.N) | meta.graphApiVersion |
META_ENABLE_HUMAN_AGENT_TAG | false | true envía con el tag HUMAN_AGENT | meta.enableHumanAgentTag |
Se leen en config/meta.config.ts y se consumen en modules/meta/services/ (meta-webhook.service.ts, meta-oauth.service.ts, meta-graph.client.ts, meta-outbound.dispatcher.ts). Las cadenas vacías se tratan como no definidas.
Migraciones y seeds
| Variable | Default | Descripción | Dónde se lee |
|---|---|---|---|
MIGRATION_DB | false | Ejecuta migraciones de esquema al arrancar | main.ts |
MIGRATION_DB_DATA | false | Ejecuta migraciones de datos (catálogo de permisos, tenants) | main.ts, permission-catalog-seed.service.ts, tenant.service.ts |
RUN_SEEDS | false | Ejecuta seeds; solo con APP_ENV=development | main.ts, database/seeds/seed.service.ts |
FORCE_SEED_CLEANUP | false | Fuerza limpieza en seeds | database/seeds/seed.service.ts |
Testing
| Variable | Default | Descripción | Dónde se lee |
|---|---|---|---|
TESTING | false | Si true, main.ts ejecuta la suite antes de levantar el servidor y npm run test:ci corre Jest (con false lo omite) | main.ts, config/app.config.ts, scripts/test-runner.js |
Variables solo de scripts
No pasan por Joi; las leen scripts de scripts/ ejecutados a mano.
| Variable | Script | Descripción |
|---|---|---|
PLATFORM_ADMIN_EMAIL, PLATFORM_ADMIN_PASSWORD | bootstrap-platform-admin.js (npm run platform:bootstrap-admin) | Credenciales del admin de plataforma; la contraseña exige mín. 12 caracteres (secreto) |
PLATFORM_ADMIN_USERNAME, PLATFORM_ADMIN_FIRSTNAME, PLATFORM_ADMIN_LASTNAME | Ídem | Opcionales; por defecto la parte local del email, Platform y Admin |
MONGODB_URI | bootstrap-platform-admin.js, migrate-message-ack.js, cleanup-whatsapp-test-contacts.js, migrations/*.js | Conexión a Mongo |
No son variables de entorno
Constantes del código que a veces se confunden con configuración: API_PREFIX (api), API_DOCS_PATH (docs), STORAGE_HEALTH_PATH (/minio/health/live), PUBLIC_STORAGE_PREFIX (public/), AVATAR_STORAGE_PREFIX (avatars), SCHEDULED_MESSAGE_ENQUEUE_TIMEOUT_MS (6000), META_SEND_PATH, META_EXTERNAL_ID_SEPARATOR y VIDEO_THUMBNAIL_WIDTH. Son fijas; cambiarlas requiere tocar el código.
Cómo se carga
// src/bootstrap/load-env.ts
// Lee .env (sin pisar variables ya definidas) antes de inicializar NestJS
// src/config/env.validation.ts
// Esquema Joi: presencia y formato; si falta una requerida la app no arranca
Archivos de config tipados
Cada grupo de variables tiene su propio archivo en src/config/ (registrados con registerAs y cargados en ConfigModule.forRoot):
| Archivo | Clave | Variables que agrupa |
|---|---|---|
app.config.ts | app | HOST, PORT, APP_NAME, APP_ENV, NODE_ENV, TESTING |
database.config.ts | database | MONGODB_URI |
jwt.config.ts | jwt | JWT_SECRET, JWT_EXPIRES_IN |
storage.config.ts | storage | STORAGE_ENDPOINT, STORAGE_PUBLIC_URL, STORAGE_ACCESS_KEY, STORAGE_SECRET_KEY, STORAGE_BUCKET, STORAGE_REGION |
redis.config.ts | redis | REDIS_HOST, REDIS_PORT, REDIS_PASSWORD, REDIS_DB, BULL_PREFIX |
meta.config.ts | meta | Todas las variables de Meta de arriba |