Cotización del dólar — Guía del gestor
Cómo usar el back-office que fija la cotización del dólar billete para las cajas y las pantallas de las sucursales de Supermercados Becerra. Está pensada para quienes lo operan día a día: el Administrador y el Cotizador (y el Auditor, que solo consulta).
Las secciones 1 a 9 son para operadores. Las secciones 10 a 17 son técnicas (instalación y configuración del servidor) y están marcadas como tales. Los textos de la interfaz se citan tal como aparecen en pantalla.
1Qué es el sistema
El sistema guarda la cotización del dólar billete de cada región y se la entrega a dos destinatarios: a las cajas del POS, que la piden a un servicio llamado Pizarra cada vez que un cliente paga con el medio de pago 9/10 DOLAR, y a la pantalla (TV) de cada sucursal, que la muestra a los clientes. Usted carga los valores en el back-office (el “gestor”); cada carga queda registrada con quién, cuándo y de cuánto a cuánto.
Lo esencial en 30 segundos
- Cada sucursal pertenece a una región, y la cotización se fija por región y medio de pago.
- Para cambiar el precio, el Cotizador entra en Cotizaciones → Nueva cotización, elige región y medio de pago y carga el valor (ver sección 4).
- Las cajas y las pantallas toman el valor nuevo enseguida (o desde la fecha programada). Para comprobar qué recibe una caja, el Administrador usa Sucursales → Probar consulta (5.5).
Solo maneja dólar billete, con 2 decimales. No maneja tarjetas en dólares ni otras monedas, y no factura en dólares. Las Referencias (BCRA, CriptoYa, DolarAPI) que se ven en pantalla son solo informativas: nunca se usan para calcular nada.
Glosario
| Término | Significado |
|---|---|
| Región | Agrupa sucursales que cobran el dólar al mismo valor. La cotización se carga por región. |
| Sucursal | Un local, identificado por su número (el mismo que usan las cajas). Siempre pertenece a una región. |
| Medio de pago | Par de números Id / sub-id que envía la caja. El dólar billete es 9/10 DOLAR. |
| Cotización / versión | Cada carga es una versión nueva: un valor (o una suspensión) con una fecha y hora “desde”. Las versiones no se borran ni se editan; una versión futura se puede anular. |
| Vigente | La versión que rige ahora: la última cuya fecha “desde” ya llegó y no está anulada. |
| Programada | Una versión con fecha “desde” futura. Entra en vigencia sola a esa hora. |
| Suspensión | Versión sin valor: mientras rige, la caja recibe “Cotización suspendida” y no puede cobrar en dólares. |
| Pizarra | El servicio al que consultan las cajas del POS para saber el valor del dólar. |
| transactionId | Número único que la Pizarra asigna a cada consulta de una caja. Queda en la auditoría de consultas. |
| Pantalla de la sucursal | Página que muestra la TV del local (modo kiosco), con el valor vigente de su región. Se habilita con un enlace de pantalla propio de cada sucursal. |
| Referencias | Valores del dólar de BCRA (divisa), CriptoYa (billete BNA) y DolarAPI (billete oficial), a modo de consulta. Solo informativas. |
| Umbral de confirmación | Porcentaje (10 % por defecto) por encima del cual un cambio de valor exige un motivo. |
2Ingreso, contraseña y roles
2.1 Ingresar
- Abra en el navegador la dirección del back-office que le dio TI.
- Escriba su Usuario y Contraseña y pulse Ingresar. Si alguno de los dos es incorrecto, el mensaje no dice cuál (es a propósito).
- Al entrar se abre Cotizaciones vigentes.
Por seguridad, la sesión vive solo en la pestaña abierta: si recarga la página (F5), la cierra o abre el back-office en otra pestaña, tendrá que ingresar de nuevo. Use los enlaces del menú para moverse.
2.2 Primer ingreso y contraseña de un solo uso
Cuando el Administrador le crea el usuario o le restablece la contraseña, usted recibe una contraseña de un solo uso. Al ingresar con ella, el sistema le pide cambiarla antes de hacer cualquier otra cosa.
Complete Contraseña actual (la de un solo uso), Contraseña nueva y Repita la contraseña nueva. Reglas que muestra la pantalla: al menos 8 caracteres, y no puede ser la que recibió al principio ni su nombre de usuario.
2.3 Cambiar su contraseña cuando quiera
En el pie del menú lateral, pulse Cambiar mi contraseña. Es la misma pantalla de arriba, sin el aviso. Cualquier usuario puede cambiar la suya; el cambio queda en la auditoría (sin los valores).
¿Olvidó la contraseña? No hay recuperación por correo: pídale a un Administrador que use Restablecer contraseña (8.1).
2.4 Roles: qué puede hacer cada uno
| Rol | Puede | No puede |
|---|---|---|
| Administrador | Regiones, sucursales, medios de pago, enlaces de pantalla, Probar consulta, usuarios y umbral. Ver cotizaciones, historial y auditoría. | Cargar cotizaciones (salvo que también sea Cotizador). |
| Cotizador | Cargar cotizaciones (valor o suspensión, inmediatas o programadas) y anular las programadas. Ver vigentes, historial y auditoría. | Tocar regiones, sucursales, medios de pago o usuarios. |
| Auditor | Solo mirar: vigentes, historial, auditoría de cambios, consultas del POS y alertas. | Cambiar nada (salvo su propia contraseña). |
- Un usuario puede tener Administrador y Cotizador a la vez (así Becerra puede operar con un solo usuario). El administrador inicial tiene los dos.
- El Auditor no se combina con ningún otro rol.
- El menú muestra solo lo que sus roles permiten; además, el servidor vuelve a controlar cada operación.
4Cotizaciones
4.1 Cotizaciones vigentes
Muestra, para cada región × medio de pago, el valor Vigente, Desde cuándo rige y la Próxima programada (si la hay). Sin cotización significa que las cajas de esa región reciben “No se encontró la cotización” para ese medio de pago. Arriba de la tabla figura la Hora del servidor (hora de Argentina): es la que cuenta para decidir qué está vigente, no la de su computadora. La captura está en la sección 3.
La franja Referencias (solo informativo) muestra el dólar vendedor de tres fuentes, cada una con su fecha: BCRA divisa, CriptoYa billete BNA y DolarAPI billete oficial. Que la divisa y el billete difieran es esperable. Si una fuente falla, esa fila dice “no disponible” y las otras se siguen viendo. Estos valores nunca se usan en la Pizarra, en las pantallas ni en ningún cálculo: el precio lo carga siempre una persona.
4.2 Nueva cotización (Cotizador)
- Entre en Cotizaciones → Nueva cotización.
- Elija la Región y el Medio de pago (normalmente
DOLAR (9/10)). - En Qué se carga deje Fijar un valor y escriba el Valor (ver formatos abajo). Debajo verá el valor vigente y el umbral.
- En Vigencia elija Inmediata o Programada (con fecha y hora de Argentina).
- Si aparece el campo Motivo, complételo (ver confirmación reforzada).
- Pulse Cargar cotización (o Confirmar y cargar si se pidió motivo).
Cómo escribir el valor
| Escriba | Se carga | Nota |
|---|---|---|
| 1520,50 | $ 1.520,50 | Coma decimal. |
| 1520.50 | $ 1.520,50 | Punto decimal (1 o 2 dígitos después del punto). |
| 1.520,50 | $ 1.520,50 | Punto de miles y coma decimal. |
| 1.520 | $ 1.520,00 | Un punto seguido de 3 dígitos se lee como miles. |
| 1520,505 · 1.52.0 · 0 | — | Se rechaza: Ingrese un valor mayor que 0 con hasta 2 decimales. |
Confirmación reforzada: cuándo se pide un motivo
El campo Motivo aparece, y es obligatorio, en dos casos:
- Primera carga (no hay valor vigente para comparar) o la vigente es una suspensión.
- El valor nuevo se aparta más del umbral (10 % por defecto) del valor vigente ahora — también si la nueva es programada.
La versión cargada con motivo queda marcada como Desvío reforzado en el historial y en la auditoría. El servidor vuelve a controlar la regla aunque la pantalla no la hubiera detectado.
El mensaje de éxito dice qué pasa con las cajas:
| Mensaje | Qué significa |
|---|---|
| La Pizarra ya la sirve. | Inmediata: la próxima consulta de una caja recibe el valor nuevo. |
| La Pizarra ya la tiene cargada y la servirá desde la fecha indicada. | Programada: entra en vigencia sola a esa hora. |
| La Pizarra la tomará en el próximo refresco, normalmente dentro de 60 segundos. | Se guardó, pero la Pizarra la toma en su próximo refresco. No hace falta volver a cargarla. |
Vigencia programada
- La fecha y hora no pueden ser anteriores a la hora del servidor: una carga “hacia atrás” se rechaza.
- No puede haber dos versiones activas con la misma región, medio de pago y fecha “desde”; el error indica el valor existente y quién lo cargó.
- Mientras no llegue su hora, la versión figura como Próxima programada en Cotizaciones vigentes y se puede anular desde el historial.
Suspensión
Elija Suspensión en Qué se carga (no se pide valor). Desde que rige, las cajas de esa región reciben “Cotización suspendida” y no pueden cobrar en dólares con ese medio de pago, y la pantalla de la sucursal no muestra valor. Para volver a operar, cargue un valor nuevo (se pedirá motivo, porque no hay valor vigente con el cual comparar).
4.3 Historial y anulación
En Cotizaciones → Historial elija región y medio de pago para ver todas sus versiones: Rige desde, Valor, Cargada (quién y cuándo), Motivo y Estado.
Para anular una versión futura (solo el Cotizador): pulse Anular en su fila, escriba el Motivo de la anulación y pulse Confirmar anulación. Una versión ya vigente o pasada no se puede anular: para corregir un valor que ya rige, cargue una versión nueva inmediata.
5Sucursales (Administrador)
El grupo Sucursales define dónde se aplica cada cotización. El orden natural de alta es: región → sucursal → medio de pago (si falta) → cotización → enlace de pantalla → probar consulta.
5.1 Regiones
Una región inactiva deja a todas sus sucursales sin cotización: las cajas reciben “No se encontró la cotización”.
5.2 Sucursales
- El Número de sucursal es único y debe ser el mismo número que envían las cajas de ese local. Si no coincide, la Pizarra no la reconoce (aparece en Alertas como sucursal desconocida).
- La Región es obligatoria: define qué cotización recibe.
- Una sucursal deshabilitada recibe “No se encontró la cotización”.
- La columna Pantalla dice Configurada o Sin configurar según la sucursal tenga un enlace de pantalla.
5.3 Medios de pago
9/10 DOLAR. (La fila FIXTURE AC-16 es un dato de prueba del ambiente de las capturas.)Cada medio tiene Id del medio de pago, Id del sub-medio (los números que envía la caja), Nombre y Habilitado. Los Ids no se pueden cambiar después del alta. Un medio deshabilitado hace que las cajas reciban “No se encontró la cotización” para él.
5.4 Enlace de pantalla (la TV de la sucursal)
Cada TV muestra la cotización mediante un enlace propio de su sucursal. El enlace se genera desde el back-office y se muestra una sola vez.
- En Sucursales → Sucursales, pulse Enlace de pantalla en la fila de la sucursal.
- Si la sucursal ya tenía un enlace, el sistema pide confirmar: “Se va a generar un enlace nuevo… El enlace anterior deja de funcionar”. Pulse Generar nuevo enlace (o Cancelar). Si no tenía, se genera directamente.
- Aparece el panel URL de la pantalla de la sucursal N. Pulse Copiar.
- Abra ese enlace en el navegador de la TV, en pantalla completa (F11 o el modo kiosco del navegador). No lo abra en su propia computadora.
- Pulse Cerrar. El enlace ya no se puede volver a ver; si lo pierde, genere uno nuevo.
#t=) está tapada; en su pantalla se ve completa.- Quien tenga el enlace puede ver la pantalla de esa sucursal. No lo envíe por canales abiertos ni lo pegue en documentos.
- Generar un enlace nuevo anula el anterior: la TV que usaba el viejo pasa a mostrar “Cotización no disponible” hasta que se le cargue el nuevo.
- Si el panel avisa que el token nuevo empieza a funcionar en el próximo refresco exitoso de la Pizarra, normalmente dentro de 60 segundos, espere ese minuto: la TV se recupera sola en su siguiente refresco.
5.5 Probar consulta
Muestra exactamente lo que la Pizarra le respondería ahora a una caja para una sucursal y un medio de pago. Úsela después de cargar o cambiar algo, o cuando una caja “no toma el dólar”.
- En Sucursales → Probar consulta, elija la Sucursal (BranchNumber) de la lista. Para un número que no está en la lista (por ejemplo, el que envía una caja mal configurada), elija Otro número… y escríbalo en Número de sucursal.
- Elija el Medio de pago y pulse Probar.
HTTP 200, currentPrice con el valor y Hay una cotización vigente.
HTTP 404, No se encontró la cotización y el motivo real: Sin versión vigente.| Dato | Qué es |
|---|---|
| HTTP | 200 = la caja recibe un valor; 404 = la caja no puede cobrar en dólares. |
| currentPrice | El valor que recibiría la caja ($ 0,00 cuando no hay). |
| priceId (versión) | El número de la versión que se serviría. |
| message / error | El texto y el indicador de error que ve la caja. |
| Motivo | La causa real (la caja no la ve): ver la tabla de resultados en la sección 7.2. |
| transactionId | Siempre (prueba, sin transactionId): la prueba no consume un número de transacción. |
Debajo figura la Respuesta exacta que recibiría el POS. La prueba no se registra como consulta del POS, pero sí queda en la Auditoría de cambios como “Prueba de consulta”, con usuario, fecha, sucursal, medio de pago y resultado.
6Pantalla de la sucursal
Es lo que ven los clientes en la TV del local: el logo de Becerra, el nombre de la sucursal y, por cada medio de pago con valor, la cotización vigente de su región y desde cuándo rige.
- Se actualiza sola cada 30 segundos: un cambio de cotización aparece en la TV en menos de medio minuto, sin tocar nada.
- Muestra solo la marca del cliente, con letra grande para leerse a distancia. Las Referencias nunca aparecen aquí.
- El navegador de la TV guarda el enlace: si la TV se reinicia, basta con abrir la dirección
/pantalla/<número de sucursal>(sin la parte secreta). Solo hay que cargar el enlace completo otra vez si se borran los datos del navegador o si se genera un enlace nuevo. - Por eso no conviene abrir el enlace en otra computadora para probarlo: quedaría guardado allí, y con más de 10 intentos fallidos por minuto desde una misma dirección la pantalla se bloquea temporalmente. Para comprobar el valor use Probar consulta.
“Cotización no disponible”
La pantalla nunca muestra un valor viejo: ante cualquier problema muestra “Cotización no disponible” y vuelve a intentar a los 30 segundos. Causas habituales: la región no tiene valor vigente (o está suspendida), se generó un enlace nuevo y la TV todavía tiene el anterior, la sucursal está deshabilitada o la TV perdió la red. Ver Preguntas frecuentes.
7Auditoría
7.1 Auditoría de cambios
Registra todo cambio hecho en el back-office: quién, cuándo, sobre qué y el valor anterior y nuevo. Se puede filtrar por Entidad (Región, Sucursal, Medio de pago, Cotización, Usuario, Configuración, Prueba de consulta), Id de la entidad y período (Desde/Hasta, hora de Argentina).
cot-fixture y pantalla-fixture son de pruebas automáticas del ambiente de las capturas.Ver detalle despliega el valor anterior y el nuevo completos; Ocultar detalle lo cierra. Las contraseñas y los enlaces de pantalla nunca se guardan: solo figura que cambiaron (Token de pantalla: cambiado).
7.2 Consultas del POS
Cada vez que una caja consulta la Pizarra queda una fila. Filtros: Sucursal, Desde/Hasta, Id de transacción y Resultado. La tabla guarda todas las consultas: combine el resultado con un período o una sucursal para que la búsqueda sea rápida.
| Columna | Qué es |
|---|---|
| Transacción | El transactionId que se le dio a la caja. Sirve para cruzar con el ticket o el registro de la caja. |
| Recibida | Fecha y hora de la consulta (Argentina). |
| Sucursal / Medio de pago | Lo que envió la caja. |
| IP | Dirección de red de la caja que consultó. |
| Versión | La versión de cotización servida (— si no se sirvió ninguna). |
| Resultado / HTTP / Precio | Cómo terminó, el código que recibió la caja y el valor. |
Resultados posibles
| Resultado | Qué significa | Qué hacer |
|---|---|---|
| OK | Se respondió el valor vigente (HTTP 200). | Nada. |
| SUSPENDIDA | La versión vigente es una suspensión. | Cargar un valor si corresponde. |
| SIN_VERSION_VIGENTE | La región no tiene valor para ese medio de pago. | Cargar una cotización (4.2). |
| SUCURSAL_DESCONOCIDA | El número de sucursal no está dado de alta. | Revisar el número de la caja o dar de alta la sucursal (5.2). |
| SUCURSAL_DESHABILITADA REGION_INACTIVA | La sucursal o su región están desactivadas. | Habilitarlas si corresponde (5.1, 5.2). |
| MEDIO_PAGO_DESCONOCIDO MEDIO_PAGO_DESHABILITADO | El medio de pago no existe o está deshabilitado. | Revisar el catálogo (5.3). |
| SNAPSHOT_NO_CARGADO | El servidor recién arrancó y todavía no cargó las cotizaciones. | Esperar unos segundos; si persiste, avisar a TI. |
| PARAMETROS_INVALIDOS IP_NO_PERMITIDA SIN_TRANSACTION_ID ERROR_INTERNO | Problemas técnicos: pedido mal formado, caja fuera de la lista de IP permitidas, o falla del servidor. | Avisar a TI (secciones 13 y 16). |
7.3 Alertas
| Alerta | Qué avisa | Quién actúa |
|---|---|---|
| Combinaciones sin cotización vigente | Región + medio de pago habilitados con sucursales habilitadas que hoy recibirían “no encontrada”. | Cotizador: cargar el valor. |
| Sucursales desconocidas que consultaron | Números de sucursal que consultaron en los últimos 7 días y no están dados de alta. | Administrador: dar de alta la sucursal o corregir la caja. |
| Consultas de auditoría perdidas | Consultas que se respondieron pero no se pudieron registrar, desde el último arranque. Debe ser 0. | TI. |
| Tamaño de la tabla de consultas | Tamaño actual frente al umbral (10 GB por defecto). | TI. |
8Configuración (Administrador)
8.1 Usuarios
Crear un usuario
- Pulse Nuevo usuario.
- Escriba el Usuario (letras, números y
. _ @ -) y una Contraseña de un solo uso de al menos 8 caracteres. - Marque los Roles. Si marca Auditor, las otras casillas se deshabilitan (el Auditor es exclusivo).
- Pulse Crear usuario y entregue la contraseña a la persona por un medio seguro. En su primer ingreso deberá cambiarla (2.2).
Cambiar roles
Nadie puede quitarse a sí mismo el rol Administrador, y no se le puede quitar al último administrador activo. Desactivar da de baja al usuario sin borrarlo (su historia en la auditoría se conserva); el mismo botón lo vuelve a activar.
Restablecer contraseña
Al pulsar Confirmar restablecimiento, la contraseña anterior deja de servir y el sistema genera una contraseña de un solo uso, que aparece una sola vez en un panel con Copiar y Cerrar. Entréguela por un medio seguro; hasta que el usuario la cambie, el sistema solo le permite cambiarla. El restablecimiento queda auditado, sin la contraseña.
8.2 Umbral de confirmación reforzada
Define el Porcentaje a partir del cual un cambio de valor exige motivo (4.2). Acepta un número mayor que 0 y hasta 100, con hasta 2 decimales (por ejemplo 10 o 12,5). El cambio queda en la auditoría.
9Preguntas frecuentes y problemas comunes
| Síntoma | Causa probable | Qué hacer |
|---|---|---|
| La TV muestra “Cotización no disponible” | La región no tiene valor vigente o está suspendida; se generó un enlace nuevo y la TV tiene el viejo; la sucursal o la región están deshabilitadas; la TV no tiene red. | 1) Mire Cotizaciones vigentes para la región. 2) Probar consulta con esa sucursal y DOLAR (9/10). 3) Si todo da 200, genere un enlace nuevo y cárguelo en la TV. Espere 30–60 s: la TV reintenta sola. |
| El POS no toma el dólar (la caja no ofrece cobrar en dólares o da error) | Sin versión vigente, suspensión, sucursal desconocida (el número de la caja no coincide), medio deshabilitado; o la caja no tiene configurado el multimoneda. | 1) Probar consulta: el Motivo dice la causa. 2) En Consultas del POS, filtre por la sucursal: si no aparece ninguna consulta de esa caja, el problema está en la caja o en la red (avise a TI, sección 14). 3) Si aparece SUCURSAL_DESCONOCIDA, revise el número. |
| Olvidé la contraseña | — | Pida a un Administrador Restablecer contraseña. Recibirá una de un solo uso y deberá cambiarla al ingresar. |
| El valor no se guarda | Formato inválido (más de 2 decimales, puntos mal puestos, 0); falta el motivo (el botón Confirmar y cargar queda gris); fecha programada en el pasado; ya existe una versión con la misma fecha. | Lea el aviso rojo: dice qué corregir. Escriba el valor como 1520,50 o 1.520,50 y complete el Motivo si aparece. |
| Cargué un valor equivocado | — | Si todavía no rige (programada): Historial → Anular. Si ya rige: cargue enseguida una versión nueva inmediata con el valor correcto (pedirá motivo si el salto supera el umbral). |
| No veo Nueva cotización o el grupo Sucursales | Su usuario no tiene ese rol. | Pida al Administrador que revise sus roles (8.1). |
| Me pide ingresar otra vez | Recargó la página, abrió otra pestaña, o su contraseña cambió (el aviso dice La contraseña se cambió. Ingrese con la contraseña nueva.). | Ingrese de nuevo. Lo que ya estaba guardado no se pierde. |
| Las Referencias dicen “no disponible” | Una fuente externa no respondió. | Nada: son informativas y no afectan a las cajas ni a las pantallas. |
| Al guardar aparece “Otra persona modificó este registro” | Otra persona guardó el mismo registro mientras usted editaba. | La pantalla ya cargó los datos actuales: revíselos y vuelva a aplicar su cambio. |
Instalación y configuración del servidor
Esta parte de la guía es para el personal de Tipre/TI que instala y opera el servidor de Supermercados Becerra. Los operadores del back-office pueden omitirla. Es un resumen orientado a la acción; el detalle completo y los casos límite están en el RUNBOOK, que es la fuente autoritativa. Las referencias entre paréntesis (por ejemplo "RUNBOOK 3.2") apuntan a sus secciones.
Convenciones: <INSTALL> es la carpeta de instalación (por ejemplo C:\Tipre\SistemaBiMonetarismo) y <RAIZ> la carpeta que la contiene junto con el junction del JDK (por defecto C:\Tipre). Los comandos son de PowerShell y usan curl.exe.
10Arquitectura y red
El servidor expone dos puertos HTTP distintos. Las cajas (POS) hablan TCP directo con la Pizarra, sin TLS; el back-office y la pantalla de sucursal pasan por un proxy de TLS.
Cajas (POS) hacia la Pizarra
(subredes de la allowlist)→Firewall
puerto 8084→Pizarra :8084
solo GetCurrentPrice→SQL Server :1433
Back-office y pantalla (TV de kiosco) hacia el servidor
TV de kiosco→Proxy de TLS
HTTPS 443→Aplicación :8080
(HTTP)→SQL Server :1433
| Puerto | Qué es | Quién puede conectarse | Notas |
|---|---|---|---|
8084 (bm.pizarra.port) | La Pizarra: el endpoint que consulta el POS. | Solo las subredes de la allowlist (firewall y aplicación, con la misma lista). | Sin TLS ni autenticación (el POS no los soporta). Nunca detrás del proxy. Solo atiende GET /APIPizarraPrecios/Tipre/GetCurrentPrice?BranchNumber=&PaymentMethod.Id=&PaymentMethod.SubId=; cualquier otra ruta da 404 vacío. Una IP fuera de la lista recibe 403 y se audita. |
8080 (server.port) | Back-office, pantalla de sucursal y actuator. | Solo el proxy de TLS y la red de operación de Tipre. No las cajas. | Habla HTTP; el TLS se termina en el proxy. El proxy publica una lista explícita de rutas y niega /actuator. |
| 1433 | SQL Server 2019 (autenticación mixta). | Solo el servidor de la aplicación. | Dos logins: dueño del esquema (Flyway) y runtime. |
| 443 saliente | Panel informativo "Dólar Banco Nación". | Desde el servidor hacia api.bcra.gob.ar, criptoya.com y dolarapi.com. | Opcional: sin esa salida las filas dicen "no disponible" y nada más se afecta. Se apaga con bm.referencia.habilitado: false. |
En Windows localhost puede resolverse a ::1, que no está en la allowlist, y la Pizarra contesta 403. Por eso la allowlist tiene que incluir 127.0.0.1/32.
11Requisitos
| Qué | Detalle |
|---|---|
| Servidor | Windows Server con acceso de administrador. Reloj sincronizado por NTP (un reloj corrido hace rechazar versiones válidas). |
| Java | Eclipse Temurin 25 (no Oracle JDK), alcanzado por el junction estable C:\Tipre\jdk. |
| Base de datos | SQL Server 2019, alcanzable desde el servidor, con autenticación mixta y una base con dos logins. Crear logins exige permisos de servidor (por ejemplo sysadmin); si usted no los tiene, los crea quien administra la instancia de Becerra. |
| Servicio | WinSW 2.12.0 (ejecutable de esa versión para la arquitectura del servidor; verifique su hash contra el que publica el proyecto). |
| Seed del catálogo | Python 3.10 o superior, en este servidor o en un puesto de administración. No se necesita para nada más. |
| No hace falta | Node.js (la interfaz viene dentro del jar) ni el árbol de fuentes. |
| Proxy de TLS | nginx o IIS con ARR, con certificado y dominio. Decisión abierta quién lo provee (ver sección 17). |
| Pedir a Becerra | Las subredes de las cajas (allowlist y firewall), la instancia de SQL Server y la salida HTTPS a los tres hosts del panel BNA. |
Archivos de la release
Se descargan de la GitHub Release del tag. El servidor nunca necesita el árbol de fuentes.
| Archivo | Para qué |
|---|---|
bimonetarismo-vX.Y.Z.jar | La aplicación con la interfaz embebida. |
bimonetarismo-service.xml | Plantilla del servicio WinSW. |
application.yml.example | Plantilla de la configuración externa. |
clientes-vX.Y.Z.zip | Marca de cada cliente, seed-ejemplo.csv y su README.md. |
seed_catalogo.py | Herramienta del seed del catálogo. |
carga-pos.jar, corpus-pos-vX.Y.Z.zip | Generador de carga POS y sus requests capturados (remedición, RUNBOOK 8). |
SHA256SUMS | Hashes de los siete anteriores. |
Verifique los hashes antes de usar nada. Todas las líneas tienen que decir OK:
cd C:\Descargas\release
Get-Content SHA256SUMS | ForEach-Object {
$hash, $nombre = $_ -split ' ', 2
$real = (Get-FileHash $nombre -Algorithm SHA256).Hash.ToLower()
"{0} {1}" -f ($(if ($real -eq $hash) { 'OK ' } else { 'FALLA ' })), $nombre
}
12Primera instalación paso a paso
Saltear el orden da síntomas confusos. Por ejemplo, sin una versión de cotización vigente todas las cajas reciben 404. Tras el primer arranque, la Pizarra también contesta 404 a todo: es lo esperado, aún no hay versiones.
- Decidir el proxy y pedir datos a Becerra. Confirmar quién provee el proxy de TLS y el dominio (bloquea el inicio, ver sección 17) y pedir las subredes de las cajas.
- Verificar los archivos de la release (comando de la sección 11).
- Crear la base y los dos logins (fase A, abajo).
- Instalar Temurin 25 y el junction
C:\Tipre\jdk; Python 3.10+ para el seed; comprobar NTP. - Crear carpetas y la cuenta del servicio con sus permisos.
- Escribir
config\application.yml(sección 13), con127.0.0.1/32en la allowlist, y la marca del cliente. - Instalar y arrancar el servicio. Primer arranque: Flyway crea las tablas.
- Fase B: bloque
DENY, matriz de permisos y reinicio. - Firewall y proxy de TLS; comprobar que
/actuator/healthpor el proxy da 404 o 403. - Chequeo de humo (sección 15). La Pizarra da 404 hasta cargar la primera versión; repítalo después.
- Ingresar con el primer administrador y cambiar su contraseña; cargar el catálogo (seed o ABM).
- Cargar la primera versión de cotización vigente por región para el medio 9/10 ("Nueva versión").
- Generar el token de la pantalla de cada sucursal desde "Sucursales" (se muestra una sola vez).
- Monitoreo, respaldos y ventanas de parches.
- Prueba de laboratorio con un POS real antes de apuntar las cajas, y prerrequisitos de cada POS (sección 14).
Carpetas y cuenta del servicio
<INSTALL>\bimonetarismo-service.exe WinSW 2.12.0, renombrado igual que el XML
<INSTALL>\bimonetarismo-service.xml plantilla de la release
<INSTALL>\bimonetarismo.jar jar de release, renombrado (sin la versión)
<INSTALL>\config\application.yml configuración externa
<INSTALL>\logs\ lo escribe WinSW
<INSTALL>\clientes\<cliente>\ carpeta de marca del cliente
C:\Tipre\jdk junction al JDK de Temurin instalado
Cierre <RAIZ> antes de poner nada dentro (quita la herencia de permisos; *S-1-5-32-544 es Administradores y *S-1-5-18 es SYSTEM). Si <RAIZ> ya existe con otro contenido, revíselo antes con icacls.
New-Item -ItemType Directory -Force <RAIZ> | Out-Null
icacls <RAIZ> /inheritance:r /grant:r "*S-1-5-32-544:(OI)(CI)F" "*S-1-5-18:(OI)(CI)F"
New-Item -ItemType Directory -Force <INSTALL>\config, <INSTALL>\logs | Out-Null
cmd /c mklink /J <RAIZ>\jdk "C:\Program Files\Eclipse Adoptium\jdk-25.x.y-hotspot"
& <RAIZ>\jdk\bin\java.exe -version
Cuenta local dedicada, sin inicio de sesión interactivo. La contraseña se pide sin eco y no se escribe en el XML:
$clave = Read-Host "Contraseña de la cuenta del servicio" -AsSecureString
New-LocalUser -Name svc-bimonetarismo -Password $clave -PasswordNeverExpires -UserMayNotChangePassword -Description "SistemaBiMonetarismo"
$cuenta = "$env:COMPUTERNAME\svc-bimonetarismo"
icacls <RAIZ> /grant "${cuenta}:(OI)(CI)RX"
icacls <INSTALL>\logs /grant "${cuenta}:(OI)(CI)M"
icacls <INSTALL>\config /inheritance:r /grant:r "*S-1-5-32-544:(OI)(CI)F" "${cuenta}:(OI)(CI)R"
icacls <RAIZ>
icacls <INSTALL>\config
Los dos icacls finales son la comprobación: en <RAIZ> solo Administradores, SYSTEM y la cuenta; en config solo Administradores y la cuenta (guarda las contraseñas de la base). Si <INSTALL> está fuera de <RAIZ>, la cuenta no hereda nada: agregue icacls <INSTALL> /grant "${cuenta}:(OI)(CI)RX".
Base de datos y logins de SQL Server
Hay dos logins por mínimo privilegio. Los permisos se aplican en dos fases porque Flyway crea las tablas en el primer arranque y un DENY exige que la tabla exista.
| Login | Para qué | Permisos |
|---|---|---|
Dueño del esquema (spring.flyway.user) | Flyway migra al arrancar. | DDL, ALTER y CREATE TRIGGER (por ejemplo db_owner de esa base y nada más). |
Runtime (spring.datasource.*) | Todo lo que hace la aplicación. | Solo SELECT, INSERT y UPDATE; sin DELETE, sin DDL y sin ALTER. |
Fase A, antes del primer arranque (con un login que pueda crear bases y logins; contraseñas largas y distintas):
CREATE DATABASE [<base>];
GO
CREATE LOGIN [<dueño>] WITH PASSWORD = N'<contraseña larga 1>', CHECK_POLICY = ON, CHECK_EXPIRATION = OFF, DEFAULT_DATABASE = [<base>];
CREATE LOGIN [<runtime>] WITH PASSWORD = N'<contraseña larga 2>', CHECK_POLICY = ON, CHECK_EXPIRATION = OFF, DEFAULT_DATABASE = [<base>];
GO
USE [<base>];
CREATE USER [<dueño>] FOR LOGIN [<dueño>];
ALTER ROLE db_owner ADD MEMBER [<dueño>];
CREATE USER [<runtime>] FOR LOGIN [<runtime>];
GRANT SELECT, INSERT, UPDATE ON SCHEMA::dbo TO [<runtime>];
GO
Con CHECK_EXPIRATION = ON la contraseña vence y la aplicación deja de conectarse ese día, sin aviso. Se recomienda complejidad y bloqueo sin vencimiento, y cambiar las contraseñas con un procedimiento propio (editar application.yml y reiniciar).
Fase B, después del primer arranque (con el login dueño):
USE [<base>];
DENY DELETE ON SCHEMA::dbo TO [<runtime>];
DENY UPDATE ON OBJECT::dbo.auditoria_cambio TO [<runtime>];
DENY UPDATE ON OBJECT::dbo.consulta_cotizacion TO [<runtime>];
DENY INSERT, UPDATE ON OBJECT::dbo.flyway_schema_history TO [<runtime>];
GRANT UPDATE ON OBJECT::dbo.seq_transaction_id TO [<runtime>];
Reinicie el servicio y verifique los permisos efectivos (no cambia nada):
EXECUTE AS USER = '<runtime>';
SELECT t.name AS tabla,
HAS_PERMS_BY_NAME('dbo.' + t.name, 'OBJECT', 'SELECT') AS sel,
HAS_PERMS_BY_NAME('dbo.' + t.name, 'OBJECT', 'INSERT') AS ins,
HAS_PERMS_BY_NAME('dbo.' + t.name, 'OBJECT', 'UPDATE') AS upd,
HAS_PERMS_BY_NAME('dbo.' + t.name, 'OBJECT', 'DELETE') AS del
FROM sys.tables t ORDER BY t.name;
REVERT;
| Tabla | sel | ins | upd | del |
|---|---|---|---|---|
auditoria_cambio, consulta_cotizacion | 1 | 1 | 0 | 0 |
flyway_schema_history | 1 | 0 | 0 | 0 |
medio_pago, region, sucursal, umbral_confirmacion, usuario, version_cotizacion | 1 | 1 | 1 | 0 |
Cuando una release agrega tablas, vuelva a correr esta matriz: un DENY no se hereda hacia adelante y las notas de la release dicen qué DENY agregar.
Servicio Windows (WinSW)
La plantilla define reinicio automático (startmode Automatic; reintentos a los 10 s, 20 s y 60 s), logs en <INSTALL>\logs (8 archivos de 10 MB), directorio de trabajo <INSTALL> y parada con stoptimeout de 60 s. Edite el XML solo si el junction no está en C:\Tipre\jdk o si hace falta un proxy de salida. No agregue ninguna contraseña al XML.
Desde una consola de administrador, en <INSTALL>. install /p pregunta la cuenta (escriba .\svc-bimonetarismo) y su contraseña; responda y a "Log on as a service":
.\bimonetarismo-service.exe install /p
.\bimonetarismo-service.exe start
Get-Service BimonetarismoService
Get-ChildItem <INSTALL>\logs
El log dice Successfully applied N migration en el primer arranque. Si el servicio no inicia con el error 1069, la cuenta no tiene el derecho "Iniciar sesión como servicio" (concédalo en la Directiva de seguridad local).
Primer administrador
Las claves bm.admin.usuario y bm.admin.password de application.yml crean el primer Administrador solo mientras la tabla de usuarios está vacía; los reinicios no tocan los usuarios. La contraseña la elige quien instala (no es de un solo uso) y no se registra en el log ni en la auditoría.
- Ingrese con ese usuario (la contraseña se pide por consola):
curl.exe -u <usuario> http://localhost:8080/api/v1/metiene que dar 200. - Cambie la contraseña desde "Cambiar contraseña" (
/cambiar-password) o conPUT /api/v1/me/password({actual, nueva}). La interfaz no lo obliga. - Después puede borrar
bm.admin.usuarioybm.admin.passworddeapplication.yml.
Si nadie puede ingresar, corrija el bloque y reinicie (mientras no haya usuarios, se vuelve a intentar). Nunca escriba usuario:contraseña en la línea de comandos: -u <usuario> hace que curl.exe pida la contraseña.
Proxy de TLS
El proxy no es parte de la aplicación ni de la release. Publica una lista explícita de rutas (todo lo demás es 404) y niega /actuator: / exacta, /favicon.svg, /login, /cambiar-password, /gestion/..., /pantalla/..., /assets/... y /api/.... Ejemplo mínimo de nginx:
server {
listen 443 ssl;
server_name cotizacion.<cliente>.<dominio>;
ssl_certificate <ruta>/fullchain.pem;
ssl_certificate_key <ruta>/privkey.pem;
location ^~ /actuator { return 404; }
location = / { proxy_pass http://<servidor>:8080; proxy_set_header Host $host; }
location = /favicon.svg { proxy_pass http://<servidor>:8080; proxy_set_header Host $host; }
location ~ ^/(login|cambiar-password|gestion|pantalla|assets|api)(/|$) { proxy_pass http://<servidor>:8080; proxy_set_header Host $host; }
location / { return 404; }
}
En IIS con ARR: una regla de bloqueo para ^actuator antes de las reglas de reenvío. El proxy no necesita enviar X-Forwarded-For: la aplicación lo ignora, por lo que detrás del proxy el límite de intentos de la pantalla actúa sobre la IP del proxy.
Firewall del servidor
New-NetFirewallRule -DisplayName "Bimonetarismo Pizarra (cajas)" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 8084 -RemoteAddress 10.x.x.x/16,10.y.y.y/16
New-NetFirewallRule -DisplayName "Bimonetarismo principal (proxy y operacion)" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 8080 -RemoteAddress <IP del proxy>,<red de operacion>
Get-NetFirewallRule -Direction Inbound -Enabled True -Action Allow | Get-NetFirewallPortFilter | Where-Object { $_.LocalPort -in '8080','8084','Any' }
La tercera línea no debe listar ninguna regla más que las dos primeras (por ejemplo una regla automática de "Java Platform SE binary" que abra el puerto a cualquier origen).
13Referencia de configuración
El archivo se llama config\application.yml y sale de application.yml.example, reemplazando cada CHANGE-ME. No se commitea nunca y no va dentro del jar. La ruta se resuelve contra el directorio de trabajo del proceso (<INSTALL>), no contra la ubicación del jar. La aplicación no arranca sin las claves spring.datasource.*, bm.pizarra.port y bm.pizarra.allowlist. Antes de editar un archivo existente, haga una copia con la fecha.
| Clave | ¿Obligatoria? | Ejemplo | Qué hace |
|---|---|---|---|
spring.datasource.url | Sí | jdbc:sqlserver://<host>:1433;databaseName=<base>;encrypt=true;trustServerCertificate=false;socketTimeout=10000 | Conexión de runtime. socketTimeout=10000 no es opcional: sin él, una base que deja de contestar sin cerrar el socket cuelga el snapshot, la reserva de ids y la auditoría. |
spring.datasource.username | Sí | <login de runtime> | Login de runtime (solo SELECT, INSERT, UPDATE). |
spring.datasource.password | Sí | <contraseña> | Contraseña de ese login. Solo vive en este archivo. |
spring.datasource.hikari.connection-timeout | No | 3000 | Espera por una conexión del pool, en ms (3000 por defecto). |
spring.flyway.user | Sí en producción | <login dueño> | Login que migra el esquema al arrancar. Si se omite, Flyway usa el de runtime, que necesitaría DDL y deshace la separación de privilegios. |
spring.flyway.password | Sí en producción | <contraseña> | Contraseña del login dueño. |
spring.flyway.url | Recomendada | jdbc:sqlserver://<host>:1433;databaseName=<base>;encrypt=true;trustServerCertificate=false;socketTimeout=600000;loginTimeout=15 | URL propia de Flyway con socketTimeout grande pero finito (10 min). Si se omite, reutiliza la de runtime (y sus 10 s cortarían una migración larga). |
bm.pizarra.port | Sí | 8084 | Puerto HTTP propio de la Pizarra, distinto de server.port. |
bm.pizarra.allowlist | Sí | 10.x.x.x/16,127.0.0.1/32,<IP del servidor>/32 | CIDR separados por coma de las subredes de las cajas. Otra IP recibe 403 y se audita. Tiene que incluir 127.0.0.1/32. Escriba los rangos IPv4 como IPv4: un CIDR mapeado (::ffff:10.0.0.0/104) hace fallar el arranque. |
bm.admin.usuario | Primera instalación | <administrador> | Primer Administrador; solo se usa mientras la tabla de usuarios está vacía. Se puede borrar después. |
bm.admin.password | Primera instalación | <contraseña> | Su contraseña; no se registra en log ni auditoría. Cámbiela tras el primer ingreso. |
spring.config.import (clave plana) | Marca | optional:file:C:/Tipre/SistemaBiMonetarismo/clientes/<cliente>/branding.yml | Carga el bloque bm.branding.* del cliente. Si el archivo ya tiene un import, agregue la ruta a ese valor separada por coma. |
bm.branding.dir (clave plana) | Marca | C:/Tipre/SistemaBiMonetarismo/clientes/<cliente>/branding | Ruta absoluta de la carpeta con el logo. Sin ella se usa la marca neutra del jar. |
bm.branding.cliente-nombre | Marca | <nombre del cliente> | Nombre mostrado. Vive en branding.yml. |
bm.branding.color-primario, bm.branding.color-secundario | Marca | "#RRGGBB" | Colores, siempre entre comillas: un # sin comillas es un comentario YAML, el valor queda vacío y el servicio no arranca. |
bm.branding.logo-cliente | Marca | cliente-logo.png | Nombre simple del archivo (png, jpg, svg, gif o webp; hasta 1 MB). |
bm.referencia.habilitado | No | true | Panel Dólar Banco Nación. Con false no sale a internet. |
bm.alertas.consultas-max-gb | No | 10 | Tamaño de la tabla de consultas que dispara la alerta del back-office. |
bm.snapshot.refresh-seconds, bm.pizarra.id-block-size, bm.auditoria.queue-size, bm.auditoria.systemic-hold-seconds, bm.auditoria.rejected-interval-ms | No | (valores por defecto del jar) | Ajustes finos. Los valores por defecto son los medidos en AC-24: no los cambie sin medir. |
Escriba spring.config.import y bm.branding.dir como claves planas en la columna 0. No agregue un segundo bloque bm: o spring:: una clave duplicada vuelve inválido el YAML y el servicio no arranca. El procedimiento completo para armar la carpeta de un cliente está solo en clientes/README.md (viene en clientes-vX.Y.Z.zip).
Certificado de SQL Server
encrypt=true;trustServerCertificate=false exige que el certificado sea de una CA en la que la JVM confíe. Decisión abierta Si la base está en el mismo servidor, trustServerCertificate=true no agrega riesgo. Si está en otra máquina, se recomienda instalar la CA en un almacén propio (trustStore=<ruta>;trustStorePassword=<contraseña> en las dos URL) y no en el cacerts del JDK: un parche de Temurin trae el suyo y la conexión empieza a fallar sin que nadie toque nada.
14Prerrequisitos en el POS
Sin esto el POS nunca consulta la Pizarra: en Becerra el dólar hoy no está operativo en el POS. En la base de cada POS:
| Qué | Valor |
|---|---|
dM_DMdeP.iTaxNumber | 1 en el medio de pago 9/10 "DOLAR" (el dólar billete; no existe 24/10). El POS solo consulta la Pizarra si es distinto de 0. |
Grupo dM_MdeP | uId = 9, nombre "DOLAR", en el menú de medios de pago (en la prueba se clonó del grupo de EFECTIVO, uIdDialog 495). |
| Profile 554 | pro_MULTIMONEDA_HABILITADO = 1 |
| Profile 555 | IP de la Pizarra. |
| Profile 556 | Puerto de la Pizarra. |
| Profile 557 | Timeout de recepción (10 s en el POS). |
| Profile 558 | Timeout de conexión (5 s en el POS). |
POS_MMON.DLL | Presente en el POS. |
Además, el NroSuc de cada POS tiene que estar dado de alta como sucursal en el servidor (con su región y una cotización vigente para 9/10) y la IP de las cajas dentro de la allowlist. Una sucursal que consulta sin estar dada de alta aparece en las alertas ("sucursales desconocidas") y recibe 404.
La POS_MMON.DLL del árbol de Becerra (pcpos20260807P_BECERRA) tiene activo #define SIMULARRTASINHOST (pos_mmon.cpp:136) y responde siempre un valor fijo. Hay que portar la corrección de simulación de DINO, recompilar y repetir la prueba (AC-25) antes de producción. AC-25 está aprobado con la DLL de DINO y pendiente con la DLL de Becerra.
El POS no muestra el message de un 404, así que "No se encontró la cotización" y "Cotización suspendida" son indistinguibles para el cajero. El ticket impreso no muestra la cotización ni el transactionId; quedan en dE_DDMP.vData (60= valor servido, 61= dólares, 62= transactionId). Cada vez que se elige el medio se hace una consulta nueva, por lo que hay transactionId sin ticket y es normal. Está pendiente confirmar si el NroSuc del POS coincide con el de TipreRetail (riesgo R-06).
La prueba de laboratorio con un POS real (RUNBOOK 11) valida que lo grabado por el POS coincide con lo auditado en el servidor.
15Verificar que funciona
Corra estos comandos desde el propio servidor, después de la instalación y de cada despliegue. Reemplace el puerto, la sucursal de prueba y el dominio.
# 1. El servicio corre
Get-Service BimonetarismoService
# 2. Arrancó y cargó el snapshot (buscar estas dos líneas)
Select-String -Path <INSTALL>\logs\bimonetarismo-service.out.log -Pattern "Started BimonetarismoApplication","Snapshot loaded with"
# 3. Vivo, y la UI y el branding salen del jar
curl.exe -s http://localhost:8080/actuator/health # {"groups":["liveness","readiness"],"status":"UP"}
curl.exe -s -o NUL -w "%{http_code}`n" http://localhost:8080/login # 200
curl.exe -s http://localhost:8080/api/v1/branding # nombre y colores del cliente
# 4. Un administrador puede ingresar
curl.exe -s -u <administrador> http://localhost:8080/api/v1/me # pide la contraseña; roles ADMINISTRADOR, COTIZADOR
# 5. La Pizarra contesta como la ve el POS
curl.exe -s -i "http://127.0.0.1:8084/APIPizarraPrecios/Tipre/GetCurrentPrice?BranchNumber=<NroSuc>&PaymentMethod.Id=9&PaymentMethod.SubId=10"
# 6. El proxy NO publica el actuator: 404 o 403
curl.exe -s -o NUL -w "%{http_code}`n" https://<dominio>/actuator/health
| Resultado | Significa |
|---|---|
Paso 5: 200 con currentPrice y transactionId | Hay sucursal y cotización vigentes; currentPrice es el valor vigente. |
Paso 5: 404 con "currentPrice": 0 y "error": true | Sucursal desconocida o sin versión vigente. Es lo esperado antes de cargar la primera versión; también trae transactionId y se audita. |
Paso 5: 403 Origen no permitido | Es la allowlist: falta 127.0.0.1/32 o se usó localhost. |
| Paso 6: 200 | El proxy publica el actuator: corríjalo antes de seguir. Pruebe también /actuator/metrics y --path-as-is https://<dominio>/api/../actuator/health. |
- Repita el paso 5 desde una IP de la allowlist (una caja o un equipo de su subred, con la IP del servidor en lugar de
127.0.0.1): comprueba el firewall y la lista. - Una ruta que no es
GetCurrentPriceen el puerto de la Pizarra da 404 vacío:curl.exe -s -o NUL -w "%{http_code}`n" http://127.0.0.1:8084/actuator/healthtiene que dar404. - Métricas normales:
pizarra.snapshot.edad.segundosmenor que 120,pizarra.auditoria.escritor.vivoen 1 ypizarra.auditoria.perdidasen 0. - Back-office: abra la interfaz por el proxy (HTTPS), ingrese, vea las cotizaciones vigentes y la sección de alertas.
- Kiosco: abra
/pantalla/<NroSuc>con el token de la sucursal (generado en "Sucursales") en el navegador de la TV. - Marca: el log tiene
Branding of this install: client name '<nombre>'; el nombre neutro "Cotización del dólar" significa que el import no ocurrió (ruta incorrecta).GET /api/v1/branding/logo-clientedebe dar 200.
16Operación: actualizaciones, respaldos y logs
Actualizar una versión (RUNBOOK 6.2)
Fuera del horario pico de las cajas: mientras el servicio está detenido, las cajas no tienen dólar (unos 12 a 16 s de arranque, más lo que tarde el respaldo).
- Lea las notas de la release, empezando por la sección calculada (migraciones nuevas y cambios de
application.yml.example). Si salteó versiones, lea la de cada release intermedia. Una clave obligatoria nueva impide el arranque. - Copie
config\application.ymlantes de editarlo y aplique los cambios. - Verifique el hash del jar.
- Detenga el servicio y confirme el cierre:
.\bimonetarismo-service.exe stop; busqueAudit shutdown: 0 audit entries remain unflusheden el log. - Respaldo completo después de detener, y anote la versión del esquema:
BACKUP DATABASE [<base>] TO DISK = N'<ruta>\pre-<tag>.bak' WITH COPY_ONLY, COMPRESSION, CHECKSUM, STATS = 10; RESTORE VERIFYONLY FROM DISK = N'<ruta>\pre-<tag>.bak' WITH CHECKSUM; SELECT TOP 1 version, description FROM flyway_schema_history WHERE success = 1 ORDER BY installed_rank DESC; - Conserve el jar anterior (
bimonetarismo.jar.anterior-<fecha>) y copie el nuevo comobimonetarismo.jar. - Arranque:
.\bimonetarismo-service.exe start. Flyway aplica las migraciones pendientes. - Si la release agregó tablas, vuelva a correr la matriz de permisos y agregue los
DENYindicados. - Chequeo de humo (sección 15) y anote fecha, tag y SHA-256 en el registro de cambios.
Si 15 minutos después del arranque el chequeo de humo no pasó, vuelva atrás sin seguir buscando la causa: las cajas están sin dólar. Si la release traía migraciones ya aplicadas, decide el equipo de desarrollo (por teléfono) entre corregir hacia adelante y restaurar.
Volver atrás (RUNBOOK 6.4)
- Solo el jar (sin migraciones aplicadas): detenga el servicio, restaure
bimonetarismo.jar.anterior-<fecha>y elapplication.ymlanterior, arranque y haga el chequeo de humo. - Con restauración (la release aplicó migraciones): no asuma que el jar anterior es compatible con el esquema nuevo. Siga el procedimiento B del RUNBOOK, que incluye adelantar la secuencia (abajo).
Respaldos y restauración (RUNBOOK 6.7)
- Respaldo completo diario y respaldo del log de transacciones con la frecuencia que fije Becerra. Pruebe la restauración periódicamente: un respaldo que nunca se restauró no está probado.
- Retención: las versiones de cotización y la auditoría se guardan para siempre; las consultas del POS, toda la vida operativa, sin purga. El back-office alerta cuando
consulta_cotizacionsupera 10 GB (bm.alertas.consultas-max-gb).
Restaurar un respaldo rebobina seq_transaction_id y la Pizarra podría reemitir ids que las cajas ya imprimieron. Orden: (1) deshabilite el arranque y detenga el servicio (Set-Service BimonetarismoService -StartupType Disabled); (2) restaure la base con un login sysadmin o dbcreator; (3) adelante la secuencia con el login dueño; (4) verifique contra el mayor 62= de las cajas; (5) recién entonces vuelva el arranque a automático, arranque y haga el chequeo de humo.
DECLARE @actual BIGINT = (SELECT CAST(current_value AS BIGINT) FROM sys.sequences WHERE name = 'seq_transaction_id');
DECLARE @sql NVARCHAR(200) = N'ALTER SEQUENCE dbo.seq_transaction_id RESTART WITH ' + CAST(@actual + 100000000 AS NVARCHAR(30));
EXEC (@sql);
SELECT CAST(current_value AS BIGINT) AS secuencia_actual FROM sys.sequences WHERE name = 'seq_transaction_id';
Logs y monitoreo
- WinSW captura la salida en
<INSTALL>\logscon rotación (8 archivos de 10 MB). Los nombres reales los muestraGet-ChildItem <INSTALL>\logs; el RUNBOOK usabimonetarismo-service.out.logy.err.log. Ningún secreto se escribe en el log. - El monitoreo lee desde el propio servidor:
curl.exe -s http://localhost:8080/actuator/metrics/<nombre>. Alerte por el aumento depizarra.auditoria.perdidas(vuelve a 0 al reiniciar: anótelo antes), porpizarra.auditoria.cola.tamanomayor que 50000,pizarra.auditoria.escritor.vivoen 0 ypizarra.snapshot.edad.segundosmayor que 300 (o -1 pasado el arranque). Tabla completa en RUNBOOK 7.2. - Fuera de la aplicación, vigile el estado del servicio, los eventos 7031 y 7034 del Service Control Manager, el disco del servidor y de la base, y la cola de respaldos.
- Reinicios y parches (Temurin trimestral, Windows, SQL Server): siempre fuera del pico; antes de reiniciar Windows detenga el servicio y busque la línea
Audit shutdown. Con un parche de Temurin, reapunte el junction (RUNBOOK 6.8). - Fragmentación del índice de
consulta_cotizacion: revísela periódicamente (RUNBOOK 10).
Diagnóstico técnico rápido
| Síntoma | Qué mirar |
|---|---|
| El servicio no arranca | El log: falta una clave obligatoria (spring.datasource.*, bm.pizarra.port, bm.pizarra.allowlist), clave YAML duplicada, color sin comillas o CIDR IPv4 mapeado. El informe de arranque nombra la clave. Error 1069: falta "Iniciar sesión como servicio". |
| La Pizarra da 404 a todo | El snapshot no cargó (base caída o sin permisos): pizarra.snapshot.edad.segundos en -1. En una instalación nueva es lo esperado hasta que exista una versión vigente. |
La Pizarra da 403 Origen no permitido | La IP no está en bm.pizarra.allowlist; desde el servidor, falta 127.0.0.1/32 o se usó localhost. |
| Las cajas no ven el dólar | Firewall o allowlist; sucursal no dada de alta o NroSuc distinto (Alertas: sucursales desconocidas); sin versión vigente; cotización suspendida; prerrequisitos del POS (sección 14). |
503 BASE_NO_DISPONIBLE | La base o un permiso. No reinicie: la Pizarra sigue sirviendo desde el snapshot en memoria, y un servicio que arranca con la base caída deja a todas las cajas en 404 (RUNBOOK 15.1). En el log, Connection is not available es un pool agotado y Login failed for user es el login. |
pizarra.auditoria.perdidas sube | Base lenta o caída con la cola llena, o un permiso que falta sobre consulta_cotizacion. Busque Audit entries lost ( en el log (RUNBOOK 15.3). |
| Nadie puede ingresar al back-office | El bloque bm.admin y el log del primer arranque. |
| La aplicación dejó de conectarse a la base sin cambios | Login con contraseña vencida (CHECK_EXPIRATION = ON) o almacén de certificados cambiado por un parche de Java. |
| Logo o nombre neutros | El import de branding.yml o bm.branding.dir. |
| Panel BNA "no disponible" | Salida HTTPS a los tres hosts. No afecta a nada más. |
Para incidentes (base caída, la Pizarra no responde, auditoría perdida) siga los playbooks de las secciones 15.1, 15.2 y 15.3 del RUNBOOK, y complete antes de producción su tabla de contactos.
17Estado del procedimiento y decisiones abiertas
Los procedimientos del RUNBOOK son un borrador del equipo de desarrollo pendiente de validación de laboratorio por el responsable de operación de Tipre. Siguen sin verificar en un servidor real: la receta de permisos en SQL Server 2019, el servicio WinSW (incluida la parada ordenada), el proxy de TLS, un respaldo y su restauración, y la prueba con un POS real (AC-25). El orden de la primera instalación sí se corrió contra una base de prueba de SQL Server 2022. Hasta la validación, todo lo marcado (origin: agent) es una recomendación que Tipre debe confirmar o cambiar.
La tabla de decisiones del RUNBOOK (sección 1) tiene la columna "Confirmado (quién, fecha)" vacía en todas sus filas: todas siguen abiertas. Estas son las que más afectan a quien instala; "Si no se confirma" es lo que rige mientras nadie diga otra cosa.
| # | Decisión | Recomendación | Si no se confirma |
|---|---|---|---|
| 16 | Quién provee el proxy de TLS | El equipo de red de Tipre (nginx o IIS con ARR), con /actuator negado. Alternativa: el proxy de Becerra con las mismas reglas. | Bloquea la instalación: no hay valor por defecto; no se empieza hasta que alguien lo confirme. |
| 10 | Certificado de SQL Server | trustServerCertificate=true solo con la base en el mismo servidor; si no, instalar la CA en un almacén propio. | Rige la recomendación. |
| 13 | Cuenta del servicio | Cuenta local dedicada svc-bimonetarismo con install /p. Alternativas: LocalSystem (más privilegio) o gMSA. | Cuenta dedicada. |
| 1 | Envoltorio del servicio | WinSW 2.12.0 con la plantilla de la release (alternativa: NSSM, reescribiendo la plantilla). | Se instala WinSW. |
| 14 | Parada ordenada del servicio | WinSW espera hasta 60 s. No verificado en un servidor real. | Se verifica en el laboratorio. |
| 2 | Actuator en el puerto principal | Sin cambios, con los tres controles de red (firewall, proxy sin /actuator, monitoreo local). | Rigen los tres controles. |
| 3 | Permisos del login de runtime | Solo SELECT, INSERT y UPDATE, con los DENY de la fase B. | Se aplica la receta. |
| 4 | Login dueño y runtime en el mismo application.yml | Aceptar el riesgo, mitigado con permisos de archivo. | Se acepta el riesgo. |
| 5 | IP de origen es la del par TCP | Aceptar que el límite de intentos de la pantalla actúe sobre la IP del proxy. | Se mantiene. |
| 11 | Política de contraseña de los logins | CHECK_POLICY = ON, CHECK_EXPIRATION = OFF. | Rige la recomendación. |
| 12 | Sin -XX:+ExitOnOutOfMemoryError | Sin la bandera, para no perder auditoría sin contarla. | Sin la bandera. |
| 17 | Ruta de Java del servicio | Junction estable C:\Tipre\jdk. | Junction. |
| 19 | Orden del respaldo de un despliegue | Después de detener el servicio. | Después de detener. |
El resto (6 umbrales de alerta, 7 calentamiento, 8 secuencia tras restaurar, 9 remedición, 15 fragmentación, 18 límite de despliegue) también figura sin confirmar en la sección 1 del RUNBOOK. Quien valida registra ahí quién confirmó cada una y cuándo.
Pendientes de proyecto relacionados: la POS_MMON.DLL de Becerra (sección 14, AC-25), la lista real de sucursales y el mapeo de NroSuc (R-06; el CSV de clientes\becerra\ trae marcadores de posición) y la tabla de contactos de incidentes (RUNBOOK 15).
18Alcance y verificación de esta guía
- Las capturas se tomaron el 5 de octubre de 2026 sobre la versión más reciente de la interfaz, en un ambiente de prueba con una base de datos descartable. Contiene datos de prueba que no existen en producción: el medio de pago FIXTURE AC-16, los usuarios
cot-fixture,pantalla-fixture,cotizador.demoyauditor.prueba, la Región de prueba y la sucursal 99 — Sucursal de prueba. - Las capturas de escritorio son de 1440×900 px; las de celular, de 375 px de ancho; las de la pantalla de la sucursal, de 1280×720. Los círculos rojos numerados se agregaron sobre las capturas para esta guía.
- Ninguna captura muestra secretos: los campos de contraseña aparecen vacíos o enmascarados, la parte secreta del enlace de pantalla está tapada, y de Restablecer contraseña solo se muestra la confirmación. El ejemplo de desvío (sección 4.2) no se envió.
- El contenido se contrastó con la interfaz en vivo, con su código fuente y con
SPEC.md,ACCEPTANCE.md,docs/API.mdydocs/RUNBOOK.md. La parte técnica (secciones 10 a 17) resume el RUNBOOK, que es la fuente de detalle; sus procedimientos todavía son borradores a validar en laboratorio. - Los vínculos a
RUNBOOK.mdfuncionan al abrir la guía desde el repositorio; si la guía se publica sola como sitio estático, el RUNBOOK debe consultarse en el repositorio.




