Compliance de contacto
Esta es la garantía central del producto: ningún mensaje sale sin pasar por el motor de compliance — evaluado inmediatamente antes de cada envío, con el estado más fresco de la base de datos, y no como una configuración estática verificada una vez al día. Cobrar en el horario equivocado, en el día equivocado o a la persona equivocada no es solo una mala práctica: dependiendo del estado (UF) de Brasil, es una infracción legal.
El orden de los vetos
Antes de cada envío, el motor evalúa cuatro barreras, en este orden. La primera que repruebe decide el destino del mensaje:
- Supresión activa — prevalece sobre cualquier condición de etapa. Si existe una supresión que cubre a la persona, la deuda o el canal, el mensaje se suprime (no sale, con el motivo registrado).
- Bloqueo legal (
legal hold) — un cobro bajo bloqueo legal no genera ningún contacto. - Ventana legal de la jurisdicción — fuera de la ventana de horario permitida en el estado (UF) del deudor, el mensaje se reprograma para la próxima apertura, nunca se descarta.
- Límites por persona — tope diario, semanal e intervalo mínimo entre contactos. Si se supera, se reprograma.
El resultado es siempre uno de tres: enviar, suprimir (con motivo tipificado) o reprogramar (con el próximo horario permitido calculado). Todo queda registrado.
Ventanas legales por estado (UF)
No existe una "ventana nacional" en la ley brasileña — las reglas de horario de cobro son estatales. El sistema mantiene una biblioteca de políticas por jurisdicción, versionada y con vigencia:
- São Paulo (
BR-SP) — Lei estadual 15.426/2014 (ley paulista de horarios de contacto): lunes a viernes de 8h a 20h, sábado de 8h a 14h; prohibido los domingos y feriados. - Default conservador nacional (
BR) — se aplica cuando no hay una ley estatal mapeada para el estado (UF) del deudor: la misma ventana conservadora (lun–vie 8h–20h, sáb 8h–14h, domingos y feriados prohibidos).
La jurisdicción proviene del estado (UF) de la dirección del deudor; un deudor sin UF válida en el registro cae en la regla nacional conservadora. La política también puede variar por canal y por tipo de persona (física/jurídica), y la resolución sigue esta precedencia: regla de la UF específica de tu organización → regla de la UF en la biblioteca legal → regla nacional de la organización → regla nacional de la biblioteca. Si nada coincide, aplica el default conservador incorporado en el código.
Los horarios se evalúan en la zona horaria de la organización (por defecto America/Sao_Paulo).
Feriados
Cuando la política prohíbe feriados (el valor por defecto), el motor bloquea los feriados nacionales de Brasil: los fijos (1º/ene, Tiradentes, 1º/may, 7/sep, 12/oct, 2/nov, 15/nov, Consciência Negra — Lei 14.759/2023 (ley que instituyó el feriado nacional del Día de la Conciencia Negra) — y Navidad) y los móviles calculados a partir de la Pascua (lunes y martes de carnaval, viernes santo y Corpus Christi). Un envío que caería en un feriado se reprograma para el próximo día con ventana abierta.
Límites por persona — no por cobro
Los límites de frecuencia aplican a la persona, sumando todos los canales, todos los cobros y todas las reglas de cobranza. Un deudor con cinco deudas no recibe cinco veces más mensajes.
| Límite | Valor por defecto |
|---|---|
| Máximo por día | 2 contactos |
| Máximo por semana | 6 contactos |
| Intervalo mínimo entre contactos | 4 horas |
Estos son los valores por defecto conservadores; pueden personalizarse por organización (configuración contactPolicy de la cuenta). Solo cuentan para el límite los mensajes efectivamente enviados/entregados/leídos — las supresiones y las fallas no consumen cuota. Si se supera el tope, el envío se reprograma.
Supresiones: por qué un contacto NO puede ocurrir
Una supresión es un registro tipificado, con alcance y evidencia — distinto de una preferencia de canal. "No quiero WhatsApp" es una cosa; "esta deuda no puede ser cobrada" es otra. Los 12 tipos:
| Tipo | Situación |
|---|---|
opt_out | El deudor pidió no ser contactado |
third_party | Contacto de un tercero (el famoso "no soy yo") |
invalid_contact | Correo electrónico/teléfono inválido |
deceased | Persona fallecida |
fraud | Sospecha de fraude |
dispute | Disputa abierta sobre la deuda |
judicial | Orden judicial |
lawyer_represented | Deudor representado por un abogado |
bankruptcy | Reorganización judicial / quiebra |
prescription | Deuda prescrita |
vulnerable | Persona en situación de vulnerabilidad |
channel_blocked | Canal bloqueado por el proveedor |
Cada supresión tiene alcance: puede aplicar a una persona, a una deuda específica, o a ambas — y a un canal específico o a todos (channel vacío = todos). También tiene vigencia (activeFrom/expiresAt) y puede revocarse con registro. En la evaluación, basta una supresión activa que cubra a la persona o la deuda, en el canal en cuestión o en todos, para vetar el envío — y la supresión tiene precedencia sobre todo: condición de etapa, campaña, urgencia de la operación.
La creación y la revocación de supresiones entran en la pista de auditoría con tipo, alcance, origen y evidencia.
Reprogramación — nunca un descarte silencioso
Cuando el veto es temporal (fuera de ventana, límite diario/semanal, intervalo mínimo), el motor calcula el próximo instante permitido — la apertura de la ventana de hoy, el inicio del próximo día hábil con ventana, o el fin del intervalo mínimo — y reprograma. El mensaje no desaparece: sale en la primera oportunidad legal, y el registro muestra el motivo del aplazamiento (outside_legal_window_BR-SP, daily_contact_limit, min_contact_interval...).
Última línea de defensa: revalidación en el worker
El compliance al momento de programar no basta: el pago puede llegar con el job ya en la cola. Por eso el worker revalida todo inmediatamente antes de entregar al proveedor: cobro pagado, cancelado, dado de baja o negociado, "ya pagué" pendiente de verificación, bloqueo legal y regla pausada — cualquiera de estos bloquea el envío en el último milisegundo, con el motivo registrado.