docs: actualiza README.md, STATUS.md; añade USER_GUIDE.md y .env

Co-authored-by: aider (openrouter/openai/gpt-5) <aider@aider.chat>
pull/1/head
borja 2 months ago
parent c9ebfb2c4e
commit 8064ba053f

@ -1,27 +1,40 @@
# .env.example
# Evolution API
# Evolution API (requerido)
EVOLUTION_API_URL="https://example-url.com"
EVOLUTION_API_KEY="example-api-key"
EVOLUTION_API_INSTANCE="example-instance"
# WhatsApp
WHATSAPP_COMMUNITY_ID="example-community-id@g.us"
CHATBOT_PHONE_NUMBER="1234567890" # Número normalizado del bot; evita auto-respuestas
# WhatsApp (requerido)
WHATSAPP_COMMUNITY_ID="example-community-id@g.us" # Comunidad principal para sincronizar grupos
CHATBOT_PHONE_NUMBER="1234567890" # Número normalizado del bot; evita auto-respuestas
# Webhook de este servicio
WEBHOOK_URL="http://your-service-internal-url:3007" # URL interna a la que Evolution API enviará webhooks
# Webhook de este servicio (requerido)
WEBHOOK_URL="http://your-service-internal-url:3007" # URL (idealmente interna) a la que Evolution API enviará webhooks
PORT=3007
# Runtime
NODE_ENV="production"
# Entorno
NODE_ENV="production" # production | development | test
TZ="Europe/Madrid" # Zona horaria usada para "hoy/mañana" y render de fechas
# Opcional: intervalo de sincronización de grupos en milisegundos (por defecto: 86400000 = 24h)
# - Usar menor durante desarrollo (p.ej. 60000 = 1 minuto)
# - Mínimo 10000ms (10s) forzado en development
# - Formato: número sin comillas
# Sincronización de grupos (opcional)
# Intervalo en milisegundos; por defecto 86400000 (24h). En desarrollo puede bajarse (mínimo recomendable 10000ms).
# GROUP_SYNC_INTERVAL_MS=86400000
# Rate limiting (opcional; desactivado en tests; por defecto 15/min)
# Notificaciones (opcional)
# Si se pone a "true", el bot enviará un breve resumen al grupo al crear una tarea (por defecto false).
# NOTIFY_GROUP_ON_CREATE=false
# Rate limiting por usuario (opcional; desactivado en tests)
# Número de comandos por minuto por usuario (refill rate). Por defecto 15.
# RATE_LIMIT_PER_MIN=15
# Capacidad del bucket (por defecto igual a RATE_LIMIT_PER_MIN).
# RATE_LIMIT_BURST=15
# Cola de respuestas (opcional — avanzado)
# Intentos máximos antes de marcar como failed (por defecto 6).
# RQ_MAX_ATTEMPTS=6
# Backoff base en milisegundos para reintentos (por defecto 5000).
# RQ_BASE_BACKOFF_MS=5000
# Backoff máximo en milisegundos (por defecto 3600000 = 1h).
# RQ_MAX_BACKOFF_MS=3600000

