Saltar a contenido

🔄 MVP — Dinamización de Conversaciones Abandonadas

Fecha: 1 de abril de 2026 Propósito: Estudio de viabilidad técnica del nuevo MVP Backlog solicitado por el cliente Estado: Análisis completo — Pendiente de decisión


1. Resumen del Requisito

"Incorporar un sistema de notificaciones para dinamización de conversaciones abandonadas, adaptando el cierre automático para procesos de continuidad (prevención, coach) e introduciendo notificaciones proactivas que animen al cliente a retomar la interacción."

Los 4 Pilares del MVP

# Pilar Descripción
1 Identificar Detectar conversaciones abandonadas en servicios de continuidad
2 Prorrogar Incrementar tiempo de cierre automático para estos servicios
3 Notificar Enviar push proactivos durante la prórroga
4 Resolver Si retoma → continúa. Si no → cierra tras prórroga

2. 🔑 Hallazgo Crítico: La Infraestructura YA Existe (60%)

Del análisis del código de QueueDetailsNotifications.jsx y Queue/index.jsx, la entidad Cola ya tiene los campos necesarios:

graph TB
    subgraph "Campos que YA EXISTEN en la Cola"
        A["max_inactive_patient_warning_time<br/>⏰ Aviso de inactividad del paciente<br/>(en minutos)"]
        B["max_inactive_patient_time<br/>⏰ Tiempo Máximo de Inactividad del Paciente<br/>(en minutos)"]
        C["close_inactive_encounters<br/>☑️ Cerrar casos inactivos automáticamente"]
        D["max_inactive_time<br/>⏰ Tiempo Máximo de Inactividad general<br/>(en minutos)"]
        E["revoke_inactive<br/>☑️ Revocar + re-evaluar políticas"]
    end

    subgraph "Lo que NECESITA el MVP"
        F["Prórroga de cierre para servicios de continuidad"]
        G["Notificación push al paciente durante prórroga"]
        H["Configuración diferenciada por servicio/cola/motivo"]
        I["Deep link para retomar conversación"]
    end

    A -.->|"Parcialmente equivalente a"| F
    B -.->|"Es exactamente"| F
    C -.->|"Controla"| F

    style A fill:#059669,color:#fff
    style B fill:#059669,color:#fff
    style C fill:#059669,color:#fff
    style D fill:#059669,color:#fff
    style E fill:#059669,color:#fff
    style F fill:#D97706,color:#fff
    style G fill:#ef4444,color:#fff
    style H fill:#D97706,color:#fff
    style I fill:#ef4444,color:#fff

Mapeo Campo por Campo

Campo existente Tipo Valor actual ¿Sirve para MVP?
max_inactive_patient_warning_time int (min) configurable PARCIAL / INVÍABLE: Netcomp dispara un push genérico estandarizado hardcodeado en Erlang (encounter_inactive) y solo se ejecuta una vez. Si queremos notificaciones multi-stage o custom, no podemos usarlo sin tocar Erlang.
max_inactive_patient_time int (min) configurable INVÍABLE: Netcomp ejecuta un script de cierre incondicional (dkv_telemed_util:close_encounter). No permite prórrogas dinámicas desde Pet Flows.
close_inactive_encounters bool true/false 🟡 Controla si actúa el script de Erlang. Para Pet Flows, deberá ser FALSE en colas dinamizadas.
max_inactive_time int (min) 15 🟡 Parcial — Es para el doctor, no para el paciente
revoke_inactive bool true/false 🟡 Parcial — Reasignación, no notificación

[!WARNING] Resultado del Spike técnico (Erlang/netcomp): Si reutilizamos max_inactive_patient_warning_time, el sistema emite automáticamente un push nativo al paciente (ej: "Tu consulta sigue abierta") hardcodeado en el código fuente. Esto imposibilita una orquestación multi-stage de Push Notifications personalizada sin requerir despliegues de netcomp. La infraestructura existe, pero su rigidez contradice el requisito del cliente (mensajes configurables y multi-stage prórroga).


3. Análisis de Gap — Lo que Existe vs Lo que Falta

