776c25c3de
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4.0 KiB
4.0 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 noserver.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)noserver.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/*esync-knowledgeusam clínica/especialidades/dentistas/procedimentos/planos (multi-tenant porclinica_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(HMACwebhook_secret); Secretária consulta/nw/*(integration_key).
Frontend (React SPA)
- Plugin
newwhatsregistrado emfrontend/views/PluginsView.tsx(catálogo PLUGINS) — config exclusiva do superadmin (a viewpluginsjá é gateada emApp.tsx isViewAllowed). ALWAYS_ONempluginRegistry.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) eWaSecretariaView.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: a config do plugin no frontend é localStorage e não
chega ao backend (que lê ENV). Definir: backend ler de
settings/DB + UI salvar lá (endpoint), OU manter ENV no deploy (UI só informativa). 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/.