Saltar al contenido
juancespedes.dev
Todos los proyectos
Caso de estudioAnonimizado

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

  1. 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
  2. 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
  3. 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
  4. 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

El navegador de cada operador habla con una API en Node.js por HTTPS y por WebSockets. La API guarda todo en SQL Server, corre procesos programados que cierran turnos e ingieren datos de planta, y expone un contrato de datos al tablero de generación.
  1. Usuarios

    • Aplicación web de operaciónReact, vistas por cargo y por planta
  2. 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
  3. Datos

    • SQL ServerCatálogos y transacciones en esquemas separados
    • Reporte oficial en ExcelGenerado desde los datos
  4. 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

  1. Aplicación web de operaciónhaciaAPI de bitácorasRegistra eventos y cierra turnos
  2. Canal en tiempo realhaciaAplicación web de operaciónAvisa cambios de turno y usuarios activos
  3. API de bitácorashaciaSQL ServerGuarda cada asiento con su turno
  4. API de bitácorashaciaMicrosoft Entra IDValida la sesión y los permisos
  5. Historiador de plantahaciaProcesos programadosEntrega el consumo de cada hora
  6. API de bitácorashaciaReporte oficial en ExcelArma el libro del día
  7. 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