Requisito MVP ¿Existe? Dónde Gap
Detectar conversación abandonada ✅ Existe PET: lógica de inactividad en cola Ninguno
Diferenciar por tipo de servicio 🟡 Parcial Cola tiene component_type, product_ids Necesita: filtro por "servicio de continuidad"
Diferenciar por cola ✅ Existe Cada cola tiene su propia config de tiempos Ninguno
Diferenciar por motivo de apertura 🔴 No existe El encounter tiene closing_reason, pero no opening_reason en cola config Gap: necesita nuevo campo o lógica
Incrementar tiempo de cierre ✅ Existe max_inactive_patient_time ya es configurable por cola Solo ajustar el valor
Enviar push al paciente 🔴 No existe El sistema actual envía emails a operadores, no push a pacientes Gap principal
Deep link para retomar 🔴 No existe Gorush soporta deep links, pero no hay lógica de "retomar encounter" Gap: necesita endpoint + deep link
Cierre tras prórroga ✅ Existe close_inactive_encounters + max_inactive_patient_time Solo configurar
Configurar mensajes por servicio/cola 🔴 No existe Las notificaciones existentes no tienen templates personalizables Gap: templates de push

Los 4 Gaps Principales

┌─────────────────────────────────────────────────────────────────────┐
│  GAP 1: Enviar push al PACIENTE (no al operador)                   │
│  → Hoy: email a destinatarios humanos (operadores/jefes de cola)   │
│  → MVP: push notification al paciente via Gorush con deep link   │
│                                                                     │
│  GAP 2: Lógica de "cuándo notificar" durante la prórroga           │
│  → Hoy: hay un warning_time pero no se sabe qué acción dispara     │
│  → MVP: a los X minutos de inactividad → push #1                │
│            a los Y minutos → push #2 (recordatorio)                │
│            a los Z minutos → cierre definitivo                     │
│                                                                     │
│  GAP 3: Templates de notificación configurables                     │
│  → Hoy: no hay templates de push por cola/servicio                 │
│  → MVP: "Hola {{nombre}}, tu conversación con {{doctor}}         │
│            sigue abierta. ¿Necesitas continuar?"                   │
│                                                                     │
│  GAP 4: Deep link de retoma                                        │
│  → Hoy: no existe deep link a encounter activo                     │
│  → MVP: qcplus://encounter/{{encounter_id}}/resume              │
└─────────────────────────────────────────────────────────────────────┘

4. Dos Opciones de Implementación

Opción A — Solo config PET (sin Pet Flows)

graph LR
    PET["🐾 PET Cloud<br/>Detecta inactividad"] 
    -->|"Nuevo código Java"| LOGIC["⚙️ Lógica nueva<br/>Evalúa servicio<br/>Decide push"]
    --> NTF["📲 dkv-notifications<br/>Envía push"]
    --> APP["📱 QC+ App<br/>Deep link retoma"]

    style PET fill:#009BE0,color:#fff
    style LOGIC fill:#D97706,color:#fff
    style NTF fill:#059669,color:#fff

Qué implica: - Añadir en PET (Java/Spring Boot) lógica que, al detectar inactividad del paciente, envíe push via dkv-notifications - Configurar templates de push en la cola (nuevos campos) - Implementar deep link de retoma en la app QC+

Pro Contra
Sin dependencia de Pet Flows Código hardcodeado en PET
Rápido para 1 uso específico No reutilizable para otros flujos
Equipo Java existente puede hacerlo Sin editor visual, sin dashboard
Cada cambio = deploy de PET
No soporta múltiples notificaciones en secuencia fácilmente

Estimación: 15-20 SP, 2-3 semanas

Opción B — PET + Pet Flows (Recomendada)

graph LR
    PET["🐾 PET Cloud<br/>Detecta inactividad"]
    -->|"Webhook"| FLOWS["📊 Pet Flows<br/>Flujo visual"]
    --> WAIT["⏱️ Wait<br/>Prórroga"]
    --> PUSH["📲 Push<br/>via dkv-notifications"]
    --> CHECK["🔍 ¿Retomó?<br/>Query a PET"]

    CHECK -->|"Sí"| END1["✅ Fin<br/>Conversación activa"]
    CHECK -->|"No"| PUSH2["📲 Recordatorio #2"]
    PUSH2 --> CLOSE["🔒 Cierre<br/>POST a PET"]

    style PET fill:#009BE0,color:#fff
    style FLOWS fill:#7C3AED,color:#fff
    style WAIT fill:#6366f1,color:#fff
    style PUSH fill:#059669,color:#fff
    style CHECK fill:#D97706,color:#fff

