← Volver a proyectos

Cómo llevar el historial y los catálogos de clientes multisucursal desde sus sistemas anteriores con un pipeline de dos pasos, dry-run, QA y producción, y una conciliación contra la fuente en cada etapa.

Rol: Responsable de implementaciones y migración de datos (puesto actual) Periodo: may – sep 2026 Estado: delivered

TypeScriptExcelMySQLPrisma (esquema en solo lectura)Claude Code AI: Claude Code
8,339, 0 errores

Órdenes históricas de 3 sucursales llevadas a producción y comparadas contra los archivos originales

El cliente arranca con su historial completo y nadie corrige registros a mano después.

Conciliación en producción, sep 2026

5,908

Refacciones cargadas en 24 cuentas de un cliente

Un cliente de mantenimiento de flotillas puede operar inventario y costos desde el primer día.

Carga en producción, jul 2026

1,485

Compras reconstruidas en grupos homogéneos después de que la primera carga tuvo errores

Una carga defectuosa se rehízo y se verificó en lugar de parcharse, así que los costos son confiables.

QA y producción, jul 2026

58 de 59 filas mapeadas, 0 errores

Filas de un archivo de unidades móviles mapeadas en un ensayo que no toca producción

Los problemas aparecen en el ensayo, antes de tocar los datos en vivo del cliente.

Dry-run, jul 2026

Arquitectura

ARQUITECTURA / DATA-MIGRATION-PIPELINE 01 Exportes de Excel un layout por sucursal 02 JSON homogéneo auditable, comparable 03 Dry-run sin escrituras 04 QA contra el origen 05 Producción carga desde JSON 06 Conciliación filas y totales Nunca cargar directo desde Excel: el JSON se compara y concilia antes.
Pipeline de migración: Excel, JSON homologado, dry run, QA, producción y conciliación.

Contexto

Un SaaS B2B para talleres automotrices (mi puesto actual) recibe clientes que ya tienen años de historia en otro lugar. Dos proyectos muestran el patrón. En el primero, clientes nuevos con varias sucursales necesitaban ver en la plataforma sus órdenes, pagos, cuentas por cobrar y movimientos bancarios, exportados de su sistema anterior en archivos de Excel con formatos distintos por sucursal. En el segundo, un cliente corporativo de mantenimiento de flotillas con 24 sucursales y unidades móviles necesitaba su catálogo de refacciones, proveedores homologados y las compras de un año para operar inventario y costos. Este caso es anónimo y la demo usa datos inventados.

Mi rol

  • Decidí: las reglas de migración por sucursal, el orden de las etapas, qué se documenta como parcial en lugar de rellenarse y cuándo una corrida está lista para producción.
  • Verifiqué: cada corrida en el ambiente de QA y una conciliación contra el Excel original antes de tocar producción, y la primera carga de compras ya en producción, que audité yo.
  • Delegué a la IA: escribir los scripts de migración y reparación en TypeScript y los análisis escritos, con Claude Code, bajo mis reglas. Yo respondo por el análisis escrito que dirección aprueba antes de escribir código.

Investigación

Antes de programar dirigí un análisis escrito de las reglas de migración por sucursal y lo llevé a dirección para su visto bueno. En una sucursal comparé la estructura de 18 archivos (6,657 filas, 2,636 folios). Dirección notó que mi primer análisis había pasado por alto 3 archivos; corregí el análisis mismo antes de escribir código. En otra sucursal los archivos mezclaban varias sedes, así que filtré por etiqueta, y en una tercera solo cerca del 15% de las órdenes tenía reporte completo: documenté una migración parcial en lugar de inventar el resto.

Decisiones

DecisiónAlternativas descartadasPor qué
Dos pasos: generar un JSON homologado y auditable desde los Excel, y cargar la base desde ese JSONCargar directo desde ExcelEl JSON se puede comparar, revisar y conciliar antes de cualquier escritura; el archivo fuente nunca es lo que se carga.
Siempre dry-run, luego QA, luego producción, verificando contra la fuenteAplicar directoEscribir en producción exige un número contra el cual comparar. La primera carga de compras llegó a producción con 3 errores, y por eso se rehízo así.
Documentar una migración parcial (cerca del 15% de las órdenes en una sucursal)Rellenar huecos para que parezca completaUn dato inventado en el historial de un cliente es peor que un hueco documentado.
Fusionar proveedores duplicados en el que tiene más dependencias, emparejando por RFC, luego nombre normalizado y luego alias manualBorrar duplicadosBorrar rompe el historial que apunta a ellos; fusionar lo conserva.
Baja lógica para las refaccionesBorrado físicoEl historial debe seguir siendo legible.

