🦎 Netcomp, Webhooks y Leader/Follower — Estado Actual¶
Fecha: 1 de abril de 2026 Propósito: Tener claridad total sobre qué datos emite el webhook de la cola, qué diferencia hay entre eventos de Encounter vs Message, y cómo la migración Leader/Follower condiciona a Pet Flows Fuentes: Código fuente de
dkv-pet-flows-admin(containers/Queue, services/netcomp), documentación eninvestigacion_dkv_pet_cloud.md
1. La Entidad Queue — Anatomía Completa de Notificaciones¶
Del análisis del código en QueueDetailsNotifications.jsx y Queue/index.jsx, la entidad Queue (Cola) tiene estos campos de notificación:
Campos de Notificación de la Cola¶
| Campo | Tipo | Descripción |
|---|---|---|
notify_new_encounter_doctors_enabled |
bool | Notificar a doctores cuando entra un caso nuevo |
notify_new_encounter_recipients_enabled |
bool | Notificar a destinatarios externos cuando entra caso |
notify_new_encounter_recipients |
string[] | Lista de emails/destinatarios para caso nuevo |
notify_max_unassigned_time_doctors_enabled |
bool | Alertar a doctores si caso no asignado en tiempo |
notify_max_unassigned_time_recipients_enabled |
bool | Alertar a destinatarios si caso no asignado |
notify_max_unassigned_time_recipients |
string[] | Lista de destinatarios para alerta de asignación |
notify_max_inactive_time_doctors_enabled |
bool | Alertar a doctores por inactividad |
notify_max_inactive_time_recipients_enabled |
bool | Alertar a destinatarios por inactividad |
notify_max_inactive_time_recipients |
string[] | Lista de destinatarios para alerta de inactividad |
webhook_new_message_recipients |
string[] | URLs webhook para nuevos mensajes |
Campos de Temporización (SLA)¶
| Campo | Tipo | Descripción | Valor ejemplo |
|---|---|---|---|
max_unattended_time |
int (min) | Tiempo máximo de respuesta del doctor | 15 min |
max_unassigned_time |
int (min) | Tiempo máximo sin asignar doctor | 30 min |
max_inactive_time |
int (min) | Tiempo máximo de inactividad | 15 min |
max_inactive_patient_warning_time |
int (min) | Aviso de inactividad del paciente | configurable |
max_inactive_patient_time |
int (min) | Cierre por inactividad del paciente | configurable |
unassign_unattended |
bool | Desasignar doctor si supera respuesta | true/false |
revoke_inactive |
bool | Revocar caso por inactividad + re-evaluar políticas | true/false |
close_inactive_encounters |
bool | Cerrar casos inactivos automáticamente | true/false |
close_unassigned_inactive |
bool | Cerrar no asignados inactivos | true/false |
2. Los 3 + 1 Sistemas de Eventos en una Cola¶
graph TD
QUEUE["🏥 Cola (Queue)<br/>ej: Telemedicina"]
subgraph "3 Notificaciones Internas"
N1["📥 Entrada de Caso<br/>notify_new_encounter_*<br/>→ Email a destinatarios"]
N2["⏰ Tiempo Asignación<br/>notify_max_unassigned_time_*<br/>→ Email + alerta doctor"]
N3["😴 Inactividad<br/>notify_max_inactive_time_*<br/>→ Email + revoke"]
end
subgraph "1 Webhook Externo"
WH["🔗 Webhook<br/>webhook_new_message_recipients<br/>→ HTTP POST a URLs externas"]
end
QUEUE --> N1 & N2 & N3 & WH
style QUEUE fill:#009BE0,color:#fff
style N1 fill:#059669,color:#fff
style N2 fill:#D97706,color:#fff
style N3 fill:#ef4444,color:#fff
style WH fill:#7C3AED,color:#fff
[!IMPORTANT] Hallazgo clave: Las 3 notificaciones internas (N1, N2, N3) son emails a destinatarios humanos (operadores, jefes de cola). El webhook (WH) es un HTTP POST a URLs de máquinas (originalmente pensado para pools de terceros). Pet Flows se engancha al webhook.
3. Encounter vs Message — ¿Dos tipos de evento?¶
Del análisis de la API del admin:
Encounter (Caso)¶
POST /encounters/{id}/create_support → Crear soporte
POST /encounters/{id}/token → Obtener token
POST /encounters/{id}/doctor_close → Cerrar caso con motivo
GET /encounters/{id}/calls → Llamadas del caso
Un Encounter es un caso médico completo: apertura, asignación a doctor, conversación, cierre. Es la entidad de nivel alto.
Message (Mensaje)¶
POST /messages → Crear mensaje
GET /messages?from=0&size=999 → Listar mensajes
PUT /messages/{id} → Actualizar mensaje
GET /messages/types → Tipos de mensaje
Un Message tiene: message_id, brand_id, service_id, queue_id, speciality_id, descriptions, type, enabled.
Los mensajes son templates de mensajes predefinidos (respuestas enlatadas), NO mensajes individuales de chat. Son configurables por cola, marca y especialidad.
El Webhook — ¿Qué se envía? (VERIFICADO)¶
[!SUCCESS] Hemos verificado el código fuente tanto en
netcomp(Erlang) como enpet-cloud(Java).
- El webhook se dispara EXCLUSIVAMENTE cuando se crea un nuevo mensaje en el chat (
nkchat_message_eventen Erlang,TelemedExtCallback.nkchatMessageEventen Java).- ESTO INCLUYE los mensajes del sistema (ej: "Tu consulta ha sido cerrada", creados por el ususario
admin/system).- El Payload es perfecto: Cada POST incluye la "foto" completa de la entidad:
{ "encounter": { ... todo el detalle de la consulta, tags, estado ... }, "message": { "type": "created", "message_id": "...", "text": "...", "created_by_role": "patient|professional|system" } }
Flujo en Pet Flows:
- Recibiremos webhooks por CADA interacción en el chat.
- Al incluir el campo "encounter", no necesitamos hacer llamadas REST adicionales para saber el estado de la consulta, ¡viene de regalo en el evento!
- Eventos de "creación" y "cierre" de la consulta se deducen a través de la recepción de los mensajes de sistema generados por el backend en esos mismos instantes.
4. Leader/Follower — Impacto en Pet Flows¶
Contexto¶
graph LR
subgraph "Estado Actual"
NC["🦎 netcomp (Erlang)<br/>LEADER actual<br/>ES 6 (persistencia)"]
PC["🐾 pet-cloud (Java)<br/>FOLLOWER actual<br/>PG + ES 7"]
RMQ["RabbitMQ<br/>Sync bidireccional"]
end
subgraph "Estado Futuro (GoLive Julio 2026)"
PC2["🐾 pet-cloud<br/>LEADER<br/>PG + ES 7"]
NC2["🦎 netcomp<br/>FOLLOWER<br/>Solo lectura"]
end
subgraph "Estado Final"
PC3["🐾 pet-cloud<br/>SOLO SISTEMA<br/>netcomp eliminado"]
end
NC <-->|"AMQP payload completo"| RMQ
PC <-->|"AMQP payload completo"| RMQ
NC -->|"GoLive"| PC2
PC -->|"GoLive"| NC2
PC2 -->|"Migración completa"| PC3
style NC fill:#ef4444,color:#fff
style PC fill:#009BE0,color:#fff
style NC2 fill:#f97316,color:#fff
style PC2 fill:#009BE0,color:#fff
style PC3 fill:#059669,color:#fff
Regla Crítica para Pet Flows¶
[!IMPORTANT] Solo el LEADER debe emitir webhooks a Pet Flows.
Si ambos sistemas emiten webhooks (netcomp como leader actual + pet-cloud como follower), Pet Flows recibiría eventos duplicados.
Solución: Configurar
webhook_new_message_recipientssolo en el sistema que sea Leader en cada momento: - Ahora: netcomp es Leader → netcomp emite el webhook - Post GoLive: pet-cloud es Leader → pet-cloud emite el webhook - Final: pet-cloud único sistema → webhook nativo
Implicación para la Arquitectura¶
| Fase | Leader | Webhook emitido por | Cambio necesario en Pet Flows |
|---|---|---|---|
| Pre-GoLive (ahora → julio) | netcomp | netcomp | Ninguno — solo configurar URL |
| GoLive (julio) | pet-cloud | pet-cloud | Verificar que el payload es compatible |
| Post-migración | pet-cloud (solo) | pet-cloud | Ninguno |
[!TIP] Buena noticia: Como ambos sistemas envían "fotos completas" del estado de la entidad via RabbitMQ, el payload del webhook debería ser idéntico independientemente de quién sea el Leader. Pero hay que verificar que pet-cloud implementa el mismo mecanismo de webhook que netcomp.
5. Preguntas Abiertas RESUELTAS (Spike Terminado)¶
| # | Pregunta | Resultado del Spike |
|---|---|---|
| 1 | ¿El webhook se dispara por mensaje o por encounter? | ✅ Por mensaje. Únicamente cuando se inserta un mensaje de chat, incluyendo mensajes automáticos del sistema. |
| 2 | ¿Qué campos incluye el payload del webhook? | ✅ Híbrido ideal. Incluye un nodo "message" y un nodo "encounter" con la instantánea del caso en ese momento. |
| 3 | ¿Pet-cloud implementa el mismo mecanismo de webhook que netcomp? | ✅ SÍ. Implementado en com.dkv.pet.module.dkvtelemed.TelemedExtCallback.java con idéntico payload cifrado. |
| 4 | ¿Hay un evento de tipo "encounter_closed" en el webhook? | ✅ SE INFIERE. Cuando se cierra un caso en netcomp/pet-cloud, se auto-genera un mensaje para el paciente. Ese mensaje gatilla el webhook y trae consigo el "encounter": { "status": "closed" }. |
| 5 | ¿Durante Leader/Follower, ambos envían webhooks o solo el Leader? | ⚠️ Punto de Riesgo Menor. En teoría, si ambos ecosistemas están suscritos vía RabbitMQ, podrían emitir webhooks duplicados. Mitigación Pet Flows: Debe procesar eventos basados en el message_id ignorando procesamientos repetidos (idempotencia en el broker Dapr Pub/Sub). |
Documentos Relacionados¶
| Documento | Propósito |
|---|---|
| 01 — Mapa de Piezas | Vista general del ecosistema |
| aux_04 — DTM | Distributed Task Manager |
| 04 — Anatomía MVP Backlog | Flujo concreto que depende de estos webhooks |