4rch1.tech  Ingeniería de software
Confidencial · Auditoría
Auditoría técnica · Proyecto UPBANC

Por qué los
módulos no cuadran

Diagnóstico en lenguaje simple y plan de solución.

Nos contactaron porque, al cargar datos en UPBANC, lo que se registra en un lugar no se refleja en otro. Auditamos el sistema completo —código y base de datos— y la causa está identificada y tiene solución.

Los módulos no cuadran porque la app tiene dos cerebros que calculan distinto, y varios módulos son islas que no se hablan entre sí.

Cliente
UPBANC · sistema contable de bancas
Preparado por
4rch1.tech · equipo de ingeniería
Fecha
18 de junio de 2026
Alcance
Código + base de datos
01 — La raíz del problema

Dos cerebros, una contradicción

El sistema calcula los mismos números en dos lugares distintos que no están de acuerdo. No es un dato que se pierda al azar: es un desacuerdo estructural entre lo que piensa el navegador y lo que dicta la base de datos.

Cerebro A

El navegador · la app
arrastre = saldo_local + ajustes_js
$ A recalcula por su cuenta, en JavaScript
No
coinciden

Cerebro B

La base de datos · el servidor
arrastre = f(cuadres_cerrados)
$ B la fuente que debería mandar

Mientras los dos cerebros sigan calculando por separado, los números van a seguir sin cuadrar sin importar cuántas veces se corrijan a mano.

02 — Qué está pasando

Diagnóstico

Seis hallazgos confirmados en el código. El primero, además, quedó confirmado con datos de tu base real. Toca cada uno para ver el detalle.

Todos6
Críticos3
Medios3
Crítico El arrastre (carryover) no se actualiza Confirmado +

Al cerrar un cuadre, la app lo guarda con un estado que la base no reconoce como "cerrado". El mecanismo que recalcula el arrastre del grupo solo se dispara con el estado correcto, así que no corre.

ResultadoCada semana arranca con un arrastre viejo y las semanas no cuadran. Señal de alarma: ya existen 4 correcciones históricas de este mismo punto.
Crítico Los gastos se leen como ingresos (signo invertido) +

Al traer los movimientos desde la nube, el tipo de gasto se interpreta mal y se cuenta como dinero que entra en vez de salir.

ResultadoEl efectivo se infla y la lista de movimientos no cuadra con los saldos.
Crítico El cierre de cuadre no es atómico +

La app arma el cierre por partes —guarda el cuadre, crea el movimiento y crea la cuenta por cobrar en pasos separados— en vez de usar la función oficial que lo hace todo de una sola vez.

ResultadoSi falla a la mitad, el cuadre queda guardado a medias.
Medio Módulos isla: los cierres diarios no alimentan nada +

Al guardar un cierre diario no se genera movimiento de caja ni se alimenta el cuadre semanal.

ResultadoQuien los registra esperando que el cuadre o el efectivo cambien, no verá reflejo: hay que volver a teclear los totales.
Medio La clasificación financiera se pierde en la nube +

El dato de clasificación de cada salida de dinero se descarta al guardar y se "adivina" al cargar.

ResultadoLos reportes de fugas de dinero salen distintos cada vez.
Medio Vocabulario y roles desalineados +

Las capas usan palabras distintas para lo mismo (estados como confirmado / cerrado / anulado) y roles distintos (owner/cashier vs administrador/cajero).

ResultadoComportamientos inconsistentes entre módulos.
02·b — La prueba

Evidencia: tu base real

No es una teoría. Esta consulta corrió sobre tu base de datos de producción el 18 de junio de 2026.

● Consulta #3 ejecutada 18 jun 2026 · public.weekly_settlements
select status, count(*) from public.weekly_settlements group by status;
confirmed
4
pending
9
closed
0
0 en "closed"

Los cierres se guardan como "confirmed", así que el disparador del arrastre —que espera "closed"— nunca corre. Además, 9 de 13 cuadres quedaron incompletos (pending). El síntoma reportado queda confirmado con datos reales.

03 — Una duda importante

¿Y si la base de Crisgeury ya está bien?

Es la pregunta correcta, y la respuesta sorprende. Mueve el interruptor y mira qué cambia.

Supongamos que la base de datos está perfecta…
Base con errores

✓ Qué resuelve la base correcta

  • Existen los cálculos del lado servidor
  • Existen los permisos y roles definidos
  • Existen las funciones oficiales

✕ Qué sigue roto igual

  • El signo invertido de los gastos
  • Los cierres diarios isla
  • Los reportes calculados en JavaScript
  • El desajuste de vocabulario
Con la base correcta el arrastre se rompe con MÁS seguridad. El mecanismo bueno espera "cerrado" para recalcular, pero la app envía "confirmado". Cuanto mejor esté la base, más garantizado queda que ese paso nunca corra. La pregunta de fondo no es si la base está bien, sino si la app y la base están de acuerdo en las mismas reglas. Hoy no lo están.
04 — Cómo se resuelve

Plan de solución

Supabase como única fuente de verdad

El principio que guía todo el plan: la base de datos calcula; la app solo muestra y envía. Se elimina el cálculo duplicado del navegador.

Orden de impacto: empezar por los pasos 1 y 2 —arreglan arrastre, atomicidad y cuentas por cobrar con poco riesgo. Luego el 3 (signo de los gastos). El paso 0 es requisito de todo.
05 — Cómo confirmar el estado de la base

Consultas de verificación

La consulta #3 ya confirmó el problema. Faltan tres consultas de solo lectura para cerrar el diagnóstico al 100%. Pídele a Crisgeury, dueño del repositorio, que las corra en su Supabase.

06 — Próximos pasos

Por dónde seguimos

  1. Confirmar el estado real de la base con las consultas de verificación.
  2. Aplicar los pasos 1 y 2 (mayor impacto, menor riesgo).
  3. Corregir el mapeo del frontend (paso 3) y conectar las islas (paso 4).
  4. Verificar con datos reales que dashboard, cuadres y reportes coinciden.