Dashboard de KPIs para un laboratorio de geotecnia


Dashboard de KPIs geotécnicos — 21 páginas en producción
Vista del dashboard en producción

Contexto

En un laboratorio de investigación y ensayos, el área de geotecnia procesa cientos de ensayos al mes: clasificación de suelos, ensayos de compactación, ensayos triaxiales, entre otros. Cada ensayo pasa por un flujo largo —recepción, ejecución, control de calidad, informe— y cada etapa genera datos en sistemas distintos.

Los jefes de área querían saber cosas como “cuántos ensayos de compactación estamos procesando esta semana”, “cuál es el tiempo promedio desde recepción hasta informe” o “qué técnico tiene más carga hoy”. No tenían forma de responder esas preguntas sin pedir reportes manuales.

El problema

El problema no era falta de datos —los datos existían— sino falta de integración. Había tres sistemas distintos involucrados:

  • MongoDB: sistema operativo principal del laboratorio
  • PostgreSQL: capa analítica derivada del operativo
  • SQLite: base local con datos de configuración y reglas de negocio específicas del área

Además, algunas métricas críticas (tiempos por etapa, carga por persona) no estaban pre-calculadas en ninguna parte. Había que construirlas al vuelo.

Decisiones de arquitectura

Por qué Streamlit y no una app web “seria”

Evalué dos caminos: construir una aplicación web completa (FastAPI

  • frontend JS) o usar Streamlit. Elegí Streamlit por razones de contexto:
  • Audiencia pequeña y conocida: ~15 personas del área, no público general. No justificaba el costo de construir frontend.
  • Iteración rápida: cuando un jefe pide “agrégame una página con X”, en Streamlit eso es un archivo nuevo en 30 minutos.
  • Equipo de mantenimiento: quien hereda el proyecto es analista de datos, no desarrollador web. Streamlit se aprende en una tarde.

El costo a pagar es escalabilidad limitada. Si mañana necesitara soportar 500 usuarios concurrentes, tendría que migrar. Para 15 usuarios internos, no es un problema.

Por qué tres bases de datos

Podría parecer sobrediseño, pero cada una tiene razón de estar:

  • MongoDB es la fuente de verdad operativa. No la toco para escritura.
  • PostgreSQL es la capa analítica previamente descrita en otro proyecto. Datos limpios, con joins eficientes.
  • SQLite contiene configuración local: reglas de negocio específicas del área, tablas de mapeo, parámetros que cambian trimestralmente. Separarlo permite versionarlo con git y modificarlo sin tocar los sistemas mayores.

Estrategia de actualización

Los KPIs del día no necesitan ser en tiempo real, pero tampoco pueden tener un día de retraso. La solución: cron nocturno que recalcula agregados a las 3 AM. El dashboard lee esos agregados, no las tablas transaccionales. Trade-off aceptado: los datos son del día anterior, pero las páginas cargan en menos de un segundo.

Stack

  • Python 3.11 como lenguaje base
  • Streamlit para la interfaz
  • SQLAlchemy para PostgreSQL y SQLite
  • PyMongo para lectura de MongoDB
  • Plotly para visualizaciones interactivas
  • Pandas para transformaciones en memoria
  • Cron del sistema para actualizaciones programadas

Aprendizajes

Tres cosas que cambiaría o aprendí en el camino:

1. La caché de Streamlit importa más de lo que parece. Al principio el dashboard era lento porque cada interacción re- consultaba la base. Con el uso estratégico de @st.cache_data y @st.cache_resource la velocidad mejoró notablemente sin cambiar nada más.

2. Las 21 páginas aparecieron gradualmente, no por diseño. Al inicio eran 5. Los usuarios pidieron más a medida que veían utilidad. En el próximo rediseño agruparía las páginas por rol (laboratorista, ingeniero, jefe de área) en vez de por tipo de análisis.

3. Un dashboard en producción no es un dashboard “terminado”. Requiere mantenimiento continuo: nuevas reglas de negocio, métricas que cambian, feedback de usuarios. Eso es parte del trabajo, no un fracaso del diseño inicial.

El resultado: 21 páginas en uso diario, dejaron de pedirse los reportes manuales que antes consumían medio día semanal.