# Plan de Sincronización de Miembros (Grupos de WhatsApp) Este documento define el plan para implementar una sincronización robusta de miembros por grupo, usando Evolution API como fuente de verdad y una réplica local en SQLite para consultas rápidas y lógica de negocio. ## Objetivos y alcance - Mantener una lista actualizada de miembros por grupo (JID @g.us), con: - Estado: activo/inactivo (soft delete). - Rol: admin/miembro. - Trazabilidad temporal: first_seen_at, last_seen_at, last_role_change_at. - Fuente: Evolution API (full sync + eventos incrementales por webhook). - Consistencia: idempotencia, tolerancia a webhooks perdidos (reconciliación periódica). - Privacidad: almacenar solo IDs normalizados y metadatos mínimos. ## Modelo de datos (migración inicial) - Tabla groups - group_id TEXT PK (JID completo, p.ej. 123@g.us) - name TEXT - active BOOLEAN - last_verified TEXT (ISO) opcional - updated_at TEXT - Tabla group_members - group_id TEXT NOT NULL - user_id TEXT NOT NULL (teléfono normalizado; dígitos) - is_admin BOOLEAN NOT NULL DEFAULT 0 - is_active BOOLEAN NOT NULL DEFAULT 1 - first_seen_at TEXT NOT NULL - last_seen_at TEXT NOT NULL - last_role_change_at TEXT - PK compuesta (group_id, user_id) - Índices: - group_members(group_id, is_active) - group_members(user_id, is_active) - Normalización: - group_id: mantener sufijo @g.us - user_id: usar normalizeWhatsAppId existente ## Estrategia de sincronización 1) Full sync (reconciliación periódica) - Listar grupos bajo WHATSAPP_COMMUNITY_ID. - Para cada grupo activo: - Obtener miembros (paginado si aplica). - Upsert de cada miembro presente: - is_active=true, last_seen_at=now. - is_admin si el rol viene en la respuesta; actualizar last_role_change_at cuando cambie. - Marcar como inactivos los que ya no aparezcan (is_active=false, last_seen_at=now). - Intervalo configurable (e.g., cada 6–24h); en test/desarrollo puede ser menor. 2) Incremental por webhooks (near-real-time) - Suscripción a eventos de Evolution API: - Alta de participante (join/add). - Baja de participante (leave/remove). - Cambio de rol (promote/demote). - Renombrado/archivado de grupo. - Handler idempotente: - Upsert por (group_id, user_id). - Cambios de estado/rol atómicos (transacción si se tocan varias filas). - Si el payload es parcial (sin rol), no pisar is_admin. ## Consistencia y fallos - La app consulta siempre is_active=true. - Full sync corrige drift por webhooks perdidos o desordenados. - Backoff y rate limiting al hablar con Evolution API. - Logs con contexto: group_id, user_id, evento/tipo, resultado. ## Uso en la aplicación (consumidores) - “/t ver todo” y recordatorios: - Incluir “sin responsable” únicamente de grupos donde el usuario sea miembro activo. - Fallback: si aún no hay snapshot de membresías, usar heurística (grupos con tareas del usuario). - Validación (opcional por fase): - Antes de operar sobre una tarea de grupo, comprobar membresía activa. ## Privacidad y seguridad - Solo almacenar user_id normalizado y rol/fechas. - No persistir nombres salvo que ya exista caché controlada. - Webhook y full sync preferiblemente en red interna; si no, proteger con allowlist/proxy. ## Plan por etapas Etapa 1 — Esquema + servicio — COMPLETADA - Migración: crear groups y group_members + índices. - Servicio GroupSync: - syncGroups(): lista grupos + reconcilia miembros. - reconcileGroup(groupId, membersSnapshot). - Utilidades: timestamps ISO, normalización de IDs. - Tests: - Migración up-only. - Reconciliación: de [A,B,C] a [A,C,D] → B inactivo, D añadido; tiempos/roles actualizados. Etapa 2 — Integración con Evolution API — COMPLETADA - Full sync: llamadas reales a endpoints (respetando paginación y límites). - Webhooks: registro y handlers idempotentes (alta/baja/rol/rename). - Tests: - Fixtures de payloads típicos (duplicados, orden alterado). - Reintentos/backoff en errores de red/5xx. Etapa 3 — Consumidores (comandos y recordatorios) — COMPLETADA - “/t ver todo” y RemindersService usan membership real. - Fallback heurístico si no hay snapshot aún. - Validaciones opcionales de pertenencia. - Tests: - Cobertura de ambos caminos (con y sin membership). Etapa 4 — Observabilidad y mantenimiento — COMPLETADA - Métricas: - Contadores y gauges básicos expuestos en /metrics (Prometheus por defecto, JSON opcional): sync_runs_total, sync_errors_total, webhook_events_total_*, webhook_errors_total, active_groups, active_members, last_sync_*. - Estado de salud: - /health (full=1) incluye last_sync_at, snapshot_age_ms, active_groups, active_members. - Mantenimiento: - Job diario de purga de miembros inactivos con retención configurable (GROUP_MEMBERS_INACTIVE_RETENTION_DAYS; por defecto 180). ## Criterios de aceptación - Tras una full sync, group_members refleja fielmente miembros activos por grupo. - Webhooks de alta/baja actualizan el estado en <1s y son idempotentes. - “/t ver todo” y recordatorios respetan la membresía y no rompen UX preexistente. - 100% de tests existentes siguen pasando; nuevos tests cubren sync/reconciliación/handlers. ## Métricas y trazas sugeridas - Contadores: sync_runs_total, sync_errors_total, webhook_events_total, webhook_errors_total. - Gauges: active_groups, active_members. - Logs estructurados: action, group_id, user_id, outcome, diff_counts. ## Riesgos y mitigaciones - Webhooks perdidos: reconciliación periódica. - Cambios de API o límites: backoff + degradación controlada. - Coste de consultas: índices adecuados; joins simples. - Privacidad: minimización de datos, documentación en README/STATUS. ## Estimación - Etapa 1: 0.5–1 día. - Etapa 2: 1–1.5 días. - Etapa 3: 0.5 día. - Etapa 4 (opcional): 0.5 día. Total: 2–3.5 días netos. ## Dependencias y archivos a tocar (cuando implementemos) - src/db.ts (esquema base para nuevas instalaciones). - src/db/migrations/index.ts (migración up-only: tablas e índices). - src/services/webhook-manager.ts (registro y handlers de eventos). - src/services/group-sync.ts (full sync y reconciliación). - src/services/command.ts (consumo en “/t ver todo”; validaciones opcionales). - src/services/reminders.ts y src/tasks/service.ts (consultas usando membresía). - tests/unit/services/* (sync, reconciliación, webhooks, consumidores).