Este es un recorrido de producto, no el caso de ninguna veterinaria real: describe cómo se mueve -y dónde se desconecta- la preferencia de un dueño de mascota dentro de FaunaWare. La pregunta que resuelve es concreta: si un dueño ya pidió no recibir WhatsApp, ¿en qué punto exacto ese aviso deja de aplicarse? Según lo visto en en FaunaWare, las campañas de recuperación de clientes ignoran la baja que el dueño ya pidió.
Esquema del recorrido · ilustración, no es una pantalla del sistema
- 1. El dueño pide no recibir WhatsAppRecepción puede registrarlo vía
PUT /notifications/preferences-aunque hoy ningún botón del panel llama a ese endpoint, así que sólo queda accesible por soporte técnico. - 2. Llega la hora de un recordatorio de citaEl programador de recordatorios consulta
notification_preferencesantes de enviar. - 3. El canal marcado se salta
isOptedOut()corta el envío por WhatsApp para ese paciente -funciona como debe. - 4. La clínica lanza una campaña de recuperaciónSelecciona pacientes por criterio clínico (última visita, crónicos) y escribe un mensaje libre.
- 5. El relay envía directo, sin preguntar
RecallRelayServicellama a/notifications/sendcon el mismo contacto y el mismo canal -sin tocarnotification_preferences. - 6. El dueño que pidió no recibir WhatsApp, lo recibe igualMismo paciente, mismo canal marcado, resultado distinto según qué función lo mande.
1-3. La baja existe y el recordatorio la respeta
El endpoint PUT /notifications/preferences (notifications.controller.ts:149-157, roles clinic-admin/reception) permite registrar el opt-out de un paciente por canal. Cuando llega la hora de un recordatorio de cita, loadPreferenceRow() (reminder-scheduler.service.ts:225-239) la lee, e isOptedOut() decide si ese canal se salta para ese paciente. Hasta aquí, el sistema hace exactamente lo que la ley exige: deja de mandar por el canal que el dueño marcó.
4-6. La campaña usa otra puerta, y esa puerta no pregunta
La campaña de recuperación no pasa por el programador de recordatorios. RecallRelayService.tick() (recall-relay.service.ts:206-215) toma cada envío pendiente de la campaña y llama directo a POST /notifications/send con el contacto, el canal elegido al crear la campaña y el mensaje libre que escribió la clínica. NotificationsService.send(), el método que atiende esa llamada, no tiene ninguna consulta a notification_preferences en su cuerpo -despacha por el canal indicado, sin más comprobación que si el proveedor de envío responde.
| Parada | ¿Consulta la baja del dueño? |
|---|---|
| 1-2. Recordatorio de cita programado | Sí -loadPreferenceRow() + isOptedOut() |
| 3. Envío del recordatorio | Sí -se salta el canal marcado |
| 4. Campaña de recuperación creada | No aplica -sólo pide criterio, canal y mensaje |
5. RecallRelayService → /notifications/send | No -llama directo, sin preferencia de por medio |
6. NotificationsService.send() | No -ninguna consulta a notification_preferences en su código |
Puedes estimar la exposición de este hallazgo, con tus propios números, en la calculadora de exposición por campaña sin revisar la baja.
Preguntas frecuentes
¿El opt-out de FaunaWare no sirve para nada, entonces?
Sí sirve: el recordatorio de cita lo respeta correctamente. El problema es que es la única ruta de envío que lo consulta.
¿Hay una pantalla para que el dueño pida la baja él mismo?
No en el código revisado: el endpoint existe para que recepción lo registre, pero ninguna pantalla del panel ni del portal del dueño lo llama hoy.
¿FaunaWare corrige esto automáticamente?
No, hoy no. Es un hallazgo verificado en el código actual, no una función ya resuelta.
Ve el recorrido completo en tu propia demo
Te mostramos en vivo la baja de un canal y las dos rutas de envío que responden distinto a ella.
Agenda una demo gratis