Files
scoreodonto.com/backend/newwhats/INTEGRACAO-MOTOR.md
T
2026-06-28 18:57:30 +02:00

4.2 KiB

Integração NewWhats (satélite) — scoreodonto.com ↔ Motor

Único deste projeto (scoreodonto.com). Clonado e adaptado ao domínio odonto a partir do satélite do mercado.clube67.com. Backend ESM — sem o host de plugins do mercado; é um módulo registrado no server.js. v1.0.0.

⚠️ Regra de registro bidirecional (obrigatória)

  • Toda mudança que toque o contrato (rotas, payloads, auth, webhook) deve ser registrada no motor e na doc central documentos-unicos/projetos/newwhats.clube67.com/integracao-satelites.md.
  • Toda mudança no motor que afete o contrato deve ser refletida aqui.
  • O satélite é um braço inteligente do motor — consome/alimenta, não duplica.

Diferenças vs o satélite do mercado

  • ESM (não CommonJS) e sem PluginManager — registrado via registerNewwhats(app, pool) no server.js.
  • Config por ENV (não tabela plugin_configs): NEWWHATS_URL, NEWWHATS_INTEGRATION_KEY, NEWWHATS_WEBHOOK_SECRET, NEWWHATS_CLINICA_ID.
  • Negócio adaptado ao odonto: /nw/* e sync-knowledge usam clínica/especialidades/dentistas/procedimentos/planos (multi-tenant por clinica_id), no lugar de clubes/sorteio/vagas.
  • Removidos (não úteis aqui): media-transcribe (o motor já transcreve — ver Fase 5), smart-router, personas, follow-up-detector, context-builder (heurísticas específicas do mercado). Reavaliar se necessário.

Arquivos

Arquivo Papel
config.js lê a config da integração das ENV
auth.js nwAuth — valida x-nw-key/Bearer nas rotas /nw/*
routes.js /nw/* odonto: /ping, /clinica, /especialidades, /dentistas, /procedimentos, /planos
sync-knowledge.js buildKnowledgeText(pool, clinicaId) + syncKnowledge(pool) → motor /api/secretaria/*
webhook-receiver.js POST /api/webhook/newwhats (HMAC) — message.new, session.status (enxuto)
proxy.js /api/nw/v1/* → motor /api/ext/v1/* (injeta x-nw-key)
index.js registerNewwhats(app, pool) — registra tudo
manifest.json metadados + config_env

Contrato (resumo)

  • Satélite → Motor: proxy /api/nw/v1/* → ext-api /api/ext/v1/* (Bearer/x-nw-key); sync-knowledge/api/secretaria/*.
  • Motor → Satélite: webhook POST /api/webhook/newwhats (HMAC webhook_secret); Secretária consulta /nw/* (integration_key).

Frontend (React SPA)

  • Plugin newwhats registrado em frontend/views/PluginsView.tsx (catálogo PLUGINS) — config exclusiva do superadmin (a view plugins já é gateada em App.tsx isViewAllowed).
  • ALWAYS_ON em pluginRegistry.ts → Inbox/Secretária aparecem para todos os usuários (a ativação por plugin é localStorage e não propaga entre contas).
  • Views: frontend/views/WaInboxView.tsx (conversas/thread/envio) e WaSecretariaView.tsx (ask) — consomem /api/nw/v1/*. Estágio 1 (funcional, visual aproximado do motor; refinar para ficar idêntico).
  • Sidebar: itens WHATSAPP + SECRETÁRIA IA (gated por isPluginActive('newwhats')).

Pendências / TODO

  • Segurança: gatear o proxy /api/nw/v1/* com a auth do scoreodonto (hoje aberto — qualquer um que alcance a rota é proxiado ao motor).
  • Ponte de config (feito): config persiste na tabela settings (id=newwhats_config); backend lê do DB com fallback ENV (config.js loadConfigFromDb). UI dedicada (NewwhatsConfigModal) com dropdown de clínicas, secrets que mantêm valor se em branco e Testar conexão (GET /api/nw/status). Endpoints superadmin: GET/PUT /api/nw/config, GET /api/nw/clinicas, GET /api/nw/status.
  • webhook message.new: capturar lead / acionar fluxo (hoje só loga).
  • Proxy WS (/api/nw/v1/stream) — só o REST foi portado (Inbox sem tempo real).
  • Parear scoreodonto com o motor (criar apiKey/pair + agente) e preencher as ENV.
  • Endpoint/admin para disparar syncKnowledge (hoje exportado, sem rota).
  • Refinar Inbox/Secretária para ficarem idênticas ao motor.

Fonte da verdade do contrato: documentos-unicos/projetos/newwhats.clube67.com/.