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-sincronizacion-miembro...

6.3 KiB

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 624h); en test/desarrollo puede ser menor.
  1. 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.51 día.
  • Etapa 2: 11.5 días.
  • Etapa 3: 0.5 día.
  • Etapa 4 (opcional): 0.5 día. Total: 23.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).