Artículo

Quería un Gantt bonito

Cómo un ingeniero civil construyó Programa de Obra con agentes de IA y Bryntum Gantt sin ceder el modelo de dominio ni llenar el producto de funciones innecesarias.

RΞD Consultores·5 de octubre de 2026
De un reporte impreso del programa de obra al Gantt de presupuestos.red

Soy ingeniero civil. No soy programador profesional. presupuestos.red nació desde esa perspectiva: costos, presupuestos, análisis de precios unitarios y control de obra.

Cuando empecé a trabajar en Programa de Obra no estaba intentando demostrar nada sobre inteligencia artificial ni construir una plataforma completa de control integral de proyectos. La ambición inicial era más modesta: quería que el programa se pudiera ver bien.

OPUS y Neodata pueden contener programas perfectamente útiles, pero sus reportes de Gantt siempre me han parecido horrendos. presupuestos.red ya me permitía abrir un presupuesto y recorrer partidas, conceptos, análisis de precios unitarios, matrices e insumos de una forma que me resultaba mucho más natural. Quería hacer algo parecido con el programa.

Probé varias opciones. Highcharts, DHTMLX y Frappe Gantt pasaron por mis experimentos. Consideré hacer uno artesanal. Con los agentes que utilizo actualmente, construir una tabla con barras sobre un eje temporal no me parecía particularmente descabellado.

Si podía construir el Gantt, ¿por qué usar Bryntum?

Los agentes cambiaron radicalmente lo que puedo materializar.

Si hubiera intentado construir esta funcionalidad sin ellos, probablemente me habría tomado meses y no creo que hubiera llegado ni a la mitad de lo que existe hoy. Con agentes, en cambio, hacer mi propio Gantt sí era una alternativa real.

Creo que habría terminado teniendo uno. También creo que me habría detenido ahí: barras, tabla, scroll, dependencias básicas y mucho tiempo intentando que se viera bien.

Bryntum cambió ese límite.

Cuando lo evalué, buscaba principalmente UI. En la práctica terminé utilizando árbol jerárquico, columnas, dependencias, eje temporal, zoom, scroll, selección, histogramas y mecanismos para coordinar distintas vistas temporales.

Bryntum no hizo posible que existiera un Gantt. Hizo posible que el Gantt dejara de ser el proyecto.

Hay además una relación que conviene declarar desde aquí. Escribí a Bryntum explicándoles que era mi opción preferida y que el costo de licencia era el obstáculo para un proyecto gratuito como presupuestos.red. Poco después me ofrecieron una licencia complimentary de Bryntum Gantt por el primer año, condicionada a que el proyecto se mantuviera gratuito y no comercial. Un eventual lanzamiento comercial requeriría migrar a una licencia comercial. Como parte de esa conversación me comprometí, entre otras cosas, a documentar la integración y escribir sobre el caso. Este artículo forma parte de ese compromiso.

Para medir cuánto dependía de esa decisión, le pedí a un agente que investigara el historial del repositorio. No era el agente de la sesión original: reconstruyó el trabajo desde Git, documentación, pruebas y registros posteriores, distinguiendo lo demostrable de lo inferido.

Le pregunté qué habría que sustituir si quitáramos Bryntum pero quisiéramos conservar la experiencia actual. Su inventario incluía el árbol y las columnas, las dependencias, el eje temporal, zoom y desplazamiento, buena parte de la interacción y la coordinación de histogramas y otras vistas temporales.

Los conversores de OPUS y Neodata, el modelo del programa, los análisis de precios unitarios, las matrices, la demanda de recursos, las dotaciones, Flujo, Curva S y Rayos X seguirían en presupuestos.red.

Representar sin inventar

Antes de dibujar un programa hay que entender qué se dibuja: algo que parece obvio hasta que abres archivos reales.

En Neodata, algunas asociaciones que parecían naturales no eran suficientemente estables. Un código podía repetirse y otro identificador resultaba ser el que realmente conectaba las distintas estructuras del archivo. Era un problema de significado antes que de presentación.

Después apareció OPUS y rompió otra suposición. Nuestra primera representación permitía pensar el programa con periodos compartidos, algo razonable con los archivos que habíamos visto. OPUS mostró actividades con distribuciones propias y diferentes entre sí.

El modelo tuvo que cambiar.

Esperaba diferencias importantes entre dos sistemas que resuelven el mismo problema. La abstracción cambió cuando los datos la contradijeron.

presupuestos.red conserva su propia representación del Programa de Obra y sólo después la traduce a lo que el Gantt necesita. Esa separación permite que abrir un archivo conserve el significado del documento original.

Bryntum tiene un motor de planificación capaz de calcular fechas a partir de dependencias, restricciones y calendarios. En presupuestos.red, las fechas importadas siguen siendo las del documento. Las tareas se mantienen como programadas manualmente para aprovechar el motor y su representación sin cederle autoridad sobre el programa de origen.

La separación tuvo fallas. Durante un tiempo, un tipo de relación que no reconocíamos se convertía en una relación fin–inicio válida. La pantalla seguía funcionando. La corrección consistió en dejar de traducir como conocido aquello cuyo significado desconocíamos.

