Estudio de caso / AMXpress · Caso técnico de integración
Legacy Sync Service
Mantener datos coherentes entre sistemas diferentes.
Servicio que reconcilia envíos, estados e historial entre AMXpress y una API legacy mediante workers, persistencia idempotente y recuperación de fallos.
- Tecnologías utilizadas
- NestJS · TypeScript · PostgreSQL · Prisma · Redis · BullMQ · Axios
El problema
El sistema externo y Core difieren en identidades, estados y campos disponibles. Listados incompletos, actualizaciones y fallos parciales pueden dejar datos incoherentes. El portal necesita una lectura local útil sin consultar agresivamente el legacy ni dar por completa una sincronización fallida.
Mi participación
Implemento el contrato entre Core y el worker Sync, la normalización del modelo externo, la reconciliación de registros y los mecanismos de reintento y deduplicación. Verifico repetición, recuperación y lectura local con regresiones e integración sobre PostgreSQL y Redis aislados.
Qué permite hacer
Solicitar sin bloquear la operación
Core encola sincronizaciones por cliente, rango y criterio en legacy-sync. También solicita refrescos individuales de tracking. Una búsqueda explícita puede esperar el job; la navegación habitual lee local y actualiza en segundo plano.
Reconciliar datos y conservar identidad
Se normalizan IDs externos, clientes, paquetes e historial. Las repeticiones conservan IDs y evitan duplicar movimientos conocidos. Una fecha confirmada no se borra por un payload parcial; una reprogramación actualiza el día del viaje.
Comunicar una finalización real
Los contadores distinguen creado, actualizado, omitido y fallido. Sólo el éxito publica dashboard_sync_completed y marca frescura. Si un elemento falla, el job falla y puede reintentarse sobre los registros ya persistidos.
Cómo encajan las piezas
Core produce jobs BullMQ sobre Redis; un worker independiente consume con concurrencia 1 y consulta el legacy secuencialmente. Sync transforma respuestas y persiste en la base operativa PostgreSQL mediante Prisma. Los eventos Redis permiten a Core actualizar dashboard y tracking. Los canales Pub/Sub históricos conviven con la cola, pero no ofrecen las mismas garantías de persistencia.
- Core APICliente + rango + criterio · deduplicaciónRedis / BullMQ
- Sync WorkerConcurrencia 1 · listas + detallesLegacy API
- Sync / PrismaEstados · fechas · historialPostgreSQL
- Sync → Redis eventsFinalización / actualización del dashboardCore → Angular
Decisiones de ingeniería
Separar solicitud, procesamiento y lectura
Core encola el trabajo y un worker independiente adapta el legacy; la navegación habitual lee PostgreSQL. La concurrencia y el ritmo de consulta se limitan para proteger al proveedor. BullMQ conserva el trabajo pendiente; los eventos Pub/Sub notifican cambios, pero no sustituyen la cola ni garantizan replay.
Reconciliar por identidad, no volver a crear
Normalizo IDs, estados, paquetes e historial antes de persistir. Las actualizaciones reutilizan identidades locales y evitan duplicar movimientos conocidos; un payload parcial no elimina información confirmada. La fecha del viaje es un ejemplo de esa regla: conserva su significado operativo, separado de los timestamps técnicos.
Recuperar fallos sin publicar falso éxito
Un rango puede persistir registros antes de fallar: no es una transacción global. Si quedan elementos fallidos, no se publica finalización ni frescura. El reintento reconcilia lo ya escrito; backoff y clasificación de errores distinguen fallos transitorios de entradas irrecuperables, sin prometer exactly-once.
Dificultades resueltas
Fallos parciales sin falso éxito
El rango no es una transacción global: puede persistir algunos registros antes de fallar. La recuperación repite el trabajo y reconcilia por identidad e historial. No se publica finalización ni frescura del rango si quedan elementos fallidos.
Respetar la capacidad del legacy
Se limita concurrencia, sockets y ritmo de consulta, con timeouts y pausas entre días. El contrato observado no certifica listados de gran volumen ni descarta truncamiento silencioso; la solución documenta ese límite en lugar de prometer consistencia absoluta.
Capacidades demostrables
Reconciliación y recuperación verificables
La integración con un legacy simulado ejercita normalización, identidad e historial, payloads parciales, reintentos y lectura tras el job. Las fechas y reprogramaciones se verifican como parte de la coherencia de los datos.
Garantías con alcance explícito
Los locks en memoria y Pub/Sub tienen límites. La persistencia protege identidad y datos confirmados, sin prometer exactly-once ni completitud del proveedor.