Todas las empresas con las que trabajé tienen un sistema así. Para un cliente, era un sistema de facturación escrito en VB.NET a principios de la década de 2010, que manejaba el cálculo de impuestos, las reglas de descuento y los totales de línea de cada factura que la empresa emitía. Funcionaba. Había funcionado durante años. Y cuando entró en vigencia una nueva norma impositiva provincial y el equipo de finanzas necesitó que se cambiara un solo número, el equipo de desarrollo pasó casi tres semanas sin atreverse a tocarlo.
No porque la corrección fuera difícil. El cambio real eran un puñado de líneas. El miedo era por todo lo que rodeaba a esas líneas: nadie del equipo actual había escrito el sistema original, no había documentación que describiera qué se suponía que debía hacer, y no había pruebas automatizadas que avisaran si esa corrección "chica" rompía una regla de descuento que venía funcionando, en silencio, desde 2013. Todos podían ver el código. Nadie podía demostrar, con alguna confianza, qué iba a pasar si lo cambiaban.
Ese miedo es común, y es completamente racional. También tiene solución, y la solución no es "migrarlo" ni "reescribirlo en C#". Esas decisiones vienen después, si es que llegan a tomarse. Lo que viene primero es más chico de lo que la mayoría de los equipos espera.
Por qué el miedo es racional
Un sistema se vuelve temible de tocar cuando se cumplen tres cosas a la vez: nadie entiende del todo qué hace, no existe un registro escrito de qué se supone que debe hacer, y no hay ninguna red de seguridad que detecte un error antes de que lo detecte un cliente. Los sistemas en VB.NET de esa época suelen reunir las tres cosas, no porque VB.NET sea un mal lenguaje —es perfectamente capaz, y Microsoft todavía lo sigue soportando—, sino porque los sistemas escritos en ese período, con ese estilo, casi nunca venían con pruebas automatizadas, y el único desarrollador (o los dos) que conocía las reglas de negocio de memoria, en general, ya cambió de puesto, ascendió, o se alejó por completo de esa parte del código.
Sumado todo, cada cambio se convierte en una apuesta basada en la memoria y en la esperanza, en lugar de en evidencia. Eso no es un defecto del equipo. Es una respuesta completamente razonable frente a algo que nadie puede verificar.
Qué significa realmente "volver a hacerlo seguro"
Hacer que un sistema sea seguro de tocar no significa modernizarlo, y no significa entender cada línea antes de tener permiso para cambiar algo. Significa dos cosas concretas, hechas en este orden, antes del próximo cambio:
Primero, escribir pruebas sobre lo que el sistema hace hoy, no sobre lo que alguien supone que hace. Suena al revés si estás acostumbrado a probar código nuevo, pero para un sistema existente, el objetivo no es probar un diseño ideal. Es capturar su comportamiento real, actual: dada esta factura, con estos ítems y esta regla impositiva, el sistema produce este total, hoy. Esas pruebas no son un juicio sobre si la lógica es buena. Son una alarma. Si un cambio futuro produce un número distinto, algo se rompió, y lo vas a saber antes que la factura de un cliente.
Segundo, documentar qué hace realmente el sistema, por separado de qué supone la gente que hace. En casi todos los sistemas legacy que auditè, hay una brecha entre las dos cosas: una regla de descuento que técnicamente sigue aplicándose bajo una condición que nadie recuerda haber configurado, un cálculo de impuestos que redondea distinto de lo que dice la especificación por una corrección hecha hace años que nunca se anotó. Escribir el comportamiento real, aunque sea brevemente, convierte un "creo que hace X" en "hace X, confirmado en esta fecha, y esta es la prueba que lo demuestra".
Una forma concreta de empezar
Para el sistema de facturación, no empezamos leyendo todo el código de punta a punta: eso es una tarea de varias semanas por sí sola, y posterga el objetivo real. Empezamos por las facturas que más importaban: el escenario impositivo de mayor volumen, el descuento más aplicado, el puñado de casos límite que el equipo de finanzas ya sabía que eran complicados. Para cada uno, escribimos una prueba que ingresaba una factura conocida y verificaba el total correcto conocido. Eso nos dio unas quince pruebas en pocos días, cubriendo los escenarios con más probabilidad de romperse y más costosos de errar: no cobertura completa, pero protección real justo donde estaba concentrado el miedo.
Con eso en su lugar, la corrección impositiva que llevaba tres semanas trabada se resolvió en una tarde. No porque el código se haya vuelto más simple, sino porque el equipo finalmente tenía una forma de saber, de inmediato, si el cambio había roto algo que importara.
Por qué esto viene antes de cualquier decisión de migrar o reemplazar
Es tentador tratar "da miedo cambiarlo" como motivo para reescribir todo en un lenguaje más nuevo. A veces, con el tiempo, esa es la decisión correcta. Pero decidir migrar o reemplazar un sistema que todavía no se entiende, sin pruebas que describan su comportamiento real, solo traslada el mismo riesgo a un proyecto más grande y más caro. Estaría reconstruyendo suposiciones, no requerimientos.
Las pruebas y la documentación del comportamiento real cumplen una doble función acá: hacen que el sistema existente sea seguro de mantener ahora mismo, y si más adelante sí ocurre una migración, se convierten en la especificación de lo que el sistema nuevo tiene que hacer. De cualquiera de las dos formas, la inversión no se pierde, y de cualquiera de las dos formas, tiene que suceder antes de la decisión grande, no después.
El sistema nunca fue realmente el problema
Nadie en ese equipo de finanzas estaba equivocado al ser cauteloso con un código que no entendía del todo y no podía verificar. Esa cautela estaba cumpliendo su función. Lo que cambió no fue el sistema en VB.NET en sí mismo —sigue corriendo exactamente la misma lógica que siempre—. Lo que cambió fue que el equipo finalmente pudo ver qué estaba haciendo, demostrarlo, y cambiarlo sin contener la respiración.
Eso es lo que significa "volver a hacerlo seguro" en la práctica: no una reescritura, no un salto de fe, solo evidencia donde antes solo había memoria.