Una pantalla que parece correcta también puede contener una interpretación falsa.

El Gantt empezó a hacer preguntas

La relación entre un presupuesto y sus recursos no la descubrí construyendo Programa de Obra.

Un concepto tiene una cantidad. Su análisis de precio unitario contiene materiales, mano de obra, maquinaria y otros componentes. Si sé cuánto voy a ejecutar, puedo calcular cuánto recurso representa. Eso es parte normal de la ingeniería de costos.

Lo diferente fue verlo sobre el tiempo.

Una actividad ya no era sólo una barra entre dos fechas. Tenía una cantidad, una matriz con consumos y una distribución temporal. La pregunta dejó de ser únicamente cuánto acero, cuántas horas de retroexcavadora o cuánta mano de obra contenía el presupuesto. También podía preguntar cuándo estaba diciendo el programa que los iba a necesitar.

De ahí salieron los histogramas de recursos.

Bryntum pone el eje temporal y la interacción. presupuestos.red convierte cantidades y matrices en requerimientos. El cálculo de cuánta maquinaria o mano de obra implica una actividad viene del presupuesto.

Una vez que el requerimiento estuvo dibujado, apareció otra pregunta: ¿por qué?

Puedo ver una carga alta de maquinaria en una semana determinada. Para control de obra resulta mucho más útil saber qué actividades la están provocando.

De ahí salió lo que terminamos llamando Rayos X.

Seleccionas un recurso y un periodo, y puedes regresar hacia las actividades que contribuyen a ese requerimiento. Desde una de ellas puedes volver al concepto y a su análisis de precio unitario.

Gantt e histograma de maquinaria con Rayos X mostrando las actividades que contribuyen al requerimiento de un vibrocompactador

Ya sabía que las matrices contienen recursos. Lo que cambió fue poder ver una consecuencia temporal que antes permanecía enterrada dentro del presupuesto. Saber que varias actividades utilizan el mismo tipo de equipo es distinto de verlas coincidir en el mismo periodo y observar la demanda agregada que el programa implica.

Muchos programas de obra pueden construirse sin confrontar esa pregunta. Un Gantt puede verse perfectamente razonable aunque nadie haya revisado qué implica la combinación simultánea de actividades desde los recursos.

Todavía no estoy completamente satisfecho con nuestra solución. Recursos y cuadrillas necesitan trabajo, y partes de la interfaz siguen siendo confusas.

Hay una razón de fondo. Demanda no es disponibilidad. Que mi programa implique tres equipos trabajando simultáneamente no significa que tenga tres equipos. Demanda tampoco es asignación, y un requerimiento matemático de mano de obra no necesariamente representa cómo una constructora organizará sus cuadrillas.

Generar más código no resuelve esa ambigüedad. Primero hay que decidir qué puede afirmar realmente el producto.

Fue precisamente tratando de automatizar la verificación de una de esas lecturas de recursos donde apareció uno de los mejores ejemplos que tengo de por qué necesito restringir a los agentes.

El código que no debía existir

Durante las pruebas de Rayos X apareció un botón tentador:

Ver causa del pico.

Como función de producto suena impecable. Sólo que el código no encontraba el pico, sino que seleccionaba la primera fila utilizable y el primer periodo cuyo valor fuera mayor que cero. No calculaba ningún máximo.

La acción funcionaba y permitía a la prueba llegar cómodamente al siguiente estado. La etiqueta, sin embargo, prometía un cálculo que no existía.

Quitamos el botón. La prueba terminó interactuando con una barra real del histograma, igual que lo haría un usuario.

El resultado inicial era razonable, y por eso era difícil de detectar. Si no conoces suficientemente el dominio o no te detienes a preguntar qué significa una etiqueta, puedes acabar con software bien implementado que no debería existir.

La limpieza de nuestras pruebas end-to-end mostró algo parecido a mayor escala. Teníamos 2,256 líneas de E2E y después quedaron 804. El número por sí mismo importa poco. Muchas de esas líneas protegían geometría, posiciones, timers internos, estructura del DOM y otros detalles de implementación convertidos en contratos permanentes.

La verificación quedó más centrada en el comportamiento del producto y menos en su estructura interna. Desde entonces intento reservar las pruebas completas de navegador para recorridos o integraciones que realmente necesitan comprobarse ahí.

Mi insistencia en DRY, YAGNI y KISS viene de experiencias como ésta. Los uso como restricciones a la generación.

Ya me ha ocurrido varias veces que un agente construye como si estuviera diseñando infraestructura para un hyperscaler. Tiene cierta lógica: si otra abstracción, otra capa o veinte pruebas adicionales cuestan minutos de inferencia en lugar de semanas de un equipo, el incentivo cambia.

La generación se vuelve barata. La permanencia de todo lo generado no.

Una vista se convierte en un sistema

Programa de Obra creció al ritmo de las preguntas: ver los recursos en el tiempo llevó a preguntar cómo se distribuía el costo. De ahí salieron Flujo y la Curva S.

La distribución económica y el acumulado se calculan en presupuestos.red. Bryntum aporta el eje, la geometría y las superficies temporales donde se presentan.

