Saltar a contenido

Configuración

Toda la configuración operativa del backend vive fuera del jar, en un application.yml junto al ejecutable. Esta página documenta cada variable/clave real, de dónde sale y qué pasa si falta. Para el detalle del proceso de arranque que la exige, ver Backend → cómo arranca. Para el despliegue paso a paso, ver Instalar en el servidor.

Config externa al jar y fail-fast

Decisión explícita del operador: "el yaml de configuración por completo tiene que estar fuera del .jar, nada de sorpresas con yaml adentro del big fat jar". El jar empaquetado no contiene ningún application*.yml/application*.properties — Spring Boot busca ./config/ relativo al directorio de trabajo del proceso, sin ningún loader custom.

C:\work\sistemapremios\
├── sistemapremios-backend-0.0.1-SNAPSHOT.jar
├── config\
│   └── application.yml      ← toda la config real vive acá
├── bases\
├── branding\
│   └── logo.png
└── logs\

El repo versiona backend/config/application.yml como referencia documentada — resuelve dev y CI sin fricción (ambos corren con working directory backend/), y nunca contiene un valor secreto: los ${SP_*} quedan sin resolver hasta que el entorno real los provee.

Sin config/application.yml, el proceso no arranca — a propósito

Un EnvironmentPostProcessor (ConfigExternaEnvironmentPostProcessor) corre antes que cualquier bean y exige:

  1. La propiedad centinela sp.config.externa: true — solo existe en el archivo externo, nunca embebida. Si falta, la excepción nombra el archivo esperado, el working directory real del proceso y sugiere --spring.config.additional-location=file:<ruta>/config/ si no se puede controlar el working directory.
  2. Dos claves de contrato del código, con su valor exacto: spring.jackson.property-naming-strategy: SNAKE_CASE (si falta, toda la API cambia de formato y la landing/gestor rompen en silencio) y spring.jpa.hibernate.ddl-auto: validate (si falta, Hibernate podría alterar el esquema en vez de solo validarlo contra Flyway).

Nunca arranca con defaults embebidos. Mejor no arrancar que arrancar distinto a lo esperado. Detalle completo de la decisión en ADR-029.

AppDirectory / working directory es crítico en Windows Service

Spring busca ./config/ relativo al working directory del proceso, no a la ubicación del jar. Con NSSM, esto significa que AppDirectory tiene que apuntar a la carpeta que contiene config/ — un desajuste típico de "Start in" deja el servicio sin encontrar la config aunque el jar esté en la ruta correcta.

Variables de entorno

Variable Default Obligatoria Para qué
SP_DB_URL jdbc:sqlserver://localhost;databaseName=SistemaPremios;encrypt=false No URL JDBC de SQL Server
SP_DB_USER sa No Usuario de la base
SP_DB_PASSWORD — (fallback a SP_DB_PASS) , en la práctica Password de la base. SP_DB_PASS es el nombre viejo, obsoleto — sigue funcionando de fallback pero loguea un WARN
SP_MASTER_KEY Base64 de 32 bytes (AES-256) para cifrar/descifrar el secreto HMAC de la clave de firma. Sin ella, el arranque falla con un mensaje explícito. Debe ser la misma clave usada al sembrar los datos, o los QR emitidos antes no vuelven a validar
SP_GESTOR_USER admin No Usuario de login del gestor
SP_GESTOR_PASSWORD — (fallback a SP_GESTOR_PASS) Password del gestor. Sin ella, el arranque falla rápido — no hay camino de "arrancar igual y avisar" (la versión anterior generaba y logueaba una password aleatoria; eso viola la regla de secretos nunca en logs)
SP_CLIENTE_NOMBRE Cliente No Nombre del cliente mostrado en landing/gestor (branding multi-cliente)
SP_CLIENTE_COLOR #E01020 No Color primario de marca, formato #RRGGBB estricto — un valor inválido hace fallar el arranque
SP_BRANDING_DIR ./branding No Carpeta donde vive logo.png del cliente
SP_BASES_DIR No Carpeta de las bases legales versionadas de la campaña (PDF subido desde el gestor)
SP_MODO_PRUEBA false No Habilita el generador de vouchers de prueba. Ver guarda de prod más abajo
SP_BASE_URL http://localhost:8080 , en producción URL pública que se embebe dentro del contenido del QR. Si queda en localhost, los QR generados apuntan a localhost y no sirven fuera de esa máquina

Las tres que muerden si las salteás

SP_GESTOR_PASSWORD (login del gestor — sin ella no arranca) · SP_BASE_URL (si queda en localhost, los QR apuntan a localhost) · SP_MASTER_KEY (debe ser la misma que se usó al sembrar los datos, o los QR no validan).

Claves de config (sp.*)

Estas viven en application.yml, no como variable de entorno directa (aunque casi todas se resuelven a partir de las de arriba vía ${SP_*:default}):

