Ficha técnica
- Negocio
- Hilos y Encanto, mi mercería en Chiapas. Vende principalmente por Mercado Libre.
- Periodo
- Julio – agosto 2026
- Estado
- En producción, con escalera de activación por publicación
- Rol
- Diseño de la arquitectura, construcción, despliegue y operación
- Alcance
- 6 fases: saneamiento de SKU, inventario central, kardex, escritura a canal, tienda y analytics
Contexto
El negocio es Hilos y Encanto, mi mercería en Chiapas, cuyo canal principal de venta es Mercado Libre, con un volumen del orden de 500 unidades vendidas al mes en ese solo canal. La operación diaria la lleva un equipo pequeño que mueve cajas físicas, arma envíos y atiende clientes; nadie está sentado esperando a que un sistema le pida atención.
Cuando entré, la existencia vivía en tres lugares a la vez: un espejo del catálogo de Mercado Libre, el conteo físico de la bodega y el punto de venta. Ninguno le hablaba a los otros. Las ventas del canal no se registraban en ningún sistema propio, y la tienda web ni siquiera descontaba stock cuando alguien pagaba.
El encargo no era «hacer un dashboard». Era construir el lugar donde la existencia por fin significa una sola cosa, sin apagar la operación mientras se construía.
El problema
Tres inventarios aislados, y ninguno de los tres era el bueno.
Con tres fuentes desincronizadas, la sobreventa no es un accidente: es cuestión de tiempo. Vender una pieza que ya salió por otro canal significa cancelar, disculparse y pagarlo en reputación de la cuenta, que es el activo más caro de un vendedor en marketplace.
El agravante es que no había forma de reconstruir la historia. Sin registro de movimientos, la pregunta «¿por qué esta caja dice ocho y hay cinco?» no tenía respuesta posible: solo quedaba volver a contar y confiar en el nuevo número hasta la próxima discrepancia.
Y encima estaba el riesgo de la cura: un sistema que empieza a escribir existencias en un canal con 796 publicaciones vivas puede hacer un daño enorme en una sola corrida mal calculada. Cualquier solución tenía que poder estar apagada y seguir siendo útil.
Decisiones clave
Estas cinco son las que explican por qué el sistema se pudo encender sin que nadie perdiera una noche de sueño.
Un 2xx no prueba nada
Toda escritura a Mercado Libre se vuelve a leer del canal y se compara contra lo que se quiso escribir. Si no coincide, el movimiento queda marcado como fallido, no como hecho.
Una API de terceros puede aceptar una petición, responder «correcto» y aplicar otra cosa —o nada—. Si el sistema cree en la respuesta en vez de en el estado, el inventario se separa de la realidad justo donde nadie está mirando.
Escalera de activación, publicación por publicación
Nada se enciende de golpe. El modo va de apagado a simulación durante tres días, después a «solo reducir» y solo al final a escritura completa. La primera publicación en pasar por la escalera se eligió a mano, y fue una barata.
Si el sistema se equivoca, quiero que se equivoque en el artículo más barato del catálogo y con la operación mirando, no en 796 publicaciones a la vez. La simulación deja ver exactamente qué habría hecho antes de dejarlo hacerlo.
No escribir es siempre seguro
El proceso se niega a escribir si sus datos están viejos: catálogo con más de 24 horas, o cursor de bodega con más de 15 minutos de retraso. Además aborta la corrida si moviera más de 20 publicaciones o más de 150 unidades de una vez.
Ante la duda, el peor resultado de no hacer nada es que el canal se queda como estaba. El peor resultado de escribir con datos viejos es sobrevender o vaciar publicaciones sanas. La asimetría es tan grande que no merece discusión.
Botón rojo sin redespliegue
Hay un apagado total que corta todas las escrituras al instante, sin tocar el código ni volver a desplegar, y modos intermedios que permiten reducir existencia pero no aumentarla.
Cuando algo va mal en producción, la persona que lo nota necesita poder pararlo en segundos. Si apagar exige un despliegue, en la práctica no se apaga: se aguanta, y el daño crece.
Cobertura sin ventas es null, nunca cero
Si un producto no tiene velocidad de venta, la cobertura en días se reporta como dato ausente. Los CSV que consume la operación salen con BOM UTF-8 para que Excel no rompa los acentos.
Un cero se lee como «urgentísimo, se acaba hoy» y manda a alguien a resurtir lo que nadie compra. Un dato ausente se lee como lo que es: aquí no hay información suficiente para opinar.
Cómo viaja una venta
El inventario central es la única fuente de verdad. Los canales leen de él y el kardex registra —nunca edita— cada movimiento.
Venta en Mercado Libre
La orden entra por la API del canal, con su publicación y su variación.
Movimiento append-only
Se registra un movimiento nuevo. Nada se edita ni se borra: se corrige agregando.
Existencia recalculada
El inventario central recalcula la disponibilidad real de ese SKU.
Escritura al canal
Si procede, se ajusta el canal — y la escritura se vuelve a leer para comprobarla.
La tienda sirve del central
La tienda web deja de tener su propio stock y publica la disponibilidad del central.
La solución
El sistema se construyó en seis fases, cada una utilizable por sí sola. Primero el saneamiento de claves de producto: sin SKU confiable no hay nada que cruzar. Después un inventario central de solo lectura, que durante semanas solo miró y comparó, sin autoridad para cambiar nada.
La tercera fase trajo el kardex: un registro append-only de movimientos de venta. No se edita un movimiento equivocado, se agrega el que lo corrige, y la existencia siempre es la suma de la historia. El backfill de 90 días de historia se escribió en unos dos minutos y la consulta de esa misma ventana corre en 3.5 ms sin necesidad de índices nuevos.
Con la historia confiable ya se pudo invertir la relación: la cuarta fase escribe de vuelta al canal con un reconciliador que verifica cada escritura, y la quinta hace que la tienda web deje de tener stock propio y sirva la disponibilidad del central. Las dos últimas abren el camino a un segundo canal y a la capa de analytics.
Todo corre en Node 22 con TypeScript sobre PostgreSQL, con validación de esquemas en las fronteras, registro estructurado de eventos y generación de reportes en CSV y PDF para la gente que opera desde el escritorio, no desde una terminal.
Resultados
- 796 publicaciones auditadas en el saneamiento inicial; de 23 publicaciones caídas, 22 quedaron reactivables.
- Kardex con 1,742 movimientos registrados y 772 unidades físicas conciliadas contra el conteo real.
- El backfill de 90 días de historia se escribe en unos dos minutos; la consulta de esa ventana responde en 3.5 ms sin índices nuevos.
- La suite de pruebas creció de 115 a 143 casos, con los frenos de seguridad y el reconciliador cubiertos.
- 1,915 unidades vendidas en 90 días quedaron trazadas movimiento a movimiento, incluidas 74 devoluciones (≈ 4%).
Las cifras de venta se publican solo en unidades. Los importes del negocio no se publican, por regla del propio proyecto.
Lo que aprendí
Que la parte difícil de integrar canales no es la API: es decidir quién tiene la razón cuando dos sistemas discrepan. Ese acuerdo hay que tomarlo antes de escribir la primera línea, porque después el código lo toma solo y casi siempre mal.
Que un sistema que puede apagarse rápido se enciende antes. La escalera de activación parecía burocracia y resultó ser lo que hizo posible empezar: nadie tuvo que apostar la cuenta a que el software estaba bien a la primera.
Y que la honestidad de un dato vale más que su disponibilidad. Reportar ausencia en vez de un cero cómodo es incómodo la primera vez que alguien lo ve en pantalla, y es lo que evita que se tomen decisiones con números inventados.
¿Vendes en más de un canal y el inventario no cuadra? Este es exactamente el problema que resuelvo.
Hablemos