Commit Graph

19 Commits

Author SHA1 Message Date
VPS 4 Deploy Agent 6d9850d8d3 feat(secretaria): monitor de cota dos providers + notificação ao admin
- brain: detecta 429/cota (quota/billing/insufficient/exceeded/limite da api/
  rate limit — inclui a msg PT do Gemini) e emite ext:provider.exhausted por
  provider da chain (throttle de 6h por provider), com fallback informado.
- routes: handler ext:provider.exhausted monta notificação profissional e envia
  por WhatsApp ao admin (admin_notify_phone da config secretaria), resolvendo o
  JID canônico via onWhatsApp (trata 9º dígito BR; pula se número não existe).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 07:49:00 +02:00
VPS 4 Deploy Agent b4d43fc3d6 feat(secretaria): modelo de canal (clinica_id) + auto-reply 1:1 com nome legível
- sec_numbers ganha clinica_id (mapa canal→clínica); migrate idempotente.
- clinica_id resolvido por CANAL no auto-reply (sec_numbers pela instância que
  recebeu) e por-REQUISIÇÃO no chat manual (header x-nw-clinica); brain.chat
  aceita opts.clinicaId e escopa a ponte de agenda (fallback: config global).
- /secretaria/numbers CRUD inclui clinica_id.
- auto-reply só cria conversa para 1:1 (@s.whatsapp.net) — exclui grupos/
  broadcast/newsletter/lid; contact_name legível (Contact → +telefone → jid).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 05:20:28 +02:00