Validación y QA

Hallazgos míos y las reglas que produjeron:

  • Columnas omitidas. Cuatro bugs vinieron de INSERT manuales que omitían columnas (descripción, método de pago, aprobación del cliente, refacciones). Se corrigieron con backfills, y la regla ahora es “decidir cada columna, no omitir”.
  • Un campo que el esquema marca como opcional pero la app exige rompía 188 órdenes al abrirlas. Lo generé con el formato de la propia app, validé unicidad y reparé las 188.
  • Movimientos financieros espejo faltantes de corridas previas se completaron con backfill.
  • Primera carga de compras. Tres errores: sucursal equivocada, proveedores mezclados en una sola compra y costos en cero. Además, un costo de lote se había capturado como costo unitario. La rehíce con el pipeline auditable y la verifiqué después de cargar.
  • Exclusiones con motivo. Se dejaron fuera, documentadas, las filas que no eran sucursales reales (4 de 8,262) y un folio con un empate imposible de resolver.

QA corrió el ciclo completo antes de producción: borrar, cargar, verificar, borrar.

Resultados

Migración conciliada contra la fuente

Órdenes históricas de 3 sucursales: archivos fuente contra producción, y errores encontrados.

Migración conciliada contra la fuente Órdenes históricas de 3 sucursales: archivos fuente contra producción, y errores encontrados. Órdenes archivos fuente 8,339 archivos fuente: 8,339 producción 8,339 producción: 8,339 Errores errores en producción 0 errores en producción: 0
Fuente: Registros propios de la migración · 2026-09
Tabla de datos
PanelSerieValor
Órdenesarchivos fuente8,339
Órdenesproducción8,339
Erroreserrores en producción0
  • 8,339 órdenes históricas de 3 sucursales migradas a producción con 0 errores; después, 2 sucursales más. En total he migrado con este proceso más de 50 sucursales de clientes.
  • Catálogo de una sucursal base clonado a 5 sucursales: 1,101 conceptos de mano de obra y 126 paquetes de servicio.
  • 5,908 refacciones cargadas en 24 cuentas.
  • 1,393 compras con 7,975 líneas de la primera carga, regeneradas como 1,485 grupos homologados.
  • Un dry-run de unidades móviles mapeó 58 de 59 filas con 0 errores.

Qué resuelve y dónde más sirve

Un cliente nuevo no puede usar un sistema que arranca vacío: necesita años de órdenes, refacciones y proveedores de sus herramientas anteriores. Moverlos a mano es lento y los errores aparecen meses después. Este pipeline mueve los datos de forma ensayada y revisada, para que el cliente empiece con su historial completo y las cifras coincidan con la fuente.

Dónde más aplica el mismo patrón:

  • Onboarding de clientes en cualquier SaaS B2B que deba importar el historial de un cliente desde hojas de cálculo o un producto anterior.
  • Consolidación de sistemas tras una fusión o adquisición, cuando los registros de dos empresas deben volverse uno sin perder historial.
  • Cambio de ERP o CRM, cuando años de registros deben pasar al sistema nuevo y demostrarse completos.

Qué haría distinto

La primera carga de compras llegó a producción con tres errores y hubo que rehacerla; haría del ciclo completo de dry-run y QA una condición previa de toda carga, la corra quien la corra. También escribiría la regla “decidir cada columna” como una verificación automática y no como una convención, para que un script que omita una columna falle antes de ejecutarse. Y exigiría reportes completos al cliente antes de empezar el análisis: la sucursal con 15% de datos completos solo se pudo documentar, no resolver.

Evidencia

Versión completa: repositorio privado, disponible bajo solicitud.

Basado en mi puesto actual; todos los datos son ficticios.