Clave Default Para qué
sp.config.externa Centinela obligatorio, ver arriba. No borrar.
sp.cliente.nombre ${SP_CLIENTE_NOMBRE:Cliente} Branding
sp.cliente.color-primario ${SP_CLIENTE_COLOR:#E01020} Branding, validado #RRGGBB
sp.branding.dir ${SP_BRANDING_DIR:./branding} Carpeta del logo
sp.modo-prueba.enabled ${SP_MODO_PRUEBA:false} Ver Backend → modo prueba
sp.base-url ${SP_BASE_URL:http://localhost:8080} Base pública embebida en el QR
sp.reconocimiento.habilitado true Perilla de privacidad por cliente para el reconocimiento de dispositivo — en false, la landing pide siempre el DNI
sp.rate-limit.enabled true Ver Backend → rate limiting
sp.rate-limit.limite 30 Requests por ventana
sp.rate-limit.ventana-ms 60000 Tamaño de la ventana (ms)
sp.rate-limit.cap-entradas 10000 Tope de IPs trackeadas antes de purgar
sp.seed.archivo Ver Backend → seed inicial. Sin esta property, SeedMinimo ni se registra como bean

Cambiar un flag operativo no reempaqueta nada

Por ejemplo, apagar el reconocimiento de dispositivo para un cliente puntual es editar sp.reconocimiento.habilitado: false en config/application.yml y reiniciar el servicio — sin tocar código ni volver a buildear el jar. Es el objetivo completo de ADR-029.

Perfiles

Perfil Uso
(sin perfil) / dev, local Desarrollo. bootui (consola de desarrollo) se activa sola en AUTO; modo prueba puede estar prendido sin problema
e2e Suite end-to-end (Playwright contra el jar empaquetado). Config propia en backend/config/application-e2e.properties
load Pruebas de carga. Config propia en backend/config/application-load.properties
prod Producción — ver guarda de abajo

prod mata el modo prueba — no se pueden combinar

ModoPruebaConfig corre al arranque: si sp.modo-prueba.enabled=true y el perfil activo contiene prod, el contexto no levanta. Es intencional — modo prueba nunca debe existir en el ambiente real. La consecuencia práctica, documentada en el runbook de despliegue: si necesitás generar QR de prueba en el servidor de producción real (para el smoke inicial), corrés sin spring.profiles.active=prod — lo que también significa que bootui no queda bloqueado por código en ese momento. La mitigación es de infraestructura: un reverse proxy (Caddy) devuelve 404 en /bootui y /bootui/* de entrada, para que la consola de desarrollo nunca quede expuesta públicamente aunque el proceso la tenga activa.

Ejemplo completo

Este es el config/application.yml real de un despliegue (basado en el runbook de instalación), con los valores a completar marcados:

sp.config.externa: true          # centinela ADR-029 — NO borrar

SP_DB_PASSWORD: "CAMBIAR"
SP_MASTER_KEY: "CAMBIAR"         # base64 32 bytes — el MISMO usado al seed
SP_GESTOR_USER: "admin"
SP_GESTOR_PASSWORD: "CAMBIAR"    # obligatoria: sin esto no arranca
SP_CLIENTE_NOMBRE: "Supermercados Caracol"
SP_CLIENTE_COLOR: "#e30613"
SP_BRANDING_DIR: "C:/work/sistemapremios/branding"
SP_MODO_PRUEBA: "true"           # NO usar junto con perfil prod
SP_BASE_URL: "https://sistemapremios.tipre.com"   # URL pública real, nunca localhost

management:
  endpoints:
    web:
      exposure:
        include: health
  endpoint:
    health:
      show-details: when-authorized

server:
  address: 127.0.0.1              # solo localhost — el reverse proxy es quien queda expuesto
  port: 28880
  forward-headers-strategy: framework
  tomcat:
    allow-trace: false
  compression:
    enabled: true
    mime-types: text/html,text/css,application/javascript,text/javascript,application/json
    min-response-size: 1024

spring:
  application:
    name: sistemapremios-backend
  datasource:
    url: ${SP_DB_URL:jdbc:sqlserver://localhost;databaseName=SistemaPremios;encrypt=false}
    username: ${SP_DB_USER:sa}
    password: ${SP_DB_PASSWORD:${SP_DB_PASS:}}
  jpa:
    hibernate:
      ddl-auto: validate
    open-in-view: false
    properties:
      hibernate:
        jdbc:
          time_zone: America/Argentina/Buenos_Aires
        query:
          in_clause_parameter_padding: true
  flyway:
    enabled: true
  jackson:
    property-naming-strategy: SNAKE_CASE
  servlet:
    multipart:
      max-file-size: 10MB
      max-request-size: 10MB

sp:
  cliente:
    nombre: ${SP_CLIENTE_NOMBRE:Cliente}
    color-primario: ${SP_CLIENTE_COLOR:#E01020}
  branding:
    dir: ${SP_BRANDING_DIR:./branding}
  modo-prueba:
    enabled: ${SP_MODO_PRUEBA:false}
  base-url: ${SP_BASE_URL:http://localhost:8080}
  reconocimiento:
    habilitado: true

Este archivo no contiene secretos reales

El application.yml versionado en el repo (backend/config/application.yml) es la referencia sin valores reales — los ${SP_*} quedan sin resolver. Los valores reales van en la carpeta de deploy, fuera de git. Detalle del despliegue completo (NSSM, Caddy, TLS) en Instalar en el servidor.