Por qué casi todos los CRM caseros se rompen en el mismo sitio
No es por falta de campos ni de automatizaciones. Es por una decisión de modelado que parece inofensiva el primer día y deja de tener arreglo al año.
Hemos visto bastantes CRM hechos en casa — sobre Airtable, sobre Notion, sobre una hoja de cálculo con macros, sobre código propio. Fallan casi siempre en el mismo punto, y no es donde la gente espera.
No fallan por falta de funciones. Fallan porque el primer día alguien creó tres tablas:
Leads → nombre, correo, teléfono, estado
Contactos → nombre, correo, teléfono, empresa
Clientes → nombre, correo, teléfono, total_comprado
Parece razonable. Son tres cosas distintas del negocio, tres tablas. Y funciona perfectamente durante unos meses.
Dónde se rompe
Ana rellena el formulario con ana@empresa.cl. Se crea un Lead.
Dos semanas después escribe por WhatsApp desde su móvil. La persona que atiende no relaciona ese número con nada, así que crea un Contacto nuevo.
Compra. Como el checkout va por otro sistema, entra con su correo personal ana.perez@gmail.com. Se crea un Cliente.
Ahora tienes tres registros de la misma persona y ninguna vista de su historia. Cuando alguien de tu equipo abra cualquiera de los tres, verá un tercio de la relación. Y lo peor: nadie se entera de que está pasando. No hay error, no hay alerta. Simplemente los datos dejan de significar lo que crees.
Multiplica por dos años y ya no tienes un CRM. Tienes tres listas de correos con opiniones distintas sobre quién es tu cliente.
La corrección: la persona es la entidad, el resto son estados
El modelo que aguanta separa quién es alguien de en qué punto está:
parties → la persona o la empresa. Existe una sola vez.
identities → (canal, handle) → party
email · ana@empresa.cl → Ana
whatsapp · +56912345678 → Ana
email · ana.perez@gmail.com → Ana
leads → un ESTADO de una party (etapa, origen, responsable)
orders → pedidos de una party
"Lead", "contacto" y "cliente" dejan de ser tablas y pasan a ser roles y estados de la misma persona. Ana no es tres registros: es una party con tres identidades, un lead cerrado y dos pedidos.
La pieza que hace el trabajo es un índice único sobre (canal, handle). Cuando llega un mensaje nuevo de WhatsApp, buscas ese número: si existe, ya sabes de quién es; si no, creas la identidad y la enganchas. El historial se unifica solo.
Dos detalles que deciden si funciona
Normaliza antes de comparar. Ana@Empresa.CL y ana@empresa.cl son la misma persona, pero para un índice único son dos filas distintas. Los correos van en minúsculas y los teléfonos en E.164 (+56912345678, sin espacios ni guiones) antes de guardarse. Sin esto, todo el modelo se cae en silencio y vuelves a tener duplicados.
Guarda quién hizo cada cosa. Cada actividad lleva un actor: user, agent o system. Parece burocracia hasta el día que un agente automático manda un mensaje raro y necesitas saber si lo escribió una persona o un modelo. Ese día, o está en el dato, o no lo averiguas.
Por qué esto no se arregla después
Migrar de tres tablas al modelo de partes con datos reales significa decidir, uno por uno, qué registros son la misma persona. Con unos cientos es una tarde tediosa. Con decenas de miles es un proyecto con presupuesto, y cualquier criterio automático que uses va a fusionar mal a alguien.
El coste de hacerlo bien el primer día son un par de tablas más y una función de veinte líneas. El coste de arreglarlo al año se mide en semanas.
Cómo saber si ya lo tienes
Una pregunta basta:
¿Puedes ver, en una sola pantalla, todo lo que ha pasado con un cliente — el formulario que rellenó, los mensajes de WhatsApp, sus pedidos y las notas del equipo — ordenado por fecha?
Si la respuesta es "más o menos, cruzando dos sistemas", todavía no lo tienes. Y lo que estás decidiendo ahora mismo no es si construirlo: es si lo construyes cuando cuesta una tarde o cuando cuesta un trimestre.