El aislamiento multiempresa es la decisión que arrastra todo lo demás. La jerarquía Entidad → Proyecto → Usuarios cuelga de un servicio de autorización que comprueba en cada operación si la fila pertenece a la entidad del usuario. Las empresas no llevan columna de entidad: se aíslan a través de la campaña que las mueve, porque la misma ficha puede aparecer en dos campañas con tratamientos distintos.
Los envíos no pasan por un broker: se encolan en una tabla y un planificador revisa cada segundo, con reintento y recuperación automática de envíos colgados a los sesenta segundos. Si el proceso muere a mitad de una campaña, al arrancar la cola sigue ahí y el trabajo no se duplica.
Alrededor de ese núcleo: validación de direcciones antes de escribir, blocklist por entidad que cancela lo encolado, bajas de un clic con token firmado, plantillas con adjuntos y más de quince variables, y sincronización periódica del correo de cada usuario por OAuth con los tokens refrescados cifrados con AES-256-GCM en base de datos.
Campaña → movilización (sin duplicados, fuera blocklist)
→ perfil de envío: ventana, pausa, cuota diaria, rampa
→ cola en tabla → worker (concurrencia 5, ciclo 1 s)
→ proveedor de correo → webhook: entrega · apertura · rebote · queja · baja
→ bandeja única con hilos, asignación y estado