Qué implica: - PET emite webhook cuando detecta inactividad del paciente (campo max_inactive_patient_warning_time) - Pet Flows ejecuta un flujo visual que: 1. Espera N minutos 2. Envía push #1 3. Espera M minutos 4. Consulta PET: ¿el paciente retomó? 5. Si no → push #2 6. Espera P minutos 7. Si no retomó → cierra via API

Pro Contra
Configurable visualmente — marketing puede ajustar tiempos y mensajes Necesita Pet Flows operativo (MVP Backlog primero o en paralelo)
Reutilizable — mismo motor para MVP Backlog (encuesta) y MVP Más componentes en producción
Dashboard — se ve qué conversaciones están en prórroga Mayor complejidad inicial
Escalable — mañana añades email, SMS, IA
No toca código Java para cambios de flujo

Estimación: 25-30 SP, pero reutiliza 80% del trabajo del MVP Backlog


5. Diseño del Flujo MVP (Opción B Refinada — Dapr Timers)

Dado que no podemos modificar el core de Erlang para detener el push automático y único, Pet Flows se convierte en el Orquestador Cronometrado.

graph TD
    T["⚡ TRIGGER<br/>Nuevo Mensaje en Chat<br/>App: DKV PET<br/>(vía webhook)"]
    --> F["🔍 DAPR ACTOR<br/>Actualiza 'LastMessageTime'<br/>(Resetea Timer)"]

    F --> W1["⏱️ DAPR TIMER<br/>T=24h Inactividad<br/>(configurable)"]
    W1 --> P1["📲 PUSH #1<br/>'Hola {{nombre}}, tu consulta...'"]

    P1 --> W2["⏱️ DAPR TIMER<br/>T=48h Inactividad<br/>(configurable)"]
    W2 --> P2["📲 PUSH #2<br/>'{{nombre}}, tu conversación se cerrará...'"]

    P2 --> W3["⏱️  DAPR TIMER<br/>T=72h Inactividad<br/>(configurable)"]
    W3 --> CLOSE["🔒 CERRAR<br/>POST /encounters/{{id}}/close<br/>reason: inactivity_timeout"]

    style T fill:#7C3AED,color:#fff
    style F fill:#D97706,color:#fff
    style W1 fill:#6366f1,color:#fff
    style P1 fill:#059669,color:#fff
    style W2 fill:#6366f1,color:#fff
    style P2 fill:#059669,color:#fff
    style W3 fill:#6366f1,color:#fff
    style CLOSE fill:#ef4444,color:#fff

La regla de Oro "Zero-Erlang-Touch"

Para las colas que queramos dinamizar mediante Pet Flows (ej. Coach, Prevención): 1. Configurar en el admin legacy (PET): max_inactive_patient_warning_time = 0 y close_inactive_encounters = false. (Se desactiva la inactividad nativa). 2. Delegar en Pet Flows: Al recibir cualquier mensaje de paciente vía webhook_new_message_recipients, Dapr registra el tiempo y planifica cronómetros independientes. Si entra un nuevo mensaje, el cronómetro nativo de Dapr se borra/sobrescribe.