@ -1,96 +1,89 @@
# Estado del Proyecto - Task Manager para WhatsApp
# Estado del Proyecto Task Manager para WhatsApp
## ✅ Funcionalidades Completadas
- **Infraestructura Principal**
- Servidor webhook con health checks
- Dockerización y despliegue CapRover
- Gestión de dependencias con Bun
- **Base de Datos**
- Modelo de tareas y asignaciones
- Normalización de IDs de WhatsApp
- Transacciones atómicas
- Migrador up-only para SQLite con tabla `schema_migrations`, backup automático con `VACUUM INTO` y baseline automático si ya existe esquema
- Esquema de `response_queue` extendido con columna `metadata`
- **Sincronización de Grupos**
- Caché de grupos activos y validación en el servidor
- Sync periódico con Evolution API
- **Webhooks**
- Registro/verificación con Evolution API
- Manejo de eventos (MESSAGES_UPSERT) con normalización del nombre del evento
- Corrección: extracción robusta de remitente en DMs vs grupos para evitar 'Invalid sender ID'
- **Cola de Respuestas**
- Persistencia en DB y envío real a Evolution API
- Workers en background activos
- Soporte de menciones: persistencia en `metadata` y envío como `mentioned` en el payload
- Reintentos con backoff exponencial + jitter (4xx = fallo definitivo; 5xx/red = reintento hasta RQ_MAX_ATTEMPTS con `next_attempt_at`)
- **Comandos**
- `/tarea nueva` end-to-end: parseo de descripción y última fecha futura, extracción de asignados desde menciones y tokens `@...`, limpieza de la descripción, persistencia de tarea y asignaciones, y respuesta con menciones.
- Listados: `/t ver` con `grupo`, `mis`, `sin` y `todos`, con tope y resumen “… y X más”, siempre por DM.
- Completar: `/t x <id>` (alias: `hecho`, `completar`, `done`) con feedback compacto por DM.
- Tomar/Soltar: `/t tomar <id>` y `/t soltar <id>` implementados end-to-end con feedback compacto por DM (idempotentes).
- Fechas naturales: soporte de “hoy/mañana” en creación con TZ configurable (env TZ; por defecto Europe/Madrid).
- Ayuda por DM: “/t” y “/t ayuda” devuelven una guía breve; el bot no publica en grupos.
- **Contactos y Nombres**
- Servicio `ContactsService` con caché en memoria (TTL) y actualización por webhooks (CONTACTS_UPDATE/CHATS_UPDATE); fallback a Evolution API para obtener nombres. Se usa para mostrar nombres en los textos (con fallback a números). En entorno de test evita llamadas de red para acelerar y aislar la suite.
- **UX de Notificaciones**
- Confirmación por DM al creador (encabezado: 📝 <id> _desc_, con líneas de fecha 📅 y responsable 🚫👤/👤) y DM a cada asignado (📬, excluye al creador); fechas vencidas marcadas con ⚠️.
- Notificación opcional al grupo controlada por `NOTIFY_GROUP_ON_CREATE` (false por defecto), incluyendo menciones para visibilidad.
- Política solo DM: el bot no publica respuestas en grupos; todos los mensajes de salida se envían por DM al autor (salvo la notificación opcional anterior).
- **Validaciones de Usuario**
- Integración completa de normalización y `ensureUserExists` en el flujo principal de mensajes
- Tests de integración para validaciones de usuarios
- **Testing**
- Suite de tests unitarios con DB en memoria para aislamiento
- **Recordatorios por DM**
- Preferencias por usuario en user_preferences (reminder_freq: off|daily|weekly; reminder_time; last_reminded_on).
- Servicio RemindersService con tick minucioso (desactivado en tests), evita duplicados por día y respeta TZ.
- Soporta daily y weekly (lunes 08:30); no envía si no hay tareas; mensaje compacto con “… y X más”.
- Comando “/t configurar daily|weekly|off” con confirmación por DM.
- Pruebas unitarias para RemindersService y configuración de recordatorios.
Estado general: listo para piloto con la junta directiva; 170 tests pasando. Riesgos operativos principales: CI/CD básico, red interna entre Evolution API y el bot, y backups/persistencia.
## ⚠️ Funcionalidades Pendientes
- **Gestión de Tareas**
- Eliminación opcional de tareas y mejoras de edición.
- **Cola de Respuestas**
- (Post-MVP) Observabilidad y métricas: contadores, latencias, tamaño de cola, endpoint /metrics.
- **Validaciones**
- Permisos de usuario (roles) y pertenencia a grupos (si se requiere política estricta).
- **Menciones y nombres**
- Refinar políticas de caché (TTL, invalidación) y ampliar compatibilidad de endpoints; en DM, WhatsApp no pinta chips de mención de terceros (limitación del cliente).
## Hecho (por áreas)
- Servidor webhook
- Endpoint /health, validación de entorno, extracción robusta de texto (conversation/extended/captions).
- Detección DM vs grupo y política “solo DM”.
- Registro/verificación de webhooks y sincronización de grupos activos con caché.
- Rate limiting por usuario (15/min por defecto; desactivado en tests; aviso con cooldown).
- Base de datos y migraciones
- Inicialización con PRAGMA FK y timestamps de alta precisión.
- Esquema: users, tasks, task_assignments, user_preferences, response_queue (con metadata).
- Migrador up-only con tabla schema_migrations; backup automático con VACUUM INTO; baseline si existe esquema previo.
- Cola de respuestas
- Persistente con workers en background, reintentos con backoff exponencial + jitter, recuperación de items processing tras reinicios, y limpieza/retención.
- 2xx=sent, 4xx=failed definitivo, 5xx/red=reintento; evita enviar al propio bot.
- Comandos
- Crear, listar (grupo/mis/sin/todos), completar, tomar, soltar; ayuda por DM.
- Fechas “hoy/mañana” con TZ configurable; formato dd/MM; vencidas con ⚠️.
- Menciones reales y tokens @…; reglas por defecto: grupo→sin responsable, DM→creador.
- Recordatorios por DM
- Preferencias por usuario (daily|weekly|off; hora con soporte en modelo/servicio), evita duplicados por día, weekly en lunes, respeta TZ, no envía si no hay tareas.
- Contactos y nombres
- Caché en memoria, actualización por webhooks, fallback a Evolution API (saltado en tests); nombres amigables en textos.
- Testing
- ~170 tests unitarios con SQLite en memoria; ResponseQueue (reintentos/cleanup), comandos (alias/fechas/listados/x/tomar/soltar), recordatorios, utilidades.
## ➡️ Próximos Pasos Prioritarios
1. Afinar recordatorios por DM (daily/weekly): hora configurable por usuario y pequeños ajustes de formato.
2. Refinar ContactsService (caché/nombres; TTL configurable; robustez ante fallos; sin red en tests).
3. Sincronización mínima de miembros (cacheada; no bloqueante).
4. Ampliar test suite (contactos, sync de miembros, ResponseQueue).
## Pendiente (priorizado)
- MVP operativo (bloqueantes/casi bloqueantes)
1) CI/CD: pipeline mínimo (build + bun test + build/push imagen + despliegue CapRover).
2) Persistencia/backup: volumen /app/data y backup diario del fichero SQLite.
3) Seguridad/red: ejecutar en red interna con Evolution API; si no, proteger el webhook (IP allowlist/reverse proxy).
4) Ensayo E2E en staging: registro de webhook, recepción de MESSAGES_UPSERT reales y envío de DMs.
- Post-MVP (mejoras)
- Observabilidad: /metrics con contadores de cola, errores y latencias.
- Orden por destinatario en ResponseQueue; idempotency_key opcional.
- Permisos/roles y pertenencia a grupos (si se requiere).
- Edición/eliminación de tareas.
- Política de caché de contactos (TTL configurable, invalidación más fina).
- Sincronización mínima de miembros (cacheada; no bloqueante).
## 🐞 Problemas conocidos
- En chats privados, WhatsApp no renderiza chips de mención para terceros; en grupos sí se resuelven al nombre local de cada receptor. El bot incluye nombres en el texto cuando los conoce y números como @dígitos para acción rápida; no hay reescritura por receptor.
## Roadmap y próximas iteraciones
- Iteración A — Operativa lista para piloto
- Entregables: pipeline CI (GitHub Actions), build de imagen, despliegue CapRover con volumen /app/data, backup diario configurado, checklist de red interna verificada.
- Iteración B — Observabilidad mínima
- Entregables: logs con contexto en puntos clave, plan de /metrics (pospuesto si no es crítico), guía de troubleshooting.
- Iteración C — Calidad de datos/UX
- Entregables: mejoras de caché de contactos, afinado de recordatorios (hora por usuario), pruebas adicionales de ResponseQueue y comandos.
## 🔧 Archivos Clave a Modificar
- `src/services/response-queue.ts`
- `src/services/command.ts`
- `src/tasks/service.ts`
- `src/server.ts`
## Checklist de readiness para piloto
- Infra
- [ ] App en CapRover con volumen /app/data.
- [ ] Variables de entorno configuradas; TZ correcta.
- [ ] Evol. API y bot en la misma red; /health OK.
- Operación
- [ ] Backups diarios de data/tasks.db y procedimiento de restauración.
- [ ] Logs accesibles; worker de cola activo.
- Funcional
- [ ] Bot añadido a los grupos; grupos activos sincronizados.
- [ ] Comandos base verificados en un grupo real (crear/ver/x/tomar/soltar/configurar).
- Comunicación/privacidad
- [ ] Aviso a la junta: cómo usar, qué se guarda, cómo desactivar recordatorios.
## Phase 4 — Desglose y estado
- Etapa 1 — Reintentos con backoff exponencial + jitter: COMPLETADA.
- Etapa 2 — Recuperación de items en `processing` (lease/expiración): COMPLETADA.
- Etapa 3 — Métricas y observabilidad: POSPUESTA (post-MVP).
- Etapa 4 — Limpieza/retención: COMPLETADA.
## Riesgos y mitigaciones
- Webhook expuesto públicamente
- Mitigación: red interna; si no es posible, IP allowlist/reverse proxy y rotación de claves.
- Pérdida de datos en SQLite
- Mitigación: volumen persistente + backups diarios + prueba de restore.
- TZ incorrecta y mensajes con fecha errónea
- Mitigación: fijar TZ en entorno, tests de humo con “hoy/mañana”.
- Fallos o latencia de Evolution API
- Mitigación: reintentos con backoff; logs de error; visibilidad en ResponseQueue.
## Commit history and status
- Latest status: All 170 unit tests passing; recordatorios por DM implementados (daily/weekly) con preferencia por usuario y comando “/t configurar”; soporte de fechas “hoy/mañana” con TZ configurable y formato dd/MM; ayuda por DM; listados ver grupo/mis/sin/todos; política solo DM; ACK al creador en una línea; notificación al grupo opcional desactivada; ContactsService evita llamadas de red en tests; nombres amigables integrados; rate limiting básico por usuario (15/min, configurable por env; desactivado en tests) implementado; formato de mensajes actualizado: cursiva en descripciones y “responsable” en lugar de “dueño”.
## Testing y cobertura
- Cubre: comandos, ResponseQueue (reintentos/cleanup), recordatorios (daily/weekly/TZ), utilidades, normalización de IDs, validaciones básicas en servidor.
- Falta: pruebas E2E reales contra Evolution API (recomendado antes del piloto).
## ▶️ Para continuar ahora
Propuesta inmediata:
- Afinar recordatorios por DM (daily/weekly): hora configurable por usuario; encabezados ⏰ y formato de mensajes ya actualizados.
- Refinar ContactsService (caché y nombres; TTL configurable; robustez ante fallos; sin red en tests).
- Sincronización mínima de miembros (cacheada; no bloqueante).
- Ampliar test suite (recordatorios, contactos, sync de miembros, ResponseQueue).
## Notas de despliegue/operación
- Migraciones up-only al arranque; backup con VACUUM INTO previo.
- Persistencia en data/; mapear a volumen y monitorizar tamaño; ejecutar VACUUM periódicamente si procede.
- Rotación de logs vía orquestador; considerar niveles/etiquetas para búsquedas.
Para que pueda proponer cambios de código, añade estos archivos a este chat:
- `src/services/command.ts`
- `src/tasks/service.ts`
- `src/services/response-queue.ts`
- `src/server.ts`
## Changelog breve
- Reintentos/backoff y recuperación de ResponseQueue: completado.
- Recordatorios por DM (daily/weekly) con preferencias: completado.
- Rate limiting por usuario: completado.
- Ayuda por DM y formato de mensajes unificado: completado.
- Limpieza/retención de historiales de cola: completado.