Después apareció otra clase de dificultad.

Cuando sólo había un Gantt, bastaba con que el Gantt funcionara. Con Gantt, recursos, Rayos X, Flujo y Curva S, el usuario espera conservar el contexto al moverse entre vistas. Si estoy mirando una actividad, cierta fecha o un concepto, cambiar de representación no debería obligarme a empezar de nuevo.

El trabajo dejó de ser construir otra gráfica y pasó a incluir continuidad de selección, tiempo y navegación.

La integración también tuvo tropiezos. Algunas configuraciones parecían correctas y no se aplicaban. En otros casos una vista desaparecía mientras otra operación todavía intentaba actualizarla, con pérdidas de foco, selección o contexto temporal.

En la práctica, los agentes pudieron apoyarse en documentación por versión, ejemplos y una API explícita. Aun así, en una de las primeras integraciones ciertas opciones parecían bien configuradas pero eran ignoradas porque el wrapper esperaba que se declararan de otra forma.

Usar una librería profesional evitó reconstruir mucha mecánica del Gantt. La parte restante fue aprender a encajar sus reglas con las nuestras.

Hay además una sutileza que me importa especialmente desde costos: coherencia no significa que todas las vistas tengan que dar el mismo número. Gantt, Flujo, recursos y Curva S pueden responder preguntas distintas e incluso trabajar con bases económicas distintas. Lo que sí tienen que conservar es una referencia coherente al mismo documento, las mismas actividades y el mismo tiempo. Obligar a dos cifras diferentes por naturaleza a coincidir sería tan incorrecto como permitir que dos vistas que deberían compartir una actividad hablen de cosas distintas.

Flujo de importes programados por actividad y periodo, junto a la Curva S del acumulado

Que puedas construirlo no significa que debas hacerlo

Una librería grande y un agente capaz tienen algo en común: ofrecen muchas posibilidades.

Bryntum puede hacer bastante más de lo que usamos. Los agentes también pueden construir mucho más de lo que hoy existe en presupuestos.red. De ahí salen tentaciones previsibles: editar actividades, activar más planificación, calcular CPM, modelar asignaciones o disponibilidad.

Que tengas algo no significa que debas usarlo.

Si presupuestos.red desconoce cuántas excavadoras posee una empresa, mostrar disponibilidad exigiría inventar datos. Si todavía no tengo una definición suficientemente general de cuadrilla entre presupuestos distintos, otra capa de código no arregla esa ambigüedad. Y mientras el objetivo sea leer fielmente un programa, convertirlo en editor tampoco aporta por sí mismo.

Aquí mi papel se vuelve evidente.

Desde diciembre de 2025 no leo código. Mi control de calidad ocurre en otra capa: uso el producto con archivos que conozco, confronto los resultados con el origen y con casos de control, y pido evidencia que pueda revisar —conteos, diferencias, invariantes, fixtures y auditorías reproducibles—. Cuando algo no me convence, otro agente puede inspeccionar la implementación, reconstruir el cálculo o intentar contradecir al primero.

Los agentes se encargan de leer el repositorio, investigar e implementar. También prueban y auditan. Yo defino el problema, aporto el conocimiento de construcción y costos, cuestiono las interpretaciones, pruebo el resultado y fijo restricciones. Y, lo más importante: decido cuándo dejar de construir.

La ingeniería de software sigue importando. Estoy delegando una parte de ella, y esa delegación puede producir resultados técnicamente correctos con un significado equivocado o resolver necesidades que nunca existieron.

Este caso tampoco demuestra que cualquiera pueda construir cualquier software mediante IA. Demuestra algo más acotado: hoy puedo dirigir la construcción de software que hace pocos años hubiera estado muy por encima de mi capacidad individual de implementación, siempre que pueda aportar el dominio, las restricciones y una forma seria de verificar el resultado.

Sigue en construcción

Programa de Obra hoy es mucho más que el Gantt bonito que quería construir.

Puedo abrir un presupuesto, recorrer su programa, relacionar actividades con sus análisis, ver cómo aparecen los recursos en el tiempo, investigar qué actividades contribuyen a ciertos requerimientos y revisar cómo se distribuye y acumula el importe programado.

Recursos y cuadrillas todavía necesitan trabajo. Hay partes de la UI que siguen siendo confusas. El modelo ya cambió porque nuevos archivos contradijeron nuestras primeras abstracciones, y también hemos eliminado código que poco antes parecía razonable.

Eso seguramente volverá a ocurrir.

En este proyecto, los agentes no hicieron menos valiosa una librería profesional. Bryntum me permitió concentrar menos esfuerzo en reconstruir la mecánica del Gantt y más en las preguntas específicas del producto: qué dicen juntos el presupuesto, el programa, los recursos y el tiempo. El Gantt era sólo el punto de entrada.

La parte que sigo sin poder delegar del todo es decidir qué significa el producto y qué vale la pena construir.

Siguiente lectura recomendada

Sin instalación · Sin registro

¿Listo para abrir tu presupuesto?

Compatible con OPUS y Neodata. Solo arrastra tu archivo.

Abrir el visor