Despliegue¶
Guía para instalar y operar BeneficiosCenter en DINO/Tipre: primer arranque, servicio Windows,
observabilidad, rotación de secretos, backup y rollback. Fuente: docs/RUNBOOK.md del
repositorio del sistema.
Warning
Ningún valor de esta página es un secreto real. Las contraseñas y claves siempre viven en
backend/config/application.yml, fuera del repo, nunca en git.
Arquitectura de despliegue¶
Caddy termina TLS y expone el puerto 443; el jar habla HTTP plano solo en localhost. Dos
servicios Windows vía NSSM: BeneficiosCenter (la app) y caddy (el proxy).
0. Compilar el jar (backend + consola)¶
Un único jar sirve la API de administración/resolución (/api/**) y la consola (/gestor)
en el mismo puerto (ADR-001) — no hace falta levantar la consola por separado en producción.
vite.config.ts fija outDir: "../backend/src/main/resources/static/gestor": el build de la
consola cae directo dentro de los recursos del backend, sin paso de copia manual. Después:
mvn package empaqueta ese static/gestor/ ya compilado dentro del jar
(target/beneficioscenter-backend-<version>.jar, <version> = 0.0.1-SNAPSHOT al momento de
escribir esto, ver backend/pom.xml). El resultado es el único artefacto que se despliega — el
mismo jar de los pasos 3 y 4 más abajo.
Los dos puertos son solo para desarrollo
En desarrollo, npm run dev levanta Vite en el puerto 5174 (con proxy de /api hacia el
backend en 8080) para tener hot-reload de la consola. En producción no existe ese segundo
puerto: el jar único de arriba responde /api/** y /gestor en el mismo puerto (8080 por
defecto, detrás de Caddy — ver arquitectura arriba).
1. Prerrequisitos¶
- JDK 21 (Temurin recomendado, ADR-001).
- SQL Server 2022, con una base dedicada:
Recomendado: un login propio de la aplicación (no sa) con permisos solo sobre esa base
(db_datareader, db_datawriter, db_ddladmin — Flyway necesita crear/alterar tablas).
- NSSM (nssm.cc) para correr la app y Caddy como servicio Windows.
- Caddy (caddyserver.com/download).
- DNS A del dominio elegido apuntando a la IP del servidor.
- Firewall de Windows: permitir 443/tcp entrante; no exponer el 8080 hacia afuera.
2. Configuración externa¶
Copiar la plantilla y completarla:
Ver el detalle de cada clave en Configuración.
3. Primer arranque¶
Flyway aplica el esquema; con la tabla usuario vacía, siembra el admin de bc.admin.*. Un
segundo arranque no duplica ni resetea ese usuario (AC-23).
Verificar:
Debe responder {"status":"UP"}. Después, cargar el catálogo base — ver
Sembrar datos.
4. Servicio Windows (NSSM) + Caddy¶
4.1 BeneficiosCenter como servicio¶
nssm install BeneficiosCenter "C:\Program Files\Eclipse Adoptium\jdk-21\bin\java.exe" "-jar C:\work\beneficioscenter\beneficioscenter-backend-<version>.jar"
nssm set BeneficiosCenter AppDirectory C:\work\beneficioscenter
nssm set BeneficiosCenter AppStdout C:\work\beneficioscenter\logs\service-out.log
nssm set BeneficiosCenter AppStderr C:\work\beneficioscenter\logs\service-err.log
nssm set BeneficiosCenter Start SERVICE_AUTO_START
nssm start BeneficiosCenter
AppDirectory es crítico
config/application.yml se busca relativo a él (INV-O04). Probar primero a mano
(java -jar ... desde esa carpeta) y recién después instalar el servicio.
4.2 Caddy (TLS 443 → app 8080)¶
Caddyfile (junto a caddy.exe):
{
email admin@tipre.com
storage file_system {
root C:\work\caddy\data
}
}
beneficioscenter.dino.example {
reverse_proxy 127.0.0.1:8080 {
header_up X-Forwarded-For {remote_host}
}
}
nssm install caddy "C:\work\caddy\caddy.exe" "run --config C:\work\caddy\Caddyfile"
nssm set caddy AppDirectory C:\work\caddy
nssm set caddy Start SERVICE_AUTO_START
nssm start caddy
5. Salud y métricas¶
| URL | Auth | Qué muestra |
|---|---|---|
GET /actuator/health |
pública | {"status":"UP"} — healthcheck del servicio |
GET /actuator/prometheus |
ADMIN (Basic) |
Métricas Micrometer en formato Prometheus |
Métricas clave:
resolver.latencia— histograma completo con buckets SLO en 5/10/20/50 ms. El p99 se deriva conhistogram_quantile(0.99, sum(rate(resolver_latencia_seconds_bucket[5m])) by (le)). Alerta sugerida: ese p99 > 0.020 durante 5 minutos.auditoria.encoladas/auditoria.perdidas— cuánto se encola y cuánto se pierde por cola llena (nunca bloquea la respuesta al gateway).configuracion.version— versión del snapshot activo.configuracion.refresh.fallos/configuracion.ultimo_refresh_epoch— si el refresco periódico del snapshot falla contra la base, el snapshot anterior se sigue sirviendo sin cortar al gateway.
Reglas de alerta cargables en Prometheus: docs/ops/alerts-prometheus.yml del repositorio del
sistema.
6. Logs¶
Archivo: logs/beneficioscenter.log, relativo al directorio de trabajo. Nunca contiene
secretos (INV-S03). Rotación por defecto de Spring Boot (Logback): hasta 10 MB, 7 días de
historial.
Un error inesperado del resolver queda en ERROR con el stack trace completo; en producción el
logger corre a INFO, así que ese ERROR es la única fuente para diagnosticar sin reiniciar en
otro nivel. Cualquier secreto embebido en un mensaje de excepción se enmascara como *** antes
de escribirse.
7. Rotar la API key del gateway¶
La bc.gateway.api-key se lee una sola vez al arrancar. Rotarla implica una ventana de
reinicio corta:
- Generar una clave nueva:
openssl rand -hex 24. - Coordinar con el equipo del GatewayQR el cambio simultáneo.
- Editar
bc.gateway.api-keyenconfig/application.yml. nssm restart BeneficiosCenter.- Confirmar con el simulador del gateway que la clave nueva funciona.
Durante el reinicio el gateway sigue operando sin beneficios (nunca frena cobros).
8. Backup de la base¶
BACKUP DATABASE beneficioscenter
TO DISK = 'D:\backups\beneficioscenter\beneficioscenter_$(Get-Date -Format yyyyMMdd_HHmm).bak'
WITH COMPRESSION, CHECKSUM;
Retener al menos los últimos 14 días. La restauración es la operación estándar de SQL Server; no requiere pasos especiales porque las migraciones son aditivas.
Retención y purga de auditoría¶
PurgaAuditoriaJob borra cada semana (bc.auditoria.purga-cron, por defecto domingos 03:30),
en lotes, las filas de consulta (arrastrando consulta_beneficio por cascada) y de
resultado_pago anteriores a bc.auditoria.retencion-dias (por defecto 365 días) — nunca las
que están dentro del período vigente (AC-67). resultado_pago no tiene cascada: se purga en
forma independiente, con el mismo batcheo y el mismo criterio de "nunca dentro del período". La
métrica auditoria.purgadas acumula el total borrado de ambas tablas. La purga es destructiva
por diseño.
Antes de bajar bc.auditoria.retencion-dias, exportar el rango que va a quedar fuera de la
nueva ventana:
curl.exe -u admin:<clave-admin> -o consultas-archivo.csv \
"http://localhost:8080/api/admin/consultas/export?desde=<fecha-desde>&hasta=<fecha-hasta>"
El rango de exportación está limitado a 90 días; para archivar una ventana más larga, exportar en varios pedidos consecutivos antes de aplicar el nuevo valor de retención.
Este export solo cubre consulta (y por join, consulta_beneficio) — no existe un endpoint
equivalente para resultado_pago, que la misma purga borra sin dejar un archivo previo.
9. Cambios de configuración de negocio (sin reinicio)¶
Guardar un beneficio, tipo de cliente o sucursal desde la consola actualiza el snapshot en memoria en la próxima consulta, sin reiniciar el proceso. Ante duda, forzar la recarga:
10. Rollback y actualización de versión¶
Mismo procedimiento para volver a una versión anterior (rollback) o pasar a una más nueva (actualización de rutina) — solo cambia de qué jar viene el reemplazo:
nssm stop BeneficiosCenter.- Reemplazar el jar actual por el jar de destino (versión anterior para rollback, nueva versión
para actualizar) en la misma carpeta (
AppDirectory), con el mismo nombre de archivo o ajustando elAppParametersde NSSM si el nombre cambia. nssm start BeneficiosCenter.
Las migraciones Flyway son aditivas: no hace falta revertir esquema. Ni un rollback ni una actualización frenan cobros — si el gateway ve timeouts durante la ventana de reinicio, sigue sin aplicar beneficios por diseño.
11. Checklist de humo (10 pasos)¶
Correr después de cada despliegue. Requiere el jar corriendo y accesible en --base-url.
- Salud del proceso —
curl.exe http://localhost:8080/actuator/health→{"status":"UP"}. - Métricas expuestas —
curl.exe -u admin:<clave-admin> .../actuator/prometheus | findstr resolver. - Sembrar catálogo y beneficios de ejemplo — ver Sembrar datos.
- Confirmar idempotencia — correr el mismo comando de nuevo; cada línea usa
=. - Simular el gateway — request de ejemplo — ver Simulador del gateway;
benefitsno vacío. - Monto menor al mínimo — escenario 2:
benefits: []. - Sucursal desconocida — escenario 3: solo aplican beneficios sin restricción.
- API key inválida — escenario 4:
HTTP 401. - Consola accesible —
curl.exe -s -D - -o NUL http://localhost:8080/gestor/→200y cabeceras de seguridad presentes. Usar GET, no HEAD. - Auditoría registrada — en la consola, Auditoría → filtrar por hoy; aparecen las consultas de los pasos 5 a 8.
Si algún paso falla: revisar logs/beneficioscenter.log antes de escalar.
12. Sin variables de entorno: toda la configuración vive en application.yml¶
BeneficiosCenter no necesita ni espera variables de entorno para arrancar: toda la
configuración operativa (§2) vive en el config/application.yml externo (INV-O04). No hay una
lista de ENV_VAR que setear en el servicio — solo ese archivo.
Para no repetir un mismo valor dos veces dentro del propio application.yml, hay dos formas
válidas (YAML estándar, no algo propio de BeneficiosCenter):
Property placeholders (${...}, referenciando otra clave del mismo archivo) — el propio
application.yml embebido en el jar ya usa este mecanismo:
YAML anchors (&nombre / *nombre) — útiles para no repetir un mismo valor completo en más
de un lugar del archivo. Ejemplo ilustrativo (no son claves reales de BeneficiosCenter, solo
muestran la sintaxis):
Ambos son mecanismos de YAML/Spring Boot estándar, no una convención propia de este proyecto — usar el que sea más cómodo para el caso.
Si nssm necesita setear alguna variable de entorno igual (por ejemplo, para una herramienta de
terceros que sí las lea), AppEnvironmentExtra la agrega al proceso del servicio — pero eso es
opcional, nunca un requisito de BeneficiosCenter:
13. BootUI: consola de desarrollo embebida¶
BootUI (com.julien-dubois.bootui) es una consola de desarrollo embebida en el mismo jar,
accesible en /bootui sin login (cadena permitAll). Da advisors de Architecture, Hibernate,
REST API, Security, etc. con scanners que puntúan el proyecto.
Es opt-in por configuración externa y viene apagada/dormida en producción: se activa con
bootui.enabled en el application.yml externo (ver Configuración).
No activar en producción
Como no tiene login y expone internals del sistema, bootui.enabled debe quedar apagado
(o ausente) en cualquier servidor productivo o expuesto a internet. Activarlo solo en
entornos de desarrollo o diagnóstico.
Dónde sigue¶
- Sembrar el catálogo base, en Sembrar datos.
- Probar el contrato del gateway sin el gateway real, en Simulador del gateway.
- Reutilizar el mismo jar para otro cliente, en Marca blanca.
- Validar la latencia bajo carga sostenida, en Prueba de carga.