analytics
Portafolio de Iván
Proyectos chevron_right La bodega que dice la verdad

Sistema en producción · v2.19

wifi_off Offline-first history Event sourcing qr_code_scanner Escáner + NFC science ~30 suites de test

La bodega que dice la verdad: PWA offline-first con event sourcing

En una bodega no hay wifi estable ni tiempo para esperar a que cargue una pantalla. Esta PWA guía el escaneo de envíos, cuenta el inventario por ubicaciones y guarda cada acción como un evento que se puede volver a reproducir.

Cifras clave

3,536

eventos reales reproducidos para validar una corrección

512 = 512

unidades enviadas y descontadas tras el arreglo

v2.19

versión en producción

~30

suites de prueba propias

Stack

ViteReact 18TypeScriptvite-plugin-pwapdfjs-distBarcodeDetectorzxing-wasmWeb NFC
schema

Por qué el registro es de eventos y no de saldos

La aplicación no guarda «cuántas piezas hay». Guarda todo lo que pasó, en orden, y calcula el saldo al reproducirlo. Cambiar la regla y volver a reproducir es lo que permitió demostrar que la corrección funcionaba.

touch_app 1 · Acción

Alguien escanea una caja

Cada acción de la operación se convierte en un evento con su hora, su ubicación y su cantidad.

save 2 · Registro

El evento se guarda, no se pisa

Almacenamiento local versionado que sobrevive a la pérdida de red y al cierre del navegador.

replay 3 · Replay

El saldo se calcula reproduciendo

El estado actual es el resultado determinista de reproducir la historia completa.

fact_check 4 · Prueba

Una corrección se demuestra

Se cambia la regla, se reproduce la historia real y se comparan los dos resultados.

store

Contexto

El mismo negocio del centro de operaciones tiene una bodega física con cajas, ubicaciones y un flujo constante de envíos al programa de logística del marketplace. Cada envío llega con un PDF de instrucciones, exige etiquetas y obliga a verificar pieza por pieza antes de que la caja salga.

La aplicación —el equipo la llama «Central»— hace tres cosas: prepara y verifica esos envíos, lleva el inventario físico por ubicaciones y arma cotizaciones. Se instala en el teléfono y funciona sin conexión, porque en una bodega la señal es una cortesía, no una garantía.

El detalle importante: quien la usa tiene las manos ocupadas. Cualquier fricción —un botón mal puesto, un paso que exige leer— se traduce en cajas mal contadas.

report

El problema

512 unidades salieron de la bodega. El inventario descontó 408.

Ciento cuatro piezas se habían ido físicamente y el sistema las seguía contando como disponibles. No es un error de redondeo: es exactamente el tipo de discrepancia que provoca vender lo que ya no existe.

Encontrar la causa fue una cosa; demostrar que el arreglo servía era otra. Con un sistema que guarda saldos, la única prueba posible es «ahora sí cuadra», que no dice nada sobre los datos viejos. Y volver a contar la bodega entera para comprobarlo no era una opción realista.

Había un segundo problema, más silencioso: la escalera de lectores de código. En algunos teléfonos Android el lector nativo del navegador deja de funcionar sin avisar —no falla, simplemente devuelve cero códigos para siempre— y el operador se queda apuntando la cámara a una etiqueta que nunca se lee.

rule

Decisiones clave

01 Guardar eventos, no saldos

La aplicación registra cada acción como un evento y calcula el estado reproduciéndolos en orden. El almacenamiento local va versionado para poder migrar la historia sin perderla.

psychology Porque permite hacer justo lo que hizo falta: corregir la regla, reproducir 3,536 eventos reales y comprobar que ahora 512 enviadas descuentan 512, sin una sola caja en negativo. Un registro de saldos no habría podido probar nada.

02 Un conteo es una observación, no un movimiento

El enganche entre inventario y bodega está cableado a nivel de pantalla, con una prueba dedicada que lo sostiene, en vez de vivir en la capa compartida del escáner.

psychology Si viviera en la capa común, cada conteo de inventario se comportaría como una salida de mercancía y vaciaría cajas en silencio. Contar lo que hay y sacar lo que se va son dos hechos distintos, y el sistema tiene que distinguirlos aunque el gesto físico se parezca.

03 «Sin etiqueta» es una cantidad, no un sí o un no

Las piezas sin etiquetar se modelan como un número de piezas sueltas por ubicación, no como una casilla marcada en el producto.

psychology Porque un mismo producto puede tener piezas etiquetadas en una caja y sin etiquetar en otra al mismo tiempo. Un booleano obliga a mentir en una de las dos ubicaciones, y esa mentira reaparece semanas después como un descuadre sin explicación.

04 Detectar el silencio del escáner

La cadena de lectura va del lector nativo del navegador a WebAssembly y de ahí a una tercera implementación. El sistema mide el silencio —más de 40 intentos y 8 segundos sin una sola lectura— y conmuta solo al siguiente lector.

psychology El fallo no lanza ningún error: el lector nativo simplemente deja de encontrar códigos. La única señal disponible es la ausencia de resultados, así que hay que tratarla como un síntoma y no esperar a que alguien reporte que «la cámara no jala».

construction

La solución

Es una PWA instalable construida con Vite, React y TypeScript. El PDF de instrucciones del envío se parsea en el propio teléfono, se genera el archivo de etiquetas que pide el proceso, y la pantalla guía el escaneo pieza por pieza indicando qué falta y qué sobra.

El inventario se lleva por ubicaciones, con lectura de códigos de barras y, en Android, con etiquetas NFC para identificar cajas de un toque. Todo funciona sin red: los eventos se guardan localmente y la interfaz nunca se queda esperando a un servidor.

Alrededor hay cerca de treinta suites de prueba propias, entre ellas la que fija que un conteo no es un movimiento. Esa prueba existe porque el error contrario ya estuvo a punto de ocurrir, y es la clase de red que evita que una refactorización futura lo reintroduzca.

emoji_events

Resultados

lightbulb

Lo que aprendí

Que event sourcing no es una elección de arquitectura elegante: es lo que convierte «creo que ya está arreglado» en una prueba reproducible sobre datos reales. El día que hizo falta, fue la diferencia entre demostrar y prometer.

Que los errores más caros no son los que fallan ruidosamente, sino los que hacen exactamente lo que se les pidió en la capa equivocada. Un conteo tratado como salida no lanza ninguna excepción: solo deja cajas vacías.

Y que en software de operación, el modelo de datos tiene que aguantar la realidad física. Si en la bodega una pieza puede estar etiquetada aquí y suelta allá, el modelo tiene que permitirlo, aunque una casilla sea más cómoda de programar.