Bitácora digital de operación para dos plantas térmicas
Reemplacé los libros de Excel de los turnos de operación por una aplicación web en tiempo real, con turnos como entidad de negocio, reportes oficiales generados desde los datos y más de 1.400 pruebas automatizadas.
Ficha del proyecto
- Rol
- Ingeniero full-stack, único desarrollador (diseño, backend, frontend, base de datos, despliegue)
- Periodo
- mar de 2026 a hoy
- Enlaces públicos
- Sistema interno: el código es privado, y los nombres, datos y diagramas se omitieron o se recrearon.
1.400+
casos de prueba automatizados entre backend y frontendFuente: Suites de node:test y Vitest del repositorio, septiembre de 2026 516
commits en 6 meses de desarrollo continuoFuente: Historial de git, marzo a septiembre de 2026 38 de 39
hallazgos cerrados de una auditoría de seguridad propiaFuente: Informe interno de auditoría de seguridad, 2026
El problema
El personal de operación de dos plantas térmicas llevaba sus bitácoras de turno en libros de Excel. La información quedaba repartida entre archivos, el cierre de turno dependía de la disciplina de cada persona y los reportes oficiales del día se armaban a mano copiando celdas.
Mi rol
- Levanté los requisitos con jefes de turno, ingenieros de operación y químicos, y los convertí en un modelo de dominio con turnos, bitácoras y permisos por cargo.
- Diseñé y construí el frontend, el backend, la base de datos y la integración con el inicio de sesión corporativo.
- Desplegué y opero el sistema en un servidor Linux de la empresa, con nginx, systemd y un script de actualización con verificaciones.
- Documenté 71 decisiones de arquitectura y llevé una auditoría de seguridad propia hasta cerrar 38 de 39 hallazgos.
Restricciones
- Usuarios en turnos de 24 horas cuyo día operativo cruza la medianoche.
- Inicio de sesión corporativo obligatorio con roles por cargo.
- Servidor propio en la red corporativa, detrás de un firewall con inspección TLS.
- Mínimas dependencias de terceros para facilitar la auditoría y el mantenimiento.
Decisiones
- 01
Turnos como entidad de negocio, con cierre atómico
El cierre de turno congela la conformación del equipo en una instantánea inmutable, así el historial no cambia si después cambia el personal.
Descartado
- Registrar eventos sueltos y reconstruir los turnos al consultar
- 02
Tiempo real con WebSockets validando el origen
Varias personas trabajan sobre el mismo turno a la vez; los cambios llegan al instante y la validación de origen evita el secuestro de la conexión.
Descartado
- Consultar al servidor cada pocos segundos
- 03
Lector y escritor de .xlsx propios sobre zlib
El reporte oficial debía salir idéntico a la plantilla de Excel sin sumar librerías grandes al backend, que tiene solo 6 dependencias de producción.
Descartado
- Usar una librería de hojas de cálculo de terceros
- 04
Contrato de datos probado con el tablero de generación
Otro sistema en producción consume los eventos de la bitácora. Una prueba de contrato falla si cualquiera de los dos lados cambia la forma de los datos, y cada sistema escribe solo en su propio esquema.
Descartado
- Dejar que el tablero lea directamente las tablas de la bitácora
Arquitectura
Usuarios
- Aplicación web de operaciónReact, vistas por cargo y por planta
Servicios
- API de bitácorasExpress, 19 módulos de dominio
- Canal en tiempo realWebSockets con validación de origen
- Procesos programadosCierre de turno, ingesta horaria y despacho
Datos
- SQL ServerCatálogos y transacciones en esquemas separados
- Reporte oficial en ExcelGenerado desde los datos
Integraciones
- Microsoft Entra IDInicio de sesión y roles por cargo
- Historiador de plantaConsumo de combustible por hora
- Tablero de generaciónConsume eventos por contrato
Cómo se mueven los datos
- Aplicación web de operaciónhaciaAPI de bitácorasRegistra eventos y cierra turnos
- Canal en tiempo realhaciaAplicación web de operaciónAvisa cambios de turno y usuarios activos
- API de bitácorashaciaSQL ServerGuarda cada asiento con su turno
- API de bitácorashaciaMicrosoft Entra IDValida la sesión y los permisos
- Historiador de plantahaciaProcesos programadosEntrega el consumo de cada hora
- API de bitácorashaciaReporte oficial en ExcelArma el libro del día
- Tablero de generaciónhaciaAPI de bitácorasConsulta eventos por periodo
Resultados
- Las dos plantas registran sus turnos en la aplicación, con el historial de cada turno congelado al cerrarlo.
- El reporte oficial del día sale de los datos con el formato de la plantilla, sin copiar celdas a mano.
- El tablero de generación consume los eventos de la bitácora por un contrato con pruebas, sin acceder a sus tablas.
Qué haría distinto
- Priorizaría desde el primer día las pruebas que protegen invariantes peligrosas, como no borrar nunca datos de una planta real, por encima de la cobertura total.
- Sacaría antes los procesos programados a un servicio aparte, para poder reiniciar la API sin pausar la ingesta de datos de planta.
Tecnologías
- React
- Vite
- Node.js
- Express
- WebSockets
- SQL Server
- Microsoft Entra ID
- Microsoft Graph
- Excel
- Linux
- nginx
- systemd