Esto nos confiere el 100% del control del flujo (Push #1, Push #2, SMS, etc.) sin inyectar ninguna lógica adicional en netcomp.

Nodo App Módulo ¿Existe en MVP Backlog?
Trigger: Inactividad paciente 🐾 DKV PET pet-patient-inactive Nuevo trigger
Filtro por servicio (edge filter) Condición en edge ✅ Ya existe
Wait (30/60/120 min) 🔧 Flow Control fc-sleep ✅ Sí
Push notification 📲 Notificaciones notify-push-rich ✅ Sí
Consultar PET 🗄️ Datos data-http ✅ Sí
Cerrar encounter 🐾 DKV PET pet-close-encounter Nueva acción
Log/Analytics 🗄️ Datos data-variable ✅ Sí

Solo necesitamos 2 módulos nuevos: pet-patient-inactive (trigger) y pet-close-encounter (acción).


6. Configuración de Mensajes por Servicio/Cola/Motivo

El requisito dice: "La herramienta permite configurar diferentes mensajes de notificación en función de: Servicio, Cola, Motivo de apertura."

Resolución con Pet Flows

En vez de crear un sistema de templates rígido en PET, cada combinación servicio+cola+motivo se resuelve con un flujo distinto o con bifurcaciones dentro del mismo flujo:

Flujo: Dinamización Prevención    Flujo: Dinamización Coach
├── Cola: Prevención General      ├── Cola: Coach Nutrición
├── Mensaje: "Tu plan de          ├── Mensaje: "Tu coach
│   prevención sigue activo..."   │   te espera..."
├── Prórroga: 4 horas             ├── Prórroga: 24 horas
└── Recordatorios: 2              └── Recordatorios: 3

                    O (alternativa)

Flujo Único: Dinamización General
├── Trigger: Inactividad paciente
├── Router: ¿Qué tipo de servicio?
│   ├── Rama Prevención → mensajes de prevención
│   ├── Rama Coach → mensajes de coach
│   └── Rama Default → mensajes genéricos
└── Configuración visual, sin código

[!TIP] Ventaja del editor visual: Marketing puede crear/modificar flujos por cola sin pedir deploy a desarrollo. Esto es exactamente lo que el requisito describe como "quick win".


7. Cambios Necesarios en PET Cloud (¡NINGUNO CORE!)

Gracias a reorientar la solución a Timers en Dapr (Pet Flows), eludimos el riesgo de tocar el Core de Netcomp en pleno proceso Leader/Follower.

# Cambio Tipo Esfuerzo
1 Solo Configuración: Setear close_inactive_encounters a false en colas específicas. Backoffice 1 SP
2 En lugar de webhook de inactividad, interceptar el webhook de todos los mensajes (que ya se emite) para registrar inactividad (LastUpdated). Pet Flows -
3 Endpoint REST: POST /api/telemed/v1/encounters/{id}/close invocado por Pet Flows (Actualmente ya debe existir para backoffice/admin). Verificación 2 SP

[!TIP] Beneficio Colateral: Al no requerir agregar un nuevo webhook al core (Erlang netcomp), el GoLive de MVP se desliga completamente de presiones del equipo Erlang. Todo el esfuerzo reside en la pieza dkv-pet-flows bajo Quarkus.


8. Comparativa: MVP Backlog vs MVP

Dimensión MVP Backlog (Encuesta) MVP (Dinamización)
Trigger Caso cerrado (webhook existente) Inactividad paciente (webhook NUEVO)
Acción principal Push con deep link a encuesta Push con deep link a retomar conversación
Complejidad del flujo Lineal: trigger → wait → push Cíclico: trigger → push → check → push → check → close
Cambios en PET Solo configurar URL webhook Nuevo evento webhook + posible endpoint extend
Canales Push + email fallback Push (obligatorio, paciente nativo)
Nodos nuevos 0 (todos del catálogo) 2 (pet-patient-inactive, pet-close-encounter)
Reutilización Base para todo lo demás Reutiliza 80% de MVP Backlog
Valor demostrable "El sistema envía encuestas" "El sistema salva conversaciones" → mayor impacto de negocio
Riesgo Bajo (webhook ya existe) Medio (necesita cambio en PET → GoLive julio)

9. Estimación de Esfuerzo (Opción B)

Si MVP Backlog ya está hecho (incremental)

# Story SP Prioridad
B.1 Nuevo trigger pet-patient-inactive en Pet Flows 3 Must
B.2 Nueva acción pet-close-encounter (POST a PET) 3 Must
B.3 Cambio en PET: emitir webhook al alcanzar max_inactive_patient_warning_time 5 Must
B.4 Flujo visual: P1 → Wait → Check → P2 → Wait → Close 5 Must
B.5 Templates de push personalizados por cola 3 Must
B.6 Deep link qcplus://encounter/{id}/resume en app QC+ 3 Must
B.7 Verificar: ¿qué hace el warning_time hoy en PET? 2 Must
B.8 Router por tipo de servicio (prevención/coach/general) 3 Should
B.9 Dashboard: conversaciones en prórroga (SSE) 5 Should
Total incremental 32 SP ~3 semanas

Si MVP Backlog NO está hecho (desde cero)

Componente SP
MVP Backlog completo 65
MVP incremental 32
Total combinado ~75 SP (comparten ~22 SP de infra)
Duración ~6-7 semanas

10. Mapeo a Criterios de Aceptación

# Criterio ¿Cubierto? Cómo
1 Sistema identifica conversaciones abandonadas en servicios de continuidad Trigger pet-patient-inactive + filtro por component_type
2 Tiempo de cierre automático se incrementa max_inactive_patient_time configurable por cola
3 Durante la prórroga se envían push al cliente Nodos Push en flujo visual con Wait entre ellos
4 Notificaciones configurables por servicio, cola y motivo Router por servicio + templates por cola
5 Cliente puede retomar desde la notificación Deep link qcplus://encounter/{id}/resume
6 Si no hay interacción, cierre automático tras prórroga Check + Close al final del flujo
7 Alcance limitado a dinamización Flujo solo para conversaciones abandonadas

11. Mapeo a Casos de Prueba

Caso Flujo Pet Flows Verificación
Caso 1: Prórroga Trigger → Cola prevención con max_inactive_patient_time = 240min Config en dkv-pet-admin
Caso 2: Push durante prórroga Wait 30min → Push #1 al paciente Log en ejecución + entry en Gorush
Caso 3: Retoma exitosa Check: GET /encounters/{id} → status != inactive Flujo termina con LOG "resumed"
Caso 4: Cierre definitivo Check: status = inactive → POST /encounters/{id}/close Encounter cerrado en PET

12. Análisis de Riesgos

Riesgo Probabilidad Impacto Mitigación
Cambio en PET durante GoLive 🔴 Alta 🔴 Alto Hacer el cambio SOLO en pet-cloud (no en netcomp). Si pet-cloud es follower, el webhook se activa solo cuando sea leader
max_inactive_patient_warning_time no dispara nada hoy 🟡 Media 🟡 Medio Spike: verificar código Java. Si no dispara, hay que añadir el listener
Deep link roto en app QC+ 🟡 Media 🟡 Medio Verificar con equipo mobile. Schema qcplus:// debe estar registrado
Push no llega (token expirado) 🟡 Media 🟡 Medio Fallback: ni email ni SMS — si push falla, se cierra sin notificación (aceptable para MVP Backlog)
Volumen alto de conversaciones abandonadas 🟡 Media 🟡 Medio Dapr maneja volumen. Rate limiter en flujo

13. Recomendación Estratégica

[!IMPORTANT] MVP tiene mayor impacto de negocio que MVP Backlog ("salvar conversaciones" > "enviar encuestas"). Pero MVP Backlog es la base técnica que MVP necesita.

Orden Recomendado

Opción 1 (Secuencial):      MVP Backlog (5 sem) → MVP (3 sem) = 8 semanas
Opción 2 (Entrelazada):     MVP Backlog+2 combinados (6-7 sem) = ganamos 1-2 semanas

La Opción 2 es factible porque MVP Backlog y MVP comparten:
  • Motor de ejecución Dapr
  • Webhook ingress
  • Push via dkv-notifications/Gorush
  • Store + serialización
  • Wait/Timer activities

Sprint Plan Combinado (Opción 2)

Sprint Semanas Entregable
Sprint 1 1-2 Fundaciones: API, Store, Webhook ingress, Dapr MVP Backlog
Sprint 2 3-4 MVP Backlog: Flujo encuesta E2E + Spike warning_time PET
Sprint 3 5-6 MVP: Trigger inactividad + Flujo dinamización + Templates push
Sprint 4 7 Polish: Dashboard prórroga + deep links + demo
Total 7 sem Ambos MVPs operativos

Documentos Relacionados

Documento Propósito
04 — Anatomía MVP Backlog Flujo encuesta (nodo a nodo)
03 — PET como App Catálogo de módulos
aux_03 — Netcomp Webhooks Webhooks y Leader/Follower
05 — Direcciones Estratégicas Sprint plan original