You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
taskbot/docs/plan-onboarding-comandos.md

313 lines
15 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# Plan por fases: Onboarding por DM y simplificación de comandos
Este documento define un plan incremental para:
- Introducir onboarding por DM no intrusivo (máx. 2 DMs por usuario, espaciados 14 días).
- Simplificar los comandos de visualización.
- Ajustar el material de ayuda.
- Añadir métricas y banderas de configuración.
- Mantener "cero mensajes en grupos" (solo reacciones).
Se prioriza minimizar migraciones y cambios de superficie, aprovechando infraestructura existente (ResponseQueue, GroupSync, Identity/Contacts, Help v2).
Estado actual relevante (resumen)
- El bot ya responde por DM a acciones de tareas y evita escribir en grupos (salvo reacciones).
- Listados de tareas: “ver grupo/mis/todas/sin”.
- Help v2 en src/services/messages/help.ts (copys).
- Envío de mensajes mediante ResponseQueue con metadata JSON (ya se usa para reacciones).
- GroupSync mantiene una cache y utilidades de membresía y snapshot frescas.
- No hay aún estado explícito de onboarding por usuario.
Principios
- Nunca escribimos mensajes en grupos (solo reacciones).
- Onboarding solo se dispara cuando se crea una tarea en un grupo (evento con “excusa” clara).
- Onboarding por usuario: máx. 2 paquetes (cada paquete = 2 DMs consecutivos con breve retraso), separados al menos 14 días y solo si no hubo interacción desde el primer paquete.
- Alias de comandos más cortos y claros para fomentar uso por DM.
---
## Fase 0 — Auditoría y decisiones de compatibilidad (Completada)
Objetivos
- Acordar defaults y compatibilidad de comandos.
- Confirmar feature flags y límites.
- Asegurar que no afectaremos flujos sensibles.
Archivos a consultar
- src/services/command.ts
- src/services/messages/help.ts
- src/utils/whatsapp.ts
- src/services/allowed-groups.ts
- tests relacionados con comandos de listado (no incluidos aquí)
Overview de cambios (sin código)
- Definir que en DM “/t ver” (sin argumentos) se comporte como “todas”.
- Mantener compatibilidad con “/t ayuda”, pero comunicar “/t info” como alias preferido.
- Aceptar “/t mias” y “/t todas” como atajos (alias de “ver mis” y “ver todas”).
- En contexto de grupo, cualquier intento de “ver …” no debe listar en el grupo; se responderá por DM (mensaje breve de transición).
- Flags/env de onboarding (ver Fase 4).
Criterios de aceptación
- Decisión documentada: “/t ver” en DM => “todas”.
- Alias permitidos y comunicados en help.
- Confirmación de “cero mensajes en grupo”.
---
## Fase 1 — Alias y routing de comandos (sin onboarding aún) (Completada)
Objetivos
- Añadir y mapear alias “info” → “ayuda”; “mias” → “ver mis”; “todas” → “ver todas”.
- Cambiar default de “/t ver” (en DM) a “todas”.
- En grupo, redirigir listados a DM con mensaje corto de transición (sin listar en el grupo).
Archivos a modificar
- src/services/command.ts
- src/services/messages/help.ts (copys actualizados con alias)
- src/utils/icons.ts y src/utils/formatting.ts (solo si se requiere algún símbolo/estilo nuevo)
Overview de cambios
- Extender ACTION_ALIASES y/o routing para nuevas acciones y scopes.
- Detectar contexto de grupo y bloquear listados en el grupo (enviar por DM un mensaje de transición: “No respondo en grupos. Tus tareas: /t mias · Todas: /t todas · Info: /t info · Web: /t web”).
- Help v2: mostrar “/t mias”, “/t todas”, “/t info”; retirar “ver grupo” de la guía básica y sugerir web para ver todo el grupo.
Impacto en tests
- Actualizar tests que esperen “/t ver” => “mis” en DM.
- Añadir tests de alias (“mias”, “todas”, “info”).
- Tests de transición desde grupo (no hay listados en el grupo; respuesta por DM).
---
## Fase 2 — Infra de Onboarding por DM en paquetes (2 DMs, migración mínima para interacción) (Completada)
Objetivos
- Enviar un paquete de 2 DMs (Mensaje 1 + Mensaje 2) por usuario cuando se crea una tarea en un grupo.
- Mensaje 1: CTA “/t tomar {CÓDIGO}” + “/t info”.
- Mensaje 2: minichuleta (“/t mias”, “/t todas”, “/t configurar …”, “/t web”), 510 s después del Mensaje 1.
- Repetir el mismo paquete una única vez más si pasan ≥ 14 días sin interacción del usuario (si hubo interacción, no se envía el segundo paquete).
- Cap por evento; sin mensajes en grupos.
Archivos a modificar
- src/services/group-sync.ts (añadir listActiveMemberIds(groupId): string[])
- src/services/response-queue.ts (añadir helpers para onboarding con metadata { kind='onboarding', variant, part, bundle_id } y soporte de retraso para el segundo DM del paquete; getOnboardingStats)
- src/services/command.ts (desencadenar el paquete tras crear tarea en grupo, respetando gating y caps; actualizar users.last_command_at al recibir cualquier comando)
- src/services/allowed-groups.ts (usado para gating en modo enforce)
- src/db/migrations/* (añadir columna users.last_command_at) y wiring en src/db/migrator.ts
- src/services/identity.ts y src/services/contacts.ts (solo consumo; no se cambian)
Overview de cambios
- GroupSyncService: nuevo helper para obtener IDs de miembros activos del grupo (solo dígitos, grupos activos, no comunidad/archivados).
- ResponseQueue:
- enqueueOnboarding(recipient, message, metadata) con metadata canónica: { kind: 'onboarding', variant: 'initial'|'reminder', part: 1|2, bundle_id, group_id, task_id, display_code }.
- getOnboardingStats(recipient): { total, lastSentAt, lastVariant?: 'initial'|'reminder' } consultando response_queue por metadata.kind='onboarding'.
- Soportar programar el segundo DM del paquete con un retraso aleatorio de 500010000ms.
- CommandService (en /t nueva):
- Tras crear la tarea en grupo, construir candidatos:
- miembros activos del grupo (GroupSync.listActiveMemberIds),
- excluir creador, asignados y el número del bot,
- filtrar por dígitos puros con longitud < 14,
- si GROUP_GATING_MODE=enforce y el grupo no está allowed no enviar.
- Cap por evento (ONBOARDING_EVENT_CAP, p. ej. 30).
- Para cada destinatario:
- Si no hay paquetes previos encolar paquete 'initial' con 2 DMs (part=1 ahora; part=2 con retraso).
- Si hay paquete 'initial' y han pasado 14 días SIN interacción (users.last_command_at primer paquete) encolar paquete 'reminder' (2 DMs).
- En cualquier otro caso no enviar.
- Envío del primer DM del paquete inmediato (next_attempt_at = now) y el segundo con pequeño retraso. Ventanas horarias opcionales (ver Fase 4).
Copys de onboarding (exactos)
- Mensaje 1 (en ambos disparos):
- Hola, soy el bot de tareas. En {Grupo} acaban de crear una tarea: #{CÓDIGO} {descripción corta}
Encárgate: /t tomar {CÓDIGO} · Más info: /t info
Nota: nunca respondo en grupos; solo por privado.”
- Mensaje 2 (minichuleta; se envía tras 510 s, en ambos disparos):
- Guía rápida (este es un mensaje único):
· Tus tareas: /t mias · Todas: /t todas
· Recordatorios: /t configurar diario | lv | semanal | off
· Web: /t web
Impacto en tests
- Tests unitarios para:
- Construcción de destinatarios (exclusiones, cap).
- Paquetes: por disparo se encolan 2 DMs/usuario (part=1 y part=2 con retraso).
- Recordatorio a los 14 días solo si no hubo interacción desde el primer paquete; si la hubo, skip.
- Gating enforce (grupo no allowed no enviar).
- Metadata de enqueue (kind='onboarding', variant initial|reminder, part 1|2, bundle_id).
Notas sobre migraciones
- Migración mínima recomendada: añadir users.last_command_at para registrar la última interacción del usuario y así decidir si enviar el segundo paquete tras 14 días. Actualizar este campo al procesar cualquier comando entrante.
- Si no se implementa, el recordatorio se puede degradar a si han pasado 14 días desde el primer paquete”, sin comprobar interacción (menos preciso).
---
## Fase 3 — Ajustes de ayuda (Help v2) y refuerzos en DMs operativos ()
Objetivos
- Actualizar help rápido/completo con alias y nuevas recomendaciones.
- Añadir CTAs discretos al final de DMs operativos existentes (ack al crear y DM al asignado).
Archivos a modificar
- src/services/messages/help.ts
- src/services/command.ts (añadir línea discreta al final de acks y DMs al asignado)
Overview de cambios
- Help rápido:
- Ver mis: /t mias (por privado)”
- Ver todas: /t todas (por privado)”
- Más info: /t info
- Retirar ver grupo de la guía básica; sugerir web (“/t web”).
- Help completo: reflejar mias/todas/info y la política de no responder en grupos”.
- CTAs discretos al final de DMs operativos:
- Tus tareas: /t mias · Todas: /t todas · Info: /t info · Web: /t web
Impacto en tests
- Actualizar snapshots/expectativas del help y de los DMs.
---
## Fase 4 — Métricas y flags de configuración ()
Objetivos
- Medir adopción y salud del onboarding y de alias.
- Controlar comportamiento con variables de entorno.
Archivos a modificar
- src/services/command.ts (instrumentación Metrics.inc/set donde corresponda)
- src/services/response-queue.ts (contadores al encolar onboarding)
- src/services/group-sync.ts (counters si se desea, p. ej. onboarding_skipped_not_allowed”)
- src/services/metrics.ts (no requiere cambios de API)
Métricas propuestas
- onboarding_dm_sent_total (labels: variant=initial|reminder, part=1|2, group_id)
- onboarding_bundle_sent_total (labels: variant=initial|reminder, group_id) opcional
- onboarding_dm_skipped_total (labels: reason, group_id)
- reasons: 'cooldown_active', 'capped_event', 'not_allowed', 'disabled', 'no_members', 'no_group', 'not_group_context', 'no_display_code', 'had_interaction'
- onboarding_recipients_capped_total (labels: group_id)
- commands_alias_used_total (labels: action=info|mias|todas)
- commands_blocked_total (ya existe para gating; mantener)
Flags/env sugeridas
- ONBOARDING_DM_ENABLED=true
- ONBOARDING_DM_COOLDOWN_DAYS=14
- ONBOARDING_EVENT_CAP=30
- ONBOARDING_BUNDLE_DELAY_MS=4000
- ONBOARDING_ENABLE_IN_TEST=false (o true si se van a probar envíos en tests)
- GROUP_GATING_MODE=enforce|off (ya existente)
- Opcional (si se diferencia horario amable): ONBOARDING_SILENCE_HOURS=22-08 (futuro)
Overview de cambios
- Usar Metrics.inc/set en los puntos de decisión.
- Leer flags con defaults robustos y sin romper tests.
---
## Fase 5 — Tests y validación end-to-end ()
Objetivos
- Cubrir alias nuevos, cambios de routing, y lógica de onboarding.
- Garantizar cero mensajes en grupo”.
Áreas de test
- Alias:
- “/t info ayuda
- “/t mias listado de asignadas
- “/t todas listado combinado (DM)
- “/t ver (DM) todas
- Contexto grupo:
- Invocar listados desde un grupo responde por DM con transición (no lista en el grupo).
- Onboarding:
- Por evento de creación en grupo se encolan 2 DMs/usuario (part=1 inmediato y part=2 con retraso).
- Tras 14 días sin interacción desde el primer paquete, se encola un segundo paquete idéntico; si hubo interacción, no se encola.
- Gating enforce: grupos no permitidos no enviar.
- Metadata de response_queue correcta (kind, variant, part, bundle_id).
- Help v2 actualizado (snapshots).
- CTAs añadidos al final de DMs operativos.
---
## Fase 6 — Despliegue y control ()
Objetivos
- Desplegar con seguridad y capacidad de rollback.
- Observar métricas clave.
Checklist de despliegue
- Activar ONBOARDING_DM_ENABLED en staging, validar envíos y métricas.
- Validar alias y help actualizados.
- Monitorizar:
- onboarding_dm_sent_total vs skipped.
- Uso de “/t mias”, “/t todas”, “/t info”.
- web_tokens_issued_total (por “/t web”).
- Habilitar en producción. Ajustar ONBOARDING_EVENT_CAP si hay grupos muy grandes.
---
## Fase 7 — Consideraciones futuras (no bloqueantes) ()
Ideas a evaluar después
- Bienvenida al primer DM inbound (mensaje corto de bienvenida una única vez cuando el usuario inicia chat).
- Ventanas horarias: programar next_attempt_at si se detecta horario nocturno (requiere mínima lógica extra).
- Tabla explícita de onboarding (si se quiere persistir fuera de response_queue), p. ej. user_onboarding con timestamps y contadores.
- Resumen semanal optin (ya soportado con “/t configurar …”): medir retención y satisfacción.
---
## Resumen de archivos a cambiar (referencia)
- src/services/command.ts
- Alias y routing: info”, mias”, todas”; “/t ver en DM => “todas”.
- Mensaje de transición al detectar listados desde grupo (solo DM).
- Disparo de onboarding tras crear tarea en grupo (con caps y cooldown).
- CTAs discretos al final de acks y DMs al asignado.
- Instrumentación de métricas.
- src/services/messages/help.ts
- Actualizar copys a “/t mias”, “/t todas”, “/t info”.
- Retirar ver grupo del básico y empujar web para ver todo el grupo.
- src/services/group-sync.ts
- Añadir listActiveMemberIds(groupId): string[].
- src/services/response-queue.ts
- Añadir enqueueOnboarding() y getOnboardingStats().
- Incrementar métricas al encolar.
- src/services/allowed-groups.ts
- Solo consumo para gating (no cambios de API).
- src/utils/whatsapp.ts, src/utils/formatting.ts, src/utils/icons.ts
- Sin cambios estructurales; mantener estilos y símbolos.
- src/services/metrics.ts
- Reutilización. No requiere cambios, solo llamadas desde los puntos anteriores.
---
## Copys finales (para implementación)
1) Onboarding Mensaje 1 (initial)
- Hola, soy el bot de tareas. En {Grupo} acaban de crear una tarea: #{CÓDIGO} {descripción corta}
Encárgate: /t tomar {CÓDIGO} · Más info: /t info
Nota: nunca respondo en grupos; solo por privado.”
2) Onboarding Mensaje 2 (reminder, único)
- Guía rápida (este es un mensaje único):
· Tus tareas: /t mias · Todas: /t todas
· Recordatorios: /t configurar diario | lv | semanal | off
· Web: /t web
3) Transición cuando se intenta listar desde grupo (responder por DM)
- No respondo en grupos. Tus tareas: /t mias · Todas: /t todas · Info: /t info · Web: /t web
4) Línea discreta al final de DMs operativos (ack creación y DM a asignados)
- Tus tareas: /t mias · Todas: /t todas · Info: /t info · Web: /t web
---
## Riesgos y mitigaciones
- Saturación en grupos grandes Cap por evento (ONBOARDING_EVENT_CAP, p. ej. 30) + cooldown 14 días por usuario.
- IDs no resueltos Filtrar a /^\d+$/ y excluir alias no mapeados.
- Confusión por comandos antiguos Alias mias/todas/info visibles en help; mensajes de transición desde grupo.
- Métricas y observabilidad Añadir contadores con labels para entender adopción y fricción.
---