Volver al inicio

Motor de cálculo unificado para Next.js y Flutter

Artículo sobre cómo el autor sincronizó la lógica de cálculo entre un sitio web Next.js y una app móvil Flutter. Describe un enfoque usando especificaciones JSON como una sola fuente de verdad, generación de código y pruebas de paridad para asegurar resultados idénticos.

Cómo un archivo JSON salvó a dos entornos de ejecución de discrepancias
Advertisement 728x90

# Motor de Cálculo Unificado para Next.js y Flutter: Cómo Evitar Discrepancias en los Números

Cuando existe la misma calculadora de construcciones tanto como una app móvil en Flutter como un sitio web en Next.js, incluso diferencias menores en las fórmulas pueden socavar la confianza del usuario. Un caso real lo demostró: si la app y el sitio producen volúmenes diferentes de hormigón para un poste de valla, no es solo un error, sino un problema sistémico de lógica duplicada. La solución: una única fuente de verdad basada en especificaciones declarativas en JSON y pruebas de paridad.

Problema de Dos Bases de Código Independientes

Inicialmente, la lógica de cálculo se implementó dos veces: en Dart para la app de Flutter y en TypeScript para el sitio de Next.js. Ambos proyectos evolucionaron en paralelo, pero de forma independiente. Los coeficientes, valores predeterminados (como el diámetro del agujero para un poste), reglas de redondeo y empaquetado de materiales vivían por separado en el código de cada entorno de ejecución. El resultado: discrepancias en las salidas para las mismas entradas.

Esta arquitectura viola el principio DRY (No te repitas) y genera deuda técnica que eventualmente sale a la luz a través de quejas de usuarios. Es especialmente crítico para herramientas de nicho donde la precisión del cálculo impacta directamente en la confianza en el producto.

Google AdInline article slot

Enfoque Declarativo: JSON como Fuente de Verdad

En lugar de duplicar la lógica de negocio, todos los parámetros variables se movieron a archivos JSON estructurados: uno por calculadora. Cada especificación contiene:

  • Valores predeterminados para campos de entrada (p. ej., diámetro de pila: 150 mm)
  • Reglas de redondeo (siempre hacia arriba)
  • Coeficientes de pérdida según el modo de precisión
  • Información de empaquetado de materiales (bolsas de 25 kg, rendimiento de 0,01 m³ por bolsa)
  • Grosor mínimo de capas y espaciados de fijaciones

Estos archivos JSON se convirtieron en la única fuente de verdad. Ahora, cualquier cambio de parámetro se hace una sola vez, en JSON, y se aplica automáticamente en ambos entornos de ejecución.

Generación de Código para la Sincronización

Para asegurar que ambos proyectos usen los mismos datos, se introdujo un proceso de generación de código:

Google AdInline article slot
  • Al cambiar las especificaciones JSON, se ejecuta el script npm run sync:specs
  • El script lee todas las especificaciones y genera un archivo Dart con un mapa constante (const Map)
  • El archivo generado se confirma en el repositorio de la app Flutter
  • CI/CD para ambos sistemas verifica cambios y despliega versiones actualizadas

El archivo generado se marca como @generated y las ediciones manuales se bloquean con el linter. Esto elimina errores humanos y asegura consistencia de datos.

Pruebas de Paridad: Protección contra Discrepancias Lógicas

Incluso con datos idénticos, las diferencias de lenguaje pueden causar variaciones de comportamiento: Math.ceil() en TypeScript y num.ceil() en Dart pueden diferir en casos límite. Para evitarlo, se implementó un sistema de pruebas de paridad:

  • Un conjunto de fixtures: docenas de combinaciones de entradas para cada una de las 61 calculadoras
  • El motor en TypeScript ejecuta todas las fixtures y guarda resultados en un archivo de referencia
  • El mismo archivo se usa en el repositorio Flutter para comparar con los resultados del motor Dart
  • Cualquier discrepancia, incluso en el último decimal, falla en CI

En seis meses, estas pruebas detectaron tres discrepancias reales que habrían pasado desapercibidas sin verificaciones automáticas.

Google AdInline article slot

Tres Modos de Precisión en Lugar de «Más 10 %»

Las calculadoras tradicionales suelen usar un factor de seguridad universal (p. ej., +10 %). Este atajo introduce imprecisiones: los azulejos necesitan margen de corte, el yeso compensación por irregularidades de base y el adhesivo por absorción de superficie.

En su lugar, se implementaron tres modos de cálculo:

  • Básico—cálculo basado en estándares sin márgenes, según GOST/SP
  • Realista (predeterminado)—considera condiciones típicas de renovación de apartamentos
  • Profesional—márgenes máximos para proyectos complejos y garantías de escasez

Los coeficientes para cada modo también se almacenan en especificaciones JSON, permitiendo cambios sin recompilar apps.

Regla clave: para entradas idénticas, los resultados deben satisfacer Básico ≤ Realista ≤ Profesional. Una prueba dedicada en CI verifica esto para todas las calculadoras.

Validadores como Segunda Línea de Defensa

Más allá de pruebas unitarias y de paridad, CI ejecuta tres validadores especializados:

  • Validador lógico: asegura que la cantidad de compra ≥ cantidad neta, los resultados no se anulan con entradas válidas, las etiquetas usan unidades métricas correctas («m²», no «sq m»)
  • Validador de empaquetado: confirma empaquetados realistas de materiales (adhesivo en cubos de 5/10/15 L, azulejos en paquetes, no individuales)
  • Validador de unidades: detecta confusiones en el sistema métrico (p. ej., sumar milímetros a metros sin conversión)

Estos scripts actúan como un «punto de control de seguridad» en la puerta del sistema: no reemplazan las pruebas unitarias, pero previenen errores tontos pero críticos a nivel de ecosistema.

Lecciones Clave

  • Única fuente de verdad vía especificaciones JSON elimina duplicación de parámetros entre entornos de ejecución.
  • Generación de código asegura sincronización de datos sin intervención manual.
  • Pruebas de paridad garantizan resultados idénticos en Dart y TypeScript.
  • Tres modos de precisión reemplazan el simplista «+10 %» y dan control al usuario sobre los márgenes.
  • Validadores especializados en CI protegen contra errores sistémicos que las pruebas unitarias podrían pasar por alto.

— Editorial Team

Advertisement 728x90

Leer después