Variables de entorno (referencia exhaustiva)
Lista completa de variables de entorno del proyecto: backend (Settings en
backend/app/core/config.py), bootstrap de un solo uso, frontend
(NEXT_PUBLIC_*), compose/dev y scripts. Los ejemplos usan placeholders
falsos — nunca pegues aquí credenciales reales.
Cómo se cargan (backend)
pydantic-settings lee .env y .env.local (en ese orden de ficheros;
ver class Config en backend/app/core/config.py). El cotejo es
case-insensitive (case_sensitive = False), el prefijo está vacío
(env_prefix = "", el nombre de la variable coincide con el campo en
mayúsculas) y las variables desconocidas se ignoran (extra = "ignore").
Fuentes: backend/app/core/config.py, backend/.env.example,
.env.example (raíz), frontend/.env.example,
backend/docker-compose.dev.yml, backend/app/core/bootstrap.py,
backend/app/shared/infrastructure/nvidia_service.py,
scripts/setup_oauth.sh.
Aplicación
| Variable |
Campo (Settings) |
Descripción |
Ejemplo |
APP_NAME |
app_name |
Nombre de la aplicación. |
Camarero IA |
DEBUG |
debug |
Modo depuración. Acepta booleanos y etiquetas: release/prod/production → False; dev/development → True (validador normalize_debug). |
false |
Base de datos
| Variable |
Campo (Settings) |
Descripción |
Ejemplo |
DATABASE_URL |
database_url |
URL de conexión a PostgreSQL con driver asyncpg (SQLAlchemy async lo exige). En compose se inyecta apuntando al host camarero_ia_db; con backend manual usa localhost. |
postgresql+asyncpg://camarero_user:camarero_password@localhost:5432/camarero_db |
Solo compose (no son campos de Settings; parametrizan
backend/docker-compose.dev.yml):
| Variable |
Descripción |
Ejemplo |
POSTGRES_DB |
Nombre de la BD que crea el contenedor. |
camarero_db |
POSTGRES_USER |
Usuario de Postgres del contenedor. |
camarero_user |
POSTGRES_PASSWORD |
Contraseña de Postgres del contenedor. |
[REDACTED] |
POSTGRES_PORT |
Puerto local publicado para Postgres. |
5432 |
BACKEND_PORT |
Puerto local publicado para el backend. |
8000 |
BACKEND_DEBUG |
Valor de DEBUG dentro del contenedor backend. |
true |
Solo tests (ver Ejecutar tests; la BD de tests vive
en el contenedor Podman camarero-test-db):
| Variable |
Descripción |
Ejemplo |
(misma DATABASE_URL) |
Apunta a la BD de tests con credenciales de test. |
postgresql+asyncpg://usuario_test:[REDACTED]@localhost:5432/bd_test |
Seguridad y JWT
| Variable |
Campo (Settings) |
Descripción |
Ejemplo |
SECRET_KEY |
secret_key |
Clave de firma JWT. Obligatoria, mín. 32 caracteres; la app no arranca sin ella (validador validate_secret_key, todos los entornos). |
[REDACTED] (generar con openssl rand -hex 32) |
ALGORITHM |
algorithm |
Algoritmo de firma JWT. |
HS256 |
ACCESS_TOKEN_EXPIRE_MINUTES |
access_token_expire_minutes |
Expiración del access token, en minutos. |
10080 (7 días) |
CORS
| Variable |
Campo (Settings) |
Descripción |
Ejemplo |
CORS_ORIGINS |
cors_origins |
Lista de orígenes permitidos, en formato JSON. |
["https://tu-dominio.example","http://localhost:3000"] |
OAuth2 (Google y Apple)
Login separado por audiencia: cliente (customer) y administrador
(admin). Los *_CLIENT_SECRET vacíos desactivan ese proveedor.
| Variable |
Campo (Settings) |
Descripción |
Ejemplo |
GOOGLE_CUSTOMER_CLIENT_ID |
google_customer_client_id |
Client ID de Google (cliente). |
1234567890-abc.apps.googleusercontent.com |
GOOGLE_CUSTOMER_CLIENT_SECRET |
google_customer_client_secret |
Client secret de Google (cliente). |
[REDACTED] |
CUSTOMER_REDIRECT_URI |
customer_redirect_uri |
Redirect URI tras login de cliente. |
http://localhost:3000/auth/callback |
GOOGLE_ADMIN_CLIENT_ID |
google_admin_client_id |
Client ID de Google (admin). |
1234567890-abc.apps.googleusercontent.com |
GOOGLE_ADMIN_CLIENT_SECRET |
google_admin_client_secret |
Client secret de Google (admin). |
[REDACTED] |
ADMIN_REDIRECT_URI |
admin_redirect_uri |
Redirect URI tras login de admin. |
http://localhost:3000/admin/auth/callback |
APPLE_CUSTOMER_CLIENT_ID |
apple_customer_client_id |
Client ID de Apple (cliente). |
com.example.cliente |
APPLE_CUSTOMER_CLIENT_SECRET |
apple_customer_client_secret |
Client secret de Apple (cliente). |
[REDACTED] |
APPLE_ADMIN_CLIENT_ID |
apple_admin_client_id |
Client ID de Apple (admin). |
com.example.admin |
APPLE_ADMIN_CLIENT_SECRET |
apple_admin_client_secret |
Client secret de Apple (admin). |
[REDACTED] |
OAUTH_REDIRECT_URI_ALLOWLIST |
oauth_redirect_uri_allowlist |
Allowlist de redirect URIs separadas por coma (endurecimiento SEC03, RFC 6749 §10.6 / RFC 7636). Vacía = usa {customer_redirect_uri, admin_redirect_uri} (propiedad oauth_redirect_uri_allowlist_set). |
https://tu-dominio.example/auth/callback,https://tu-dominio.example/admin/auth/callback |
APPLE_JWKS_TIMEOUT_SECONDS |
apple_jwks_timeout_seconds |
Timeout de descarga del JWKS de Apple, en segundos. Acota socket y asyncio.wait_for; fallo fail-closed (500, no 401). |
5 |
IA (LLM vía NVIDIA NIM)
| Variable |
Campo (Settings) |
Descripción |
Ejemplo |
NVIDIA_API_KEY |
nvidia_api_key |
API key del proveedor LLM. Tiene prioridad sobre STEPFUN_API_KEY (propiedad ai_api_key). |
nvapi-[REDACTED] |
NVIDIA_MODEL |
nvidia_model |
Modelo de chat. |
stepfun-ai/step-3.5-flash |
NVIDIA_BASE_URL |
nvidia_base_url |
Base URL del proveedor (o del proxy local OpenAI-compatible). |
https://integrate.api.nvidia.com/v1 |
AI_STREAM_TIMEOUT_SECONDS |
ai_stream_timeout_seconds |
Segundos máximos esperando el primer frame del proveedor antes de emitir error estructurado. Por debajo del read-timeout httpx (120 s) para que dispare primero el use case (ERR02). |
60 |
MAX_AI_TOKENS_PER_SESSION |
max_ai_tokens_per_session |
Tope duro de tokens IA (prompt + completion) por sesión de mesa. 0 lo desactiva (AI01). |
200000 |
Alias heredados (compatibilidad; no usar en despliegues nuevos):
| Variable |
Campo (Settings) |
Descripción |
Ejemplo |
STEPFUN_API_KEY |
stepfun_api_key |
Alias heredado de la API key (solo si NVIDIA_API_KEY está vacía). |
[REDACTED] |
STEPFUN_MODEL |
stepfun_model |
Alias heredado del modelo. |
stepfun-ai/step-3.5-flash |
Solo servicio legacy (no es campo de Settings; la lee
backend/app/shared/infrastructure/nvidia_service.py):
| Variable |
Descripción |
Ejemplo |
NVIDIA_API_TIMEOUT |
Timeout HTTP (s) del cliente legacy hacia el proveedor. |
120.0 |
Embeddings y chat híbrido
El modelo alimenta el clasificador de intenciones y el recomendador basado en
contenido; carga perezosa en proceso.
| Variable |
Campo (Settings) |
Descripción |
Ejemplo |
EMBEDDINGS_ENABLED |
embeddings_enabled |
Activa el modelo en proceso. En tests/CI siempre false (evita descargar ~390 MB). |
true |
EMBEDDINGS_MODEL_NAME |
embeddings_model_name |
Modelo de embeddings. |
sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2 |
EMBEDDINGS_CACHE_DIR |
embeddings_cache_dir |
Caché del modelo (se exporta como HF_HOME antes de la primera carga; útil en volumen montado). |
/data/hf-cache |
Clasificador de intenciones:
| Variable |
Campo (Settings) |
Descripción |
Ejemplo |
INTENT_MIN_CONFIDENCE |
intent_min_confidence |
Umbral de similitud coseno bajo el que el mensaje va a la rama LLM de fallback. El min_confidence por árbol del JSON lo sobrescribe para el nodo classify. |
0.65 |
Resolutor semántico de productos (extracción de pedidos en el chat):
| Variable |
Campo (Settings) |
Descripción |
Ejemplo |
RESOLVER_ACCEPT_THRESHOLD |
resolver_accept_threshold |
El top-1 debe superarlo para ser candidato. |
0.50 |
RESOLVER_AMBIGUOUS_FLOOR |
resolver_ambiguous_floor |
Candidatos por encima compiten en desambiguación. |
0.45 |
RESOLVER_MARGIN |
resolver_margin |
Si top1 − top2 está por debajo → ambiguo (mostrar opciones) en vez de adivinar. |
0.06 |
Intérprete del árbol de decisiones:
| Variable |
Campo (Settings) |
Descripción |
Ejemplo |
INTERPRETER_MAX_STEPS |
interpreter_max_steps |
Tope de nodos recorridos por mensaje (anti-bucle). |
50 |
INTERPRETER_ACTION_TIMEOUT_SECONDS |
interpreter_action_timeout_seconds |
Timeout por acción, en segundos. |
5 |
POS (TPV)
| Variable |
Campo (Settings) |
Descripción |
Ejemplo |
POS_ADAPTER_TYPE |
pos_adapter_type |
Selector de adaptador TPV. local = LocalPOSAdapter interno (sin TPV externo); futuro hiopos = HioposPOSAdapter. |
local |
Impuestos
| Variable |
Campo (Settings) |
Descripción |
Ejemplo |
DEFAULT_TAX_RATE |
default_tax_rate |
Tasa de IVA por defecto (porcentaje entero). |
10 |
Rate limiting
| Variable |
Campo (Settings) |
Descripción |
Ejemplo |
REDIS_URL |
redis_url |
URL de Redis para el limiter (tiene prioridad). |
redis://localhost:6379/0 |
VALKEY_URL |
valkey_url |
URL de Valkey (alternativa si no hay REDIS_URL). |
valkey://localhost:6379/0 |
Sin ninguna URL, el limiter degrada a tabla Postgres (RATE01). La propiedad
rate_limiter_redis_url resuelve la efectiva.
Bootstrap (un solo uso, no es Settings)
La lee backend/app/core/bootstrap.py al arrancar; crea el primer superadmin
si no existe ninguno.
| Variable |
Descripción |
Ejemplo |
ADMIN_SUPER_EMAIL |
Email del superadmin a crear una sola vez. Eliminar del .env tras el primer arranque. |
admin@tu-dominio.example |
Frontend (NEXT_PUBLIC_*)
Las consume el frontend en build/runtime (lógica en
frontend/lib/config/api.ts); no son campos de Settings.
| Variable |
Descripción |
Ejemplo |
NEXT_PUBLIC_API_URL |
URL base de la API con el sufijo /api/v1. Si no se define, el frontend resuelve: dominio demo → API demo; otro despliegue → mismo origen + /api/v1; desarrollo → http://localhost:8000/api/v1. |
http://localhost:8000/api/v1 |
NEXT_PUBLIC_APP_URL |
URL pública de la app (metadata y OG images). |
http://localhost:3000 |
NEXT_PUBLIC_REPORT_ERRORS_IN_DEV |
Activa el reporte de errores en desarrollo (ver frontend/lib/errors/). |
false |
OPENAPI_SNAPSHOT |
(Solo script npm run codegen) Ruta del snapshot OpenAPI para regenerar tipos TS. Por defecto ../backend/tests/contract/openapi_snapshot.json. |
/ruta/a/otro/openapi.json |
Ejemplo mínimo de .env (backend, local)
DATABASE_URL=postgresql+asyncpg://camarero_user:camarero_password@localhost:5432/camarero_db
SECRET_KEY=[GENERA-CON-openssl-rand-hex-32]
DEBUG=false
NVIDIA_API_KEY=nvapi-[REDACTED]
NVIDIA_BASE_URL=https://integrate.api.nvidia.com/v1
NVIDIA_MODEL=stepfun-ai/step-3.5-flash
# CORS_ORIGINS=["https://tu-dominio.example","http://localhost:3000"]
# ADMIN_SUPER_EMAIL=admin@tu-dominio.example # solo primer arranque; borrar después
Páginas relacionadas