|  |  | # Task WhatsApp Chatbot
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | A WhatsApp chatbot for task management, designed to work with Evolution API in a secure internal network environment.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## 📌 Overview
 | 
						
						
						
							|  |  | This service provides a WhatsApp interface for task management within WhatsApp groups. It:
 | 
						
						
						
							|  |  | - Listens for `/tarea` commands in WhatsApp groups via Evolution API webhooks.
 | 
						
						
						
							|  |  | - Stores tasks, users, and groups in a SQLite database.
 | 
						
						
						
							|  |  | - Synchronizes group information periodically from the Evolution API.
 | 
						
						
						
							|  |  | - Manages user permissions and group membership (partially implemented).
 | 
						
						
						
							|  |  | - Integrates with Evolution API for WhatsApp connectivity.
 | 
						
						
						
							|  |  | - Sends direct messages to acknowledge the creator and notify each assignee; includes mentions with phone numbers for quick action.
 | 
						
						
						
							|  |  | - DM-only responses: the bot does not post messages in groups; all outputs are sent via DM to the author (except the optional creation summary below).
 | 
						
						
						
							|  |  | - Advanced listings: "/t ver" supports scopes "grupo", "mis", "sin" and "todos" with pagination ("… y X más").
 | 
						
						
						
							|  |  | - Complete tasks: "/t x <id>" (aliases: hecho, completar, done) with compact DM feedback.
 | 
						
						
						
							|  |  | - Claim/unassign tasks: "/t tomar <id>" and "/t soltar <id>" with compact DM feedback.
 | 
						
						
						
							|  |  | - Natural date parsing: supports "hoy"/"mañana" with TZ (env TZ; default Europe/Madrid).
 | 
						
						
						
							|  |  | - Unified date display: all dates are rendered as dd/MM; help available via DM with "/t" or "ayuda".
 | 
						
						
						
							|  |  | - Optional: group notification on task creation controlled by NOTIFY_GROUP_ON_CREATE (default false), including proper mentions for visibility.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## 🔐 Security Model
 | 
						
						
						
							|  |  | - **Internal Networking**: The webhook should ideally only accept connections from Evolution API via internal Docker networking (configuration dependent).
 | 
						
						
						
							|  |  | - **Environment Variables**: Sensitive configuration (API keys, URLs) is managed through environment variables.
 | 
						
						
						
							|  |  | - **Group Restrictions**: Designed to operate within pre-approved WhatsApp groups (validation logic pending integration).
 | 
						
						
						
							|  |  | - **Input Validation**: Basic validation exists for webhook structure; needs enhancement for command arguments and user/group IDs.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## 🧱 Architecture
 | 
						
						
						
							|  |  | ```mermaid
 | 
						
						
						
							|  |  | graph TD
 | 
						
						
						
							|  |  |     A[Webhook Received] --> B{Valid Payload?}
 | 
						
						
						
							|  |  |     B -->|No| C[Ignore]
 | 
						
						
						
							|  |  |     B -->|Yes| D{Normalize IDs & Check Group Active?}
 | 
						
						
						
							|  |  |     D -->|No| C[Ignore/Log]
 | 
						
						
						
							|  |  |     D -->|Yes| E[Ensure User Exists in DB]
 | 
						
						
						
							|  |  |     E --> G{/tarea Command?}
 | 
						
						
						
							|  |  |     G -->|No| C
 | 
						
						
						
							|  |  |     G -->|Yes| J[Process Command Logic]
 | 
						
						
						
							|  |  |     J -- Success/Error --> K[Queue Response(s)]
 | 
						
						
						
							|  |  |     K --> L[Process Queue & Send Response via API]
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  |     subgraph Database Interaction
 | 
						
						
						
							|  |  |         E --> DB[(SQLite DB)]
 | 
						
						
						
							|  |  |         J --> DB
 | 
						
						
						
							|  |  |     end
 | 
						
						
						
							|  |  |     subgraph Evolution API
 | 
						
						
						
							|  |  |         L --> EA((Evolution API))
 | 
						
						
						
							|  |  |         EA -- Webhook --> A
 | 
						
						
						
							|  |  |     end
 | 
						
						
						
							|  |  | ```
 | 
						
						
						
							|  |  | *(Diagram updated for planned flow)*
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## Decisiones de diseño de la cola de respuestas (estado actual)
 | 
						
						
						
							|  |  | 1) Persistencia: 100% persistente (tabla única).
 | 
						
						
						
							|  |  | 2) Worker: continuo en background.
 | 
						
						
						
							|  |  | 3) Locking: status=processing (sin lease).
 | 
						
						
						
							|  |  | 4) Orden: sin orden estricto por chat.
 | 
						
						
						
							|  |  | 5) Reintentos: activados con backoff exponencial + jitter (configurables).
 | 
						
						
						
							|  |  | 6) Errores: 4xx = fallo definitivo; 5xx/red = reintento hasta RQ_MAX_ATTEMPTS con `next_attempt_at`.
 | 
						
						
						
							|  |  | 7) Idempotencia: no.
 | 
						
						
						
							|  |  | 8) Esquema DB: tabla única response_queue.
 | 
						
						
						
							|  |  | 9) Transporte: envío desde ResponseQueue (fetch directo a Evolution API).
 | 
						
						
						
							|  |  | 10) Concurrencia: N workers globales.
 | 
						
						
						
							|  |  | 11) Integración: encolar y worker continuo (arranca con el servidor).
 | 
						
						
						
							|  |  | 12) Configuración: defaults fijos (sin nuevas env vars por ahora).
 | 
						
						
						
							|  |  | 13) Limpieza: retención periódica de historiales aplicada (sent y failed antiguos).
 | 
						
						
						
							|  |  | 14) Seguridad: no enviar al número del bot (CHATBOT_PHONE_NUMBER).
 | 
						
						
						
							|  |  | 15) Pruebas: unitarias de cola con mocks de fetch.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | Actualización Phase 4 — Etapa 1 (Completada):
 | 
						
						
						
							|  |  | - Reintentos activados con backoff exponencial + jitter.
 | 
						
						
						
							|  |  | - Nuevos campos: `next_attempt_at`, `last_status_code`.
 | 
						
						
						
							|  |  | - Selección de pendientes filtrando por `(status='queued' AND next_attempt_at <= now)`.
 | 
						
						
						
							|  |  | - Config por entorno: `RQ_MAX_ATTEMPTS`, `RQ_BASE_BACKOFF_MS`, `RQ_MAX_BACKOFF_MS`.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## Arquitectura de la cola persistente (MVP)
 | 
						
						
						
							|  |  | - Estados: queued | processing | sent | failed.
 | 
						
						
						
							|  |  | - Campos actuales por mensaje: id (PK), recipient, message, status, attempts (0), last_error (nullable), metadata (nullable), created_at, updated_at.
 | 
						
						
						
							|  |  | - Índices recomendados: (status, created_at) para seleccionar pendientes rápidamente.
 | 
						
						
						
							|  |  | - Sin orden estricto por chat; el envío puede intercalarse entre destinatarios.
 | 
						
						
						
							|  |  | - Concurrencia: N workers globales operando en bucle, cada uno toma mensajes en estado queued y los marca processing.
 | 
						
						
						
							|  |  | Estado: la tabla response_queue ya está creada e incluida en los tests de DB.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## Flujo del worker continuo (MVP)
 | 
						
						
						
							|  |  | - Se inicia al arrancar el servidor (desactivado en tests).
 | 
						
						
						
							|  |  | - Ciclo: seleccionar hasta un pequeño batch de mensajes queued, marcar processing, enviar a Evolution API, marcar sent o failed según respuesta.
 | 
						
						
						
							|  |  | - Sin reintentos; logs mínimos y no sensibles.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## Limitaciones actuales
 | 
						
						
						
							|  |  | - Sin orden garantizado por chat (pendiente serialización por destinatario).
 | 
						
						
						
							|  |  | - Sin idempotencia (pendiente `idempotency_key` e índice único).
 | 
						
						
						
							|  |  | - Métricas/observabilidad básicas pendientes (endpoint /metrics).
 | 
						
						
						
							|  |  | - Sin garantía de orden cross-chat; fair scheduling pendiente.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## Plan incremental posterior
 | 
						
						
						
							|  |  | - Añadir reintentos con backoff exponencial y jitter. (Completado)
 | 
						
						
						
							|  |  | - Garantizar orden por chat (serialización por recipient).
 | 
						
						
						
							|  |  | - Introducir lease (lease_until) para tolerancia a fallos y recuperación.
 | 
						
						
						
							|  |  | - Limpieza/retención y métricas/observabilidad.
 | 
						
						
						
							|  |  | - Opcional: idempotencia e índices adicionales.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## ✅ Current Status (as of latest commit)
 | 
						
						
						
							|  |  | ### Implemented
 | 
						
						
						
							|  |  | - Webhook server setup (`src/server.ts`) receiving Evolution API events.
 | 
						
						
						
							|  |  | - Corrección: extracción robusta de remitente en DMs vs grupos para evitar 'Invalid sender ID'.
 | 
						
						
						
							|  |  | - Sistema de migraciones up-only para SQLite (`src/db/migrator.ts`, `src/db/migrations/`), ejecutado al arranque; backup automático con VACUUM INTO y baseline cuando existe esquema previo.
 | 
						
						
						
							|  |  | - Group synchronization service (`src/services/group-sync.ts`) to fetch/store/cache groups. Includes active group caching and `isGroupActive` checks in server.
 | 
						
						
						
							|  |  | - Webhook registration and verification with Evolution API (`src/services/webhook-manager.ts`).
 | 
						
						
						
							|  |  | - WhatsApp ID normalization utility (`src/utils/whatsapp.ts`).
 | 
						
						
						
							|  |  | - User creation/update function (`src/db.ts::ensureUserExists`) integrated into the main flow.
 | 
						
						
						
							|  |  | - Command handling for `/tarea nueva` end-to-end (`src/services/command.ts`):
 | 
						
						
						
							|  |  |   - Parses description and selects the last future date (YYYY-MM-DD) as due date.
 | 
						
						
						
							|  |  |   - Extracts assignees from explicit mentions and plain-text @tokens; defaults to creator only when none found.
 | 
						
						
						
							|  |  |   - Cleans description to remove @mentions tokens.
 | 
						
						
						
							|  |  |   - Persists task and assignments atomically via `TaskService`.
 | 
						
						
						
							|  |  |   - Builds response with assignment list and includes Evolution API “mentioned” JIDs via `ResponseQueue`.
 | 
						
						
						
							|  |  | - Command handling for listings, completion and assignment (tomar/soltar):
 | 
						
						
						
							|  |  |   - `/t ver` with scopes `grupo`, `mis`, `sin` and `todos` with top-N and “… y X más”; DM-only policy enforced.
 | 
						
						
						
							|  |  |   - `/t x <id>` to complete tasks (aliases: `hecho`, `completar`, `done`) with compact feedback.
 | 
						
						
						
							|  |  | - Task persistence service (`src/tasks/service.ts`) with `created_by` and assignment inserts in a transaction; supports DB injection for tests.
 | 
						
						
						
							|  |  | - Response queue persistente con workers en background y envío vía Evolution API (`src/services/response-queue.ts`), persistiendo metadata `{ mentioned: [...] }` y enviándola como `mentioned` en el payload, con reintentos (backoff exponencial + jitter), recuperación de `processing` y limpieza/retención.
 | 
						
						
						
							|  |  | - Contacts service and friendly names: `ContactsService` resolves display names via webhooks (CONTACTS_UPDATE/CHATS_UPDATE) and Evolution API fallback; used to render names in outgoing texts (falls back to numbers). Skips network calls under NODE_ENV=test for fast and isolated unit tests.
 | 
						
						
						
							|  |  | - Notification UX: Always send DM acknowledgment to the creator in a single line (format: ✅ Tarea <id> creada: "description"), DM to each assignee (excluding the creator); optional group notification controlled by `NOTIFY_GROUP_ON_CREATE` (default false) with proper mentions.
 | 
						
						
						
							|  |  | - Natural date tokens support (“hoy”/“mañana”) with TZ configurable (env TZ; default Europe/Madrid) in task creation.
 | 
						
						
						
							|  |  | - Unified dd/MM date formatting across outgoing texts.
 | 
						
						
						
							|  |  | - Help by DM for "/t" and "/t ayuda" with a concise guide and examples.
 | 
						
						
						
							|  |  | - Environment variable validation (`src/server.ts`, `src/services/webhook-manager.ts`).
 | 
						
						
						
							|  |  | - Health check endpoint (`/health`).
 | 
						
						
						
							|  |  | - **Database isolation in unit tests**: Using in-memory instances to avoid conflicts.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ### Incomplete / Missing Core Functionality
 | 
						
						
						
							|  |  | - ResponseQueue reliability: reintentos con backoff, recuperación de `processing`, métricas y limpieza/retención.
 | 
						
						
						
							|  |  | - ContactsService improvements (optional): refine caching policy and endpoints; basic friendly-name resolution is already implemented and used in outgoing texts.
 | 
						
						
						
							|  |  | - More robust error handling and observability around API/DB operations.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ### Known Issues
 | 
						
						
						
							|  |  | - Mentions UX: In group chats, mentions are highlighted and each client resolves the chip to their local contact name; we include friendly names in text when available. In direct messages, WhatsApp does not render mention chips for third parties, so we include the number as @digits for quick action; no per-recipient name rewriting occurs.
 | 
						
						
						
							|  |  | - Test suite: all unit tests passing.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## 🛠️ Setup
 | 
						
						
						
							|  |  | ### Environment Variables
 | 
						
						
						
							|  |  | *(Ensure these are set correctly)*
 | 
						
						
						
							|  |  | ```env
 | 
						
						
						
							|  |  | # Evolution API Connection
 | 
						
						
						
							|  |  | EVOLUTION_API_URL=http://evolution-api:3000 # Or your API URL
 | 
						
						
						
							|  |  | EVOLUTION_API_KEY=your-api-key
 | 
						
						
						
							|  |  | EVOLUTION_API_INSTANCE=main # Your instance name
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | # WhatsApp Specific
 | 
						
						
						
							|  |  | WHATSAPP_COMMUNITY_ID=your-community-id # ID of the main community to sync groups from
 | 
						
						
						
							|  |  | CHATBOT_PHONE_NUMBER=1234567890 # Bot's normalized phone number (e.g., for assigning tasks)
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | # Webhook Configuration
 | 
						
						
						
							|  |  | WEBHOOK_URL=http://your-service-internal-url:3007 # URL Evolution API calls *back* to this service
 | 
						
						
						
							|  |  | PORT=3007 # Port this service listens on
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | # Runtime Environment
 | 
						
						
						
							|  |  | NODE_ENV=production # Or development
 | 
						
						
						
							|  |  | TZ=Europe/Madrid # Default timezone used for "hoy/mañana" parsing and date displays
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | # Optional
 | 
						
						
						
							|  |  | # GROUP_SYNC_INTERVAL_MS=3600000 # Sync interval in ms (default: 24h)
 | 
						
						
						
							|  |  | # NOTIFY_GROUP_ON_CREATE=false # If 'true', also post a brief summary with mentions to the group
 | 
						
						
						
							|  |  | ```
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ### Development Setup
 | 
						
						
						
							|  |  | ```bash
 | 
						
						
						
							|  |  | # Install dependencies
 | 
						
						
						
							|  |  | bun install
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | # Copy .env.example to .env and fill in values
 | 
						
						
						
							|  |  | cp .env.example .env
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | # Start development server (watches for changes)
 | 
						
						
						
							|  |  | bun run dev
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | # Run tests
 | 
						
						
						
							|  |  | bun test
 | 
						
						
						
							|  |  | ```
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## 📅 Roadmap & Priorities (Updated Plan)
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ### MVP — Próximos pasos (prioridad actual)
 | 
						
						
						
							|  |  | 1) Rate limiting básico: bucket en memoria por remitente (p. ej., 10/min), respuesta amable al exceder, desactivado en NODE_ENV=test.
 | 
						
						
						
							|  |  | 2) Recordatorios diarios por DM: preferencia por usuario (daily|off, por defecto off), hora fija local (p. ej., 08:30 TZ), un DM con resumen compacto de “tus tareas”.
 | 
						
						
						
							|  |  | 3) Refinar ContactsService: mejorar heurística de nombre, invalidación temprana en CHATS_UPDATE/CONTACTS_UPDATE, TTL configurable, robustez ante fallos, sin llamadas de red en tests.
 | 
						
						
						
							|  |  | 4) Sincronización mínima de miembros: obtener y cachear miembros de grupos activos con TTL, uso no bloqueante; base para futuras validaciones/UX.
 | 
						
						
						
							|  |  | 5) Ampliar test suite: cubrir recordatorios, rate limiting, actualización de nombres, sync de miembros y casos extremos de ResponseQueue.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ### Phase 1: User & Group Foundation (Highest Priority - In Progress)
 | 
						
						
						
							|  |  | - [x] **Create WhatsApp ID Normalization Utility:** (`src/utils/whatsapp.ts`) Handle different ID formats.
 | 
						
						
						
							|  |  | - [x] **Implement `ensureUserExists`:** (`src/db.ts`) Add users to DB on first interaction.
 | 
						
						
						
							|  |  | - [x] **Implement `isGroupActive` Check:** (`src/services/group-sync.ts`, `src/server.ts`) Cache exists in `group-sync.ts`. **Needs integration** into `src/server.ts`.
 | 
						
						
						
							|  |  | - [x] **Integrate Validation in Server:** (`src/server.ts`) Use normalization, `ensureUserExists`, and active group check before processing commands.
 | 
						
						
						
							|  |  | - [x] **Implement DB isolation in tests:** (`tests/unit/services/group-sync.test.ts`) Use in-memory instances to avoid conflicts.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ### Phase 2: Refinar `/tarea nueva` (Alta prioridad)
 | 
						
						
						
							|  |  | - [x] Completar `TaskService.createTask` con `created_by` y asignaciones (incluyendo `ensureUserExists` para asignados) y transacción atómica.
 | 
						
						
						
							|  |  | - [x] Mejorar `CommandService` para parsear menciones y devolver el id de la tarea creada y resumen de asignados.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ### Phase 3: Comandos adicionales y refinamientos (Alta prioridad)
 | 
						
						
						
							|  |  | - [x] Implementar `/tarea mostrar [group|mine]` para listar pendientes.
 | 
						
						
						
							|  |  | - [x] Implementar `/tarea completar <task_id>` con validaciones básicas.
 | 
						
						
						
							|  |  | - [x] Soportar mensajes de texto extendido y captions de media (además de conversation).
 | 
						
						
						
							|  |  | - [x] Implementar tomar/soltar (claim/unassign) con feedback por DM.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ### Phase 4: Fiabilidad de la cola (Media; observabilidad pospuesta post-MVP)
 | 
						
						
						
							|  |  | - [x] Añadir reintentos con backoff exponencial y jitter.
 | 
						
						
						
							|  |  | - [x] Recuperar ítems en estado `processing` tras reinicios (lease o expiración y requeue).
 | 
						
						
						
							|  |  | - [x] Limpieza/retención de historiales.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ### Phase 4 — Desglose y estado
 | 
						
						
						
							|  |  | - Etapa 1 — Reintentos con backoff exponencial + jitter (Completada)
 | 
						
						
						
							|  |  |   - Parámetros: RQ_MAX_ATTEMPTS (6), RQ_BASE_BACKOFF_MS (5000), RQ_MAX_BACKOFF_MS (3600000).
 | 
						
						
						
							|  |  |   - Lógica: 2xx → sent; 4xx → failed definitivo; 5xx/red → reintento con `next_attempt_at` hasta MAX_ATTEMPTS.
 | 
						
						
						
							|  |  | - Etapa 2 — Recuperación de items en `processing` mediante lease/expiración (Completada)
 | 
						
						
						
							|  |  | - Etapa 3 — Métricas y observabilidad (Pospuesta post-MVP)
 | 
						
						
						
							|  |  | - Etapa 4 — Limpieza/retención (Completada)
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ### Phase 5: Advanced Features (Low Priority)
 | 
						
						
						
							|  |  | - [ ] Add task reminders system.
 | 
						
						
						
							|  |  | - [ ] Implement user permissions system.
 | 
						
						
						
							|  |  | - [ ] Add rate limiting.
 | 
						
						
						
							|  |  | - [ ] Create task history tracking.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ### Etapas siguientes (priorización propuesta)
 | 
						
						
						
							|  |  | 1) Phase 4 — Etapa 4: Limpieza y retención
 | 
						
						
						
							|  |  | - Objetivo: evitar crecimiento indefinido y mantener la BD sana.
 | 
						
						
						
							|  |  | - Implica: retención/archivado de response_queue, posible VACUUM, config RQ_RETENTION_DAYS y job periódico.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | 2) Fiabilidad avanzada de ResponseQueue
 | 
						
						
						
							|  |  | - Objetivo: mejorar entrega y evitar duplicados/ruido.
 | 
						
						
						
							|  |  | - Implica: orden por destinatario, idempotency_key con índice único, límites de inflight/backpressure.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | 3) UX Iteración A (MVP centrado en valor)
 | 
						
						
						
							|  |  | - Objetivo: fluidez de uso y silencio en grupos.
 | 
						
						
						
							|  |  | - Implica: alias y sinónimos, “solo DM”, soporte “hoy/mañana”, comandos tomar/soltar, ayuda breve.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | 4) UX Iteración B (listas y completar)
 | 
						
						
						
							|  |  | - Objetivo: visibilidad y cierre rápido.
 | 
						
						
						
							|  |  | - Implica: “ver grupo” y “ver mis” con tope y “y X más…”, completar (x/hecho/done) robusto, formatos compactos.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | 5) Recordatorios (Phase 5)
 | 
						
						
						
							|  |  | - Objetivo: nudge suave por DM.
 | 
						
						
						
							|  |  | - Implica: tabla user_preferences, comando “configurar”, job diario de resumen.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | 6) Permisos y pertenencia a grupos
 | 
						
						
						
							|  |  | - Objetivo: control de quién puede qué, y pertenencia válida.
 | 
						
						
						
							|  |  | - Implica: roles y/o verificación de pertenencia; posibles migraciones y sincronización de miembros.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | 7) Historial de tareas (auditoría ligera)
 | 
						
						
						
							|  |  | - Objetivo: trazabilidad de cambios.
 | 
						
						
						
							|  |  | - Implica: tabla task_events; eventos en crear/asignar/tomar/soltar/completar; consulta “historial”.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | 8) Rate limiting (operación segura)
 | 
						
						
						
							|  |  | - Objetivo: proteger ante abuso o loops.
 | 
						
						
						
							|  |  | - Implica: token bucket por usuario/grupo; configuración de límites.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | 9) Sincronización de miembros (opcional)
 | 
						
						
						
							|  |  | - Objetivo: conocer miembros activos por grupo para features avanzadas.
 | 
						
						
						
							|  |  | - Implica: endpoints Evolution API para miembros; cache/migraciones.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | 10) Métricas y observabilidad (deferido del MVP)
 | 
						
						
						
							|  |  | - Objetivo: visibilidad con bajo coste.
 | 
						
						
						
							|  |  | - Implica: counters/gauges/histograms y endpoint /metrics; logging estructurado. Se pospone al final de esta lista.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## 🔑 Key Considerations & Caveats
 | 
						
						
						
							|  |  | *   **WhatsApp ID Normalization:** Crucial for consistently identifying users and groups. Needs careful implementation to handle edge cases. (Utility function exists).
 | 
						
						
						
							|  |  | *   **Response Latency:** Sending responses requires an API call back to Evolution. Ensure the `ResponseQueue` processing is efficient.
 | 
						
						
						
							|  |  | *   **Cola de respuestas:** Persistente en DB; pendiente añadir reintentos/backoff y limpieza/retención.
 | 
						
						
						
							|  |  | *   **Group Sync:** The current full sync might be slow or rate-limited with many groups. Delta updates are recommended long-term.
 | 
						
						
						
							|  |  | *   **Error Handling:** Failures in command processing or response sending should be logged clearly and potentially reported back to the user. Database operations should use transactions for atomicity (especially task+assignment creation).
 | 
						
						
						
							|  |  | *   **State Management:** The current design is stateless. Complex interactions might require state persistence later.
 | 
						
						
						
							|  |  | *   **Security:** Ensure group/user validation logic is robust once integrated.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## 🧪 Testing
 | 
						
						
						
							|  |  | ### Running Tests
 | 
						
						
						
							|  |  | ```bash
 | 
						
						
						
							|  |  | bun test
 | 
						
						
						
							|  |  | ```
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ### Test Coverage
 | 
						
						
						
							|  |  | - Database initialization and basic operations (`db.test.ts`).
 | 
						
						
						
							|  |  | - Webhook validation (basic) (`webhook-manager.test.ts`).
 | 
						
						
						
							|  |  | - Command parsing (basic structure) (`command.test.ts`).
 | 
						
						
						
							|  |  | - Environment checks (`server.test.ts`).
 | 
						
						
						
							|  |  | - Basic error handling (`server.test.ts`).
 | 
						
						
						
							|  |  | - WhatsApp ID normalization (`whatsapp.test.ts`).
 | 
						
						
						
							|  |  | - Group sync operations (`group-sync.test.ts`).
 | 
						
						
						
							|  |  | - **Needed:** Tests for `ensureUserExists` integration, `isGroupActive` integration, `CommandService` logic, `ResponseQueue` processing (mocking API), `TaskService` operations.
 | 
						
						
						
							|  |  | - All unit tests passing. Added unit tests for CommandService (date parsing "hoy/mañana", DM help, dd/MM formatting, default assignment rules).
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## 🧑💻 Contributing
 | 
						
						
						
							|  |  | 1. Fork the repository
 | 
						
						
						
							|  |  | 2. Create a feature branch (`git checkout -b feature/implement-user-validation`)
 | 
						
						
						
							|  |  | 3. Add/update tests for new functionality
 | 
						
						
						
							|  |  | 4. Ensure tests pass (`bun test`)
 | 
						
						
						
							|  |  | 5. Submit a pull request
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## 📚 Documentation
 | 
						
						
						
							|  |  | For detailed API documentation and architecture decisions, see the [docs/](docs/) directory (if created).
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ---
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ## 📐 Diseño UX acordado (MVP y siguientes iteraciones)
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | Este apartado documenta las decisiones de UX aprobadas para el MVP y su evolución inmediata. Objetivo: mínima fricción, cero ruido en grupos y mensajes compactos.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ### Principios
 | 
						
						
						
							|  |  | - Silencio en grupos: el bot NO publica mensajes en grupos. Cuando alguien usa un comando en un grupo, el bot responde solo por DM al autor, sin dejar mensaje en el grupo.
 | 
						
						
						
							|  |  | - Homogeneidad: mismos comandos y comportamiento tanto en la comunidad “Casa” como en la del AMPA.
 | 
						
						
						
							|  |  | - Mensajes compactos: máximo 2–3 líneas, usando emojis y formato WhatsApp (negritas, monoespacio) para legibilidad.
 | 
						
						
						
							|  |  | - Aprendizaje progresivo: alias cortos y ayuda accesible por DM.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ### Comando base y alias
 | 
						
						
						
							|  |  | - Prefijo admitido: “/t” y “/tarea”.
 | 
						
						
						
							|  |  | - Subcomandos y sinónimos (aceptar cualquiera, mapear a una acción canónica):
 | 
						
						
						
							|  |  |   - Crear: n, nueva, crear, +
 | 
						
						
						
							|  |  |   - Ver: ver, mostrar, listar, ls
 | 
						
						
						
							|  |  |   - Completar: x, hecho, completar, done
 | 
						
						
						
							|  |  |   - Tomar: tomar, claim
 | 
						
						
						
							|  |  |   - Soltar: soltar, unassign
 | 
						
						
						
							|  |  |   - Ayuda: ayuda, help, ?
 | 
						
						
						
							|  |  |   - Configurar: configurar, config
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ### Gramática de “crear tarea”
 | 
						
						
						
							|  |  | - Texto libre: descripción.
 | 
						
						
						
							|  |  | - Fecha: soportar tokens “hoy” y “mañana” (MVP). Futuro: +2d, +1w, lun/mar/…
 | 
						
						
						
							|  |  | - Menciones: “@…” y menciones reales del cliente.
 | 
						
						
						
							|  |  | - Asignación por defecto:
 | 
						
						
						
							|  |  |   - En grupos: si no hay menciones → tarea queda “sin dueño”.
 | 
						
						
						
							|  |  |   - En DM: si no hay menciones → asignada al creador.
 | 
						
						
						
							|  |  | - Comandos de gestión de asignación:
 | 
						
						
						
							|  |  |   - /t tomar <id> → el usuario se asigna la tarea.
 | 
						
						
						
							|  |  |   - /t soltar <id> → elimina su asignación, devolviendo la tarea a “sin dueño” si no quedan asignados.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ### Listados
 | 
						
						
						
							|  |  | - /t ver grupo → devuelve por DM las pendientes del grupo desde el que se invoca (incluye sección “sin dueño”).
 | 
						
						
						
							|  |  | - /t ver mis → devuelve por DM las pendientes del usuario agregadas de todos sus grupos.
 | 
						
						
						
							|  |  | - Listas extensas: mostrar top N (p. ej., 10) y resumen “y X más…”.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ### Completar
 | 
						
						
						
							|  |  | - /t x <id> (alias: /t hecho <id>, /t completar <id>)
 | 
						
						
						
							|  |  | - Registro de quién completó. Por ahora no se restringe a asignados (permite fluidez); política configurable en el futuro.
 | 
						
						
						
							|  |  | - Confirmación solo por DM.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ### Ayuda y onboarding
 | 
						
						
						
							|  |  | - “/t” sin parámetros o “ayuda” → siempre por DM, con guía corta y 2–3 ejemplos.
 | 
						
						
						
							|  |  | - En grupos: no se escribe nada en el grupo; únicamente el DM al autor.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ### Mensajes: plantillas compactas
 | 
						
						
						
							|  |  | - Confirmación al crear (DM al creador):
 | 
						
						
						
							|  |  |   - ✅ 26 “*Acta de la reunión*”
 | 
						
						
						
							|  |  |   - 📅 12/09
 | 
						
						
						
							|  |  |   - 👥 sin dueño (Junta AMPA) — o — 👤 @Juan
 | 
						
						
						
							|  |  | - DM a asignados:
 | 
						
						
						
							|  |  |   - 🔔 Tarea 26 — 📅 12/09
 | 
						
						
						
							|  |  |   - “*Acta de la reunión*”
 | 
						
						
						
							|  |  |   - Grupo: Junta AMPA
 | 
						
						
						
							|  |  |   - Completar: /t x 26
 | 
						
						
						
							|  |  | - Listado (enviado por DM):
 | 
						
						
						
							|  |  |   - Junta AMPA
 | 
						
						
						
							|  |  |     - 26) “*Acta…*” — 📅 12/09 — 👤 @Juan
 | 
						
						
						
							|  |  |     - 27) “*Carteles fiesta*” — 📅 10/09 — 👥 sin dueño
 | 
						
						
						
							|  |  |     - … y 3 más
 | 
						
						
						
							|  |  | - Completar (feedback por DM):
 | 
						
						
						
							|  |  |   - ✔️ 26 completada — “*Acta…*”
 | 
						
						
						
							|  |  |   - Gracias, Juan.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ### Preferencias (MVP)
 | 
						
						
						
							|  |  | - Única preferencia: frecuencia de recordatorios por DM: daily | off.
 | 
						
						
						
							|  |  | - MVP sin web: el usuario escribe “configurar” por DM y el bot le ofrece elegir “diario” u “off”.
 | 
						
						
						
							|  |  | - Por defecto: off (evitar spam). Futuro: hora y zona horaria configurables; magic link a web de configuración.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ### Recordatorios
 | 
						
						
						
							|  |  | - Resumen diario por DM (si el usuario eligió “diario”):
 | 
						
						
						
							|  |  |   - Buenos días, Ana — hoy tienes 3 tareas:
 | 
						
						
						
							|  |  |     - 26) “*Acta…*” — 12/09 — Junta AMPA
 | 
						
						
						
							|  |  |     - 31) “*Pagar comedor*” — hoy — Casa
 | 
						
						
						
							|  |  |     - 33) “*…*” — 15/09 — Casa
 | 
						
						
						
							|  |  |   - Completar: /t x <id>
 | 
						
						
						
							|  |  | - Un solo DM con secciones por comunidad para evitar múltiples mensajes.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ### No objetivos del MVP
 | 
						
						
						
							|  |  | - No asignar por defecto a “todo el grupo” (evita DMs masivos y responsabilidad difusa).
 | 
						
						
						
							|  |  | - No canal “Tareas” compartido por defecto (riesgo de ruido). Se considerará en el futuro solo si hay demanda y opt‑in.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ### Plan de implementación (iteraciones)
 | 
						
						
						
							|  |  | - Iteración A — UX base y silencios
 | 
						
						
						
							|  |  |   - Alias de comandos y sinónimos en CommandService.
 | 
						
						
						
							|  |  |   - Respuestas de todos los comandos únicamente por DM (incluido cuando se invocan en grupos).
 | 
						
						
						
							|  |  |   - Mensajes compactos con plantillas.
 | 
						
						
						
							|  |  |   - Soporte de “hoy/mañana”.
 | 
						
						
						
							|  |  |   - Default sin dueño en grupos; asignar al creador en DMs.
 | 
						
						
						
							|  |  |   - Nuevos comandos: tomar y soltar.
 | 
						
						
						
							|  |  |   - Ayuda por DM.
 | 
						
						
						
							|  |  | - Iteración B — Listados y completar
 | 
						
						
						
							|  |  |   - /t ver grupo, /t ver mis.
 | 
						
						
						
							|  |  |   - /t x <id> con registro de quién completa.
 | 
						
						
						
							|  |  |   - Tests para alias, hoy/mañana, ver y x.
 | 
						
						
						
							|  |  | - Iteración C — Recordatorios
 | 
						
						
						
							|  |  |   - Preferencia reminder_freq (daily|off) por usuario via “configurar” por DM.
 | 
						
						
						
							|  |  |   - Job diario que envía el resumen (solo “tus tareas” en MVP).
 | 
						
						
						
							|  |  | - Iteración D — (Opcional) Miembros de grupo
 | 
						
						
						
							|  |  |   - Sincronizar miembros si se necesita incluir “sin dueño” por grupo en recordatorios.
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ### Cambios técnicos asociados (resumen)
 | 
						
						
						
							|  |  | - src/services/command.ts
 | 
						
						
						
							|  |  |   - Mapeo de sinónimos a acciones canónicas.
 | 
						
						
						
							|  |  |   - Parser de “hoy/mañana”.
 | 
						
						
						
							|  |  |   - Subcomandos: ver grupo|mis, x, tomar, soltar.
 | 
						
						
						
							|  |  |   - Render de mensajes compactos.
 | 
						
						
						
							|  |  | - src/server.ts
 | 
						
						
						
							|  |  |   - Detección de contexto grupo vs DM; nunca responder en grupo (solo DM al autor).
 | 
						
						
						
							|  |  | - src/tasks/service.ts
 | 
						
						
						
							|  |  |   - Permitir tareas sin asignaciones.
 | 
						
						
						
							|  |  |   - Métodos: claimTask(user_id), unassignTask(user_id), completeTask(id, completed_by).
 | 
						
						
						
							|  |  | - src/services/response-queue.ts
 | 
						
						
						
							|  |  |   - Envío de DMs para ayuda, confirmaciones, listados y recordatorios.
 | 
						
						
						
							|  |  | - (Futuro) Preferencias
 | 
						
						
						
							|  |  |   - Tabla user_preferences(user_id PK, reminder_freq TEXT, updated_at).
 | 
						
						
						
							|  |  |   - “configurar” por DM en MVP; más adelante, web con magic link (user_tokens).
 | 
						
						
						
							|  |  | 
 | 
						
						
						
							|  |  | ### Testing sugerido
 | 
						
						
						
							|  |  | - Alias de comandos y “/t” sin parámetros → DM de ayuda.
 | 
						
						
						
							|  |  | - Crear en grupo sin menciones → sin dueño; no hay mensaje en el grupo; DM al autor.
 | 
						
						
						
							|  |  | - Crear en DM sin menciones → asignada al creador.
 | 
						
						
						
							|  |  | - “hoy/mañana” en fechas.
 | 
						
						
						
							|  |  | - ver grupo y ver mis → DM con paginación/resumen.
 | 
						
						
						
							|  |  | - completar, tomar y soltar → reglas y feedback por DM.
 |