VPS 4 Deploy Agent 9dbdd359ce feat(ext-api): API REST /secretaria/* (agents/nodes/calendar/numbers/conversations)
Expõe o contrato de administração esperado pelo painel da Secretária no satélite
(antes só havia /secretaria/ask|numbers + /sec/* parcial → 404 em agents/calendar):
- agents: GET/POST/PUT/DELETE
- brain nodes: GET/POST por agente (/agents/:agentId/nodes) + PUT/DELETE (/nodes/:id)
- calendar: GET/POST/PUT/DELETE
- numbers: POST/PUT/DELETE (GET já existia)
- conversations (teste): list/create/patch/delete, /messages, /chat (brain.chat),
  /finalize (brain.finalizeProtocol)
Backed pelas tabelas sec_* (globais/single-tenant no motor).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 04:59:43 +02:00
VPS 4 Deploy Agent 35188b4f9a feat(ext-api): chave de satélite e-mail-capable (REST + WS)
A integration_key do satélite (nwk_) passa a resolver por x-nw-email quando
presente (preserva multi-conta: cada usuário vê o WhatsApp do seu e-mail),
caindo no tenant dono do par quando ausente — igual no middleware REST e no
handshake do WS bridge. Valida o par (revoke) antes de resolver por email.
Permite migrar o scoreodonto da EXT_MASTER_KEY global p/ chave própria
(revogável/auditada), sem mudança de comportamento.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 03:56:25 +02:00
VPS 4 Deploy Agent 89758a0e6b feat(ext-api): gerenciador de satélites — auth por integration_key + gestão
Torna o registry de satélites (PluginPair) o gatekeeper do ext-api, em vez de
uma única EXT_MASTER_KEY global:
- satellites.ts: serviço + router /api/ext/v1/satellites (listar/provisionar/
  revogar/rotacionar), montado fora do authMiddleware com gate de chave mestra.
- apikey-auth: resolvePairKey aceita a chave do satélite (nwk_) no REST e no WS,
  resolvendo o tenant do par; checa revoke no banco a cada request (revoke
  instantâneo) + throttle de lastSeenAt.
- Chave mestra e ApiKey por-tenant seguem funcionando (não-quebra).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 03:29:43 +02:00
VPS 4 Deploy Agent 28b9ba899c feat(secretaria): kill-switch do auto-reply (secretaria.auto_reply=false)
Bloqueia SÓ o disparo automático da Secretária (envios manuais seguem normais).
Só desliga quando a config é explicitamente false — sem a flag, inalterado.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 00:51:47 +02:00
VPS 4 Deploy Agent d09155613c feat(secretaria): tools de agenda operam na agenda real do satélite via ponte
listar_horarios/agendar_horario chamam a ponte do scoreodonto (/api/nw/agenda
slots|book) quando configurada — slot_id sintético (dentista|start|end), telefone
derivado do JID do contato — com fallback ao calendário interno preservado.
brain.ts injeta a config da agenda (agenda_url/secret/clinica_id) no toolCtx.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 00:51:47 +02:00
VPS 4 Deploy Agent 007c300cb0 fix(secretaria): fallback resiliente a erros de rede no callAI
isRecoverableError inclui fetch failed/timeout/econnreset/etimedout/und_err —
um blip de rede no primeiro provider agora cai para o próximo da chain (openai→
gemini→anthropic→ollama) em vez de virar "[Erro ao chamar IA: fetch failed]".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 20:55:22 +02:00
VPS 4 Deploy Agent a1eec8dac2 feat(ext-api): inbox ordenado, avatar self-heal, /sec/keys e guard de grupo
- GET /inbox: orderBy lastMessageAt DESC NULLS LAST (Postgres põe NULLS FIRST
  em DESC → chats-stub sem mensagem tomavam o topo; parecia lista de contatos).
- GET /contacts/:jid/avatar/refresh: re-busca a foto pela conexão Baileys viva
  (URLs do CDN expiram/404), com timeout de 5s e limpeza da URL obsoleta.
- GET/PUT /sec/keys: passam a ler/gravar na config do plugin 'secretaria'
  (config é por-plugin: set(pluginName, obj)); antes gravava em plugin errado
  e o brain nunca via as chaves. Corrige TS2345.
- auto-reply da Secretária: nunca responde em grupos (@g.us).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 20:55:22 +02:00
VPS 4 Deploy Agent dbb4da8220 feat(ext-api): chave mestra + x-nw-email (middleware REST + WS bridge)
Satélite confiável acessa a conta de qualquer email via EXT_MASTER_KEY:
- apikey-auth: helpers isMasterKey/resolveMasterEmail resolvem o tenant pelo
  User.email; middleware REST refatorado para usá-los.
- ws-bridge: handshake do /api/ext/v1/stream trata a chave mestra + x-nw-email
  (antes só tabela apiKey → o túnel WS tomava 401).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 20:55:10 +02:00
VPS 4 Deploy Agent 62ba985ebe fix(ext-api): /secretaria/ask usa chat.jid (não remoteJid inexistente)
prisma.chat.findFirst filtrava por remoteJid, que não existe no model Chat (é jid)
→ 500 em todo /secretaria/ask. Corrigido; endpoint retorna o reply normalmente.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 16:53:13 +02:00
VPS 4 Deploy Agent 9ba3c78752 fix(secretaria): embeddings Gemini usam gemini-embedding-001 (768d)
text-embedding-004 foi descontinuado (404 'model not found'). Migra para
gemini-embedding-001 com outputDimensionality=768 (vetores leves p/ JSON+cosseno).
Validado: embed() retorna vetor 768d via Gemini.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 15:29:09 +02:00
VPS 4 Deploy Agent f51785bace fix(secretaria): embed() cai para Gemini se OpenAI falhar (não derruba RAG)
Antes, com openai_key presente, qualquer falha (ex.: 429 insufficient_quota)
retornava null sem tentar o Gemini. Agora tenta OpenAI e, em falha, usa Gemini.
Aviso documentado: OpenAI (1536d) e Gemini (768d) são incompatíveis — trocar de
provider exige reindexar (sync-knowledge + memória de contato).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 15:23:45 +02:00
VPS 4 Deploy Agent e47b64a5b5 feat(media): index e delete em lote de mídias (Wasabi, coordenado DB↔storage)
- StorageProvider.deleteObjects(paths): delete seletivo em lote (chunks de 1000),
  no provider concreto (Wasabi DeleteObjectsCommand + fallback local).
- GET /api/instances/:id/media-index: index/auditoria por chat/tipo/período
  (baseado no DB, com agregado byType, paginado).
- POST /api/instances/:id/media-batch-delete: delete coordenado DB↔Wasabi,
  dryRun por padrão (precisa dryRun:false p/ apagar); limpa mediaPath/mediaUrl.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 14:52:25 +02:00
VPS 4 Deploy Agent 734b250238 feat(ext-api): alias GET /secretaria/numbers (sincroniza contrato com satélite)
O satélite (mercado, webhook-receiver) chama /api/ext/v1/secretaria/numbers, mas
o ext-api só tinha /sec/*. Adiciona o alias que espelha a rota interna
/api/secretaria/numbers (lista sec_numbers) — retrocompatível, não altera o satélite.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 08:27:41 +02:00
VPS 4 Deploy Agent 42a04efe14 feat(secretaria): memória de longo prazo por contato (a partir das conversas)
A secretária passa a "lembrar" do cliente entre conversas:
- tabela sec_contact_memory (fato + embedding JSON), chave = ext_chat_id/contact_name.
- na sumarização (a cada ~10 trocas) extrai fatos duradouros do cliente via LLM
  e salva com embedding + dedup por similaridade (>0.92).
- buildSystemPrompt injeta "MEMÓRIA DO CLIENTE" com os fatos mais relevantes à
  pergunta (cosseno); sem chave de embedding usa os mais recentes; tudo com
  fallback silencioso (não regride).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 08:05:42 +02:00
VPS 4 Deploy Agent 31bf45faf5 feat(secretaria): RAG sem pgvector no conhecimento (embeddings + cosseno)
Adiciona busca semântica na Base de Conhecimento da secretária:
- embeddings.ts: chunking, embed (OpenAI text-embedding-3-small ou Gemini
  text-embedding-004) e similaridade cosseno — tudo na aplicação, sem pgvector.
- tabela sec_knowledge_chunks (vetor em JSON/text) com índices.
- brain.ts: no nó 'knowledge', injeta só os top-4 trechos relevantes à pergunta
  do usuário; indexação lazy por hash do conteúdo. Fallback para o conteúdo
  inteiro se não houver chave de embedding ou em qualquer falha (não regride).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-28 07:08:42 +02:00
VPS 4 Deploy Agent 2a15e8ea1e fix(secretaria): migra colunas de telemetria em sec_messages (42703)
O createTable de sec_messages não tinha usage_tokens/provider_used/model_used,
mas brain.ts insere esses campos — quebrando com "column does not exist" em
qualquer banco criado antes dessas colunas (ex.: clones). Adiciona as colunas
ao createTable e um bloco idempotente hasColumn/alterTable (padrão já usado no
arquivo) que garante as colunas em tabelas pré-existentes no boot.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-27 23:43:37 +02:00
VPS 4 Deploy Agent 2f8c04a0a7 chore(ops): restore all source files in newwhats.clube67.com
continuous-integration/webhook Falha no deploy de clube67_newwhats.local (VPS 4)
2026-05-18 03:28:29 +02:00