@ -0,0 +1,92 @@
# Guía de uso — Task WhatsApp Chatbot
Principios
- Prefijo de comandos: “/t” o “/tarea”.
- Respuestas “solo DM”: el bot no publica en grupos; siempre envía un mensaje directo al autor (salvo resumen opcional al crear si se activa).
- Fechas: puedes escribir “hoy” o “mañana” y también YYYY-MM-DD. La zona horaria se configura con la variable de entorno TZ (por defecto Europe/Madrid).
- Límite de uso: rate limit por usuario (15/min por defecto); si lo superas, verás un aviso (acotado a 1/min).
Comandos y alias
- Crear
- Aliases: n, nueva, crear, +
- Ejemplos:
- /t nueva Acta de la reunión mañana
- /t n Carteles fiesta 2025-09-12 @600123456
- /t + Preparar dossier @600111111 @600222222
- Reglas:
- En grupo: si no mencionas a nadie → “sin responsable”.
- En DM: si no mencionas a nadie → se asigna al creador.
- Ver
- Aliases: ver, mostrar, listar, ls
- Scopes:
- grupo — pendientes del grupo desde el que invocas (incluye “sin responsable”).
- mis — tus pendientes (agregado de todos tus grupos).
- sin — pendientes sin responsable (según contexto).
- todos — visión general (según permisos futuros).
- Ejemplos:
- /t ver grupo
- /t ver mis
- Completar
- Aliases: x, hecho, completar, done
- Ejemplos:
- /t x 26
- /t hecho 31
- Notas: registra quién completa; no restringido solo a asignados (por fluidez).
- Tomar
- Aliases: tomar, claim
- Ejemplo: /t tomar 26
- Idempotente: si ya eres asignado, lo indica sin error.
- Soltar
- Aliases: soltar, unassign
- Ejemplo: /t soltar 26
- Idempotente: si no estabas asignado, lo indica sin error. La tarea puede quedar “sin responsable” si no quedan asignados.
- Configurar recordatorios
- Aliases: configurar, config
- Opciones: daily | weekly | off
- Ejemplos:
- /t configurar daily
- /t configurar weekly
- /t configurar off
- Notas: resumen diario/weekly por DM; weekly los lunes a la hora configurada (por defecto 08:30 si aplica); se evita duplicar en el mismo día y no se envía si no hay tareas.
- Ayuda
- Aliases: ayuda, help, ?
- Ejemplos: /t, /t ayuda
Gramática y formato
- Menciones
- Acepta menciones reales del cliente y tokens @número en el texto.
- En DM, WhatsApp no muestra chips de mención de terceros; se incluye @número como texto para acción rápida.
- Fechas
- “hoy”, “mañana” o YYYY-MM-DD. La app usa TZ del servidor para interpretar y mostrar.
- Salida (mensajes)
- Formato compacto con emojis; descripciones en cursiva; fechas en dd/MM.
- Fechas vencidas marcadas con ⚠️.
- Ejemplos de cabeceras:
- 📝 26 _Acta de la reunión_
- 📬 Tarea 26 — 📅 12/09
Ejemplos prácticos
- Crear en grupo sin menciones (queda sin responsable):
- /t nueva Revisión presupuesto mañana
- Crear en DM (se asigna a ti):
- /t nueva Preparar documento hoy
- Crear con varios asignados:
- /t nueva Carteles @600111111 @600222222 2025-10-10
- Ver tus tareas:
- /t ver mis
- Completar:
- /t x 42
- Tomar y soltar:
- /t tomar 42
- /t soltar 42
- Configurar recordatorios:
- /t configurar weekly
Limitaciones y notas
- El bot no publica en grupos por diseño.
- La cola de respuestas no garantiza orden estricto por destinatario.
- En algunos clientes, las menciones en DM no se muestran como chips.
- Límite de 15 comandos/min por usuario (configurable).
Contacto y soporte
- Si encuentras problemas o tienes ideas, abre un issue en el repositorio o contacta con el administrador de la instancia.
Loading…
Cancel
Save