← SCRAM AI Lab
Estrategia técnica de dual-write y proxy edge para migrar de Mautic a un CRM propio sin pérdida de prospectos, inconsistencia de datos ni caída operativa.
May 21, 2026
438 lecturas

Llevamos cinco años viendo migraciones de Mautic terminar mal: cutover de viernes en la noche, lunes el equipo de marketing descubre que 8% de los contactos no llegaron, 15% de los segments se rompieron porque los filtros no mapean uno-a-uno, y el formulario de la landing principal estuvo apuntando al endpoint viejo durante 36 horas. El patrón que sí funciona tiene tres fases y dura un mes — pero nadie te despierta a las 3 AM.
Para migrar de Mautic a un CRM propio sin perder prospectos, se debe implementar una arquitectura de escritura dual asíncrona mediante colas de mensajes durante treinta días, complementada con redirecciones perimetrales 301 en el proxy inverso. Este esquema garantiza que los formularios activos sigan respondiendo mientras el nuevo sistema valida la integridad de los datos.
La elección de la técnica define el riesgo operativo del negocio. La siguiente matriz resume las tres metodologías más comunes observadas en despliegues corporativos:
| Criterio | Hard Cutover (Fin de semana) | Export / Import Manual | Dual-Write con Shadow Period |
|---|---|---|---|
| Tiempo de inactividad | De 12 a 48 horas | Variable (acumula retraso) | Cero tiempo de inactividad |
| Riesgo de pérdida de leads | Crítico (endpoints rotos o desalineados) | Alto (desfase por cargas batch) | Nulo (respaldo en cola asíncrona) |
| Complejidad técnica | Baja en código, extrema en soporte | Baja a media (scripts ad-hoc) | Media a alta (requiere worker/proxy) |
| Capacidad de rollback | Compleja o destructiva | Inconsistente | Inmediata (cambio de lectura en 5 min) |
Los primeros 15 días el CRM nuevo es la fuente de verdad para lectura, pero todo lo que se escribe (forms, tracker, sync ERP) se duplica a Mautic en background. Mautic queda en read-only para UI humana — nadie puede tocarlo manualmente. Esto compra ventana de rollback: si algo explota, apuntas las lecturas a Mautic en 5 minutos.
// services/contact-write.service.ts
async function captureContact(data: ContactInput) {
// Primario: CRM nuevo
const contact = await prisma.crmContact.create({ data });
// Espejo a Mautic (best-effort, no bloquea)
this.mauticMirrorQueue.add('mirror-contact', {
crmId: contact.id,
email: data.email,
phone: data.phone,
payload: data,
}, { attempts: 3, backoff: 'exponential' });
return contact;
}
En paralelo, un job nocturno baja contactos históricos de Mautic en batches de 10K. La parte crítica es la deduplicación compuesta: email exacto OR phone normalizado (sin lada, sin espacios). Mautic permite duplicados; tu CRM nuevo no debe.
async function backfillBatch(offset: number) {
const mauticContacts = await mautic.getContacts({
limit: 10000,
offset,
orderBy: 'date_modified',
});
for (const m of mauticContacts) {
const phoneNorm = normalizePhone(m.phone); // +52 5512345678
const existing = await prisma.crmContact.findFirst({
where: {
OR: [
{ email: m.email.toLowerCase() },
phoneNorm ? { phone: phoneNorm } : undefined,
].filter(Boolean),
},
});
if (existing) {
await prisma.crmContact.update({
where: { id: existing.id },
data: { mauticId: m.id, ...mergeFields(existing, m) },
});
} else {
await prisma.crmContact.create({ data: mapMauticToCrm(m) });
}
}
}
Números reales del caso AWALAB: 47K contactos, 12K segments, 6 horas de ejecución total. El cuello de botella no fue Postgres ni Mautic — fue la normalización de teléfonos con libphonenumber para detectar duplicados.
En bases de datos de México y América Latina, el identificador principal para ventas operativas suele ser WhatsApp antes que el correo electrónico. Mautic almacena teléfonos en texto libre, lo que genera variantes de un mismo número: formatos locales de diez dígitos, entradas con prefijo internacional +52, o registros antiguos que arrastran el prefijo móvil 1 eliminado por el IFT en 2019. Si no se homogeniza bajo el estándar internacional E.164 durante el backfill, el CRM generará cuentas duplicadas para el mismo prospecto y fragmentará las conversaciones comerciales.
Después de 30 días de dual-write sin incidentes, dropeamos las escrituras a Mautic. Los endpoints viejos (/form/submit/mautic, /mtc.js) reciben redirect 301 a los equivalentes del CRM nuevo. Los 301 los procesa Traefik en el edge sin tocar Mautic — para entonces Mautic ya está apagado, solo Traefik conoce el mapeo.
# traefik dynamic config
http:
routers:
mautic-legacy:
rule: "Host(`mautic.scram2k.com`) || PathPrefix(`/mtc.js`)"
service: noop@internal
middlewares: [redirect-to-crm]
middlewares:
redirect-to-crm:
redirectRegex:
regex: "^https://mautic\\.scram2k\\.com/(.*)"
replacement: "https://api.scram2k.com/v1/tracker/$1"
permanent: true
Incluso con arquitectura dual-write, existen puntos ciegos técnicos que conviene monitorear:
Equipo que conozco intentó "lift and shift" en un fin de semana: export CSV de Mautic, import al CRM nuevo, apagar Mautic. Resultado: 12% de contactos con teléfono malformado quedaron como duplicados, segments dinámicos se convirtieron en listas estáticas (perdiendo la lógica), tracking JS apuntaba a endpoint inexistente por 4 días hasta que alguien notó que el formulario de demo no estaba capturando leads. Cutover hard sin shadow period es la receta para el postmortem.
La pregunta de seguimiento: ¿cuánto del código de espejo a Mautic se reusa para futuras migraciones (HubSpot, Salesforce)? Spoiler: el 80% si abstraes el adapter desde el día uno.
Artículos relacionados
OpenAI DevDay 2026: GPT-6.1 Sol a un quinto del precio de Astra y agentes que no se apagan
En DevDay (29 sep) OpenAI lanzó GPT-6.1 Sol a $2/$10, dots para ChatGPT Pro y Business Premium, Ultrafast para Astra y uso de computadora en la Agents API.
Cómo evaluamos un modelo nuevo antes de ponerlo frente a un cliente: el juez, 120 turnos y el enrutador
Septiembre trajo Fable 5.1 y GPT-6 Astra. Nuestro método para decidir si un modelo entra al asistente de SCRAM: un juez automático que califica cada turno, una muestra de 120 conversaciones reales etiquetadas por una persona, tres métricas y un enrutador por niveles. Con la historia del juez que borraba su propio rastro.
GPT-6 Astra: lo que OpenAI confirmó, lo que circula sin fuente y qué hacer mientras tanto
OpenAI presentó GPT-6 Astra el 4 de septiembre de 2026 como su modelo "más inteligente y alineado", con rollout escalonado y sin precio publicado. Separamos lo confirmado de los rumores (1M de contexto, benchmarks saturados) y explicamos cómo evaluarlo sin romper tu producto.