Sync de PDV legado sin detener la operación
En este artículo
Una cervecería necesitaba mostrar el ranking de consumo en la TV del bar. Los datos venían del TPV — el sistema antiguo del local. El equipo era una TV Box Android 24/7; la internet fallaba; el TPV se reiniciaba cada día. Apagar todo para migrar era arriesgado: el bar no podía parar.
Este post describe lo que hice en Batalha dos Barris: en lugar de cambiar el sistema de golpe, reemplacé partes poco a poco, con un agente de sincronización separado.
Contexto
- Origen de los datos: MySQL del TPV (sistema legado; no controlamos el deploy).
- Destino: PostgreSQL + API Flask + player Angular (PWA) en la TV Box.
- Expectativa del negocio: ranking actualizado con frecuencia, sin que alguien tenga que tocar el código en la TV.
Si la sincronización para, el ranking se congela — y los clientes del bar lo ven.
Arquitectura
textMySQL del TPV → Agente Python (SSH) → PostgreSQL → API Flask → App Angular en TV Box
- El player en la TV no accede al MySQL legado directamente.
- El agente maneja SSH, reinicios del TPV y el punto donde paró la sync.
- La API usa caché para no saturar el player con peticiones.
Elegimos sincronización por intervalos en lugar de conexión en vivo (websocket). En una TV Box con internet inestable, es más simple y confiable.
Problemas que aparecieron
Internet cae en el agente: la sync debe continuar desde el último ID u hora confirmada — sin reprocesar todo ni saltar ventas.
TPV se reinicia: el agente reconecta y valida el punto de retoma; el player muestra el último dato en caché.
Retraso en los datos: hoy lo detectamos por logs; si lo hiciera de nuevo, añadiría alertas cuando el retraso supere un límite aceptable.
Lecciones para otros proyectos
- Retomar donde se quedó debe ser requisito desde el inicio.
- Sync incremental con intervalo que tolere fallos cortos de red.
- Aislar fallos: legado, agente, API y player no deben tumbarse entre sí.
- Siguiente paso: medir retraso y fallos por etapa.




Comentarios
Inicia sesión con tu cuenta de GitHub para comentar. Los comentarios son públicos y se guardan como Discussions en el repositorio de comentarios del blog.