Secretária IA — Auditoria de Inconsistências e Roadmap de Correções #14

Open
opened 2026-05-12 04:33:17 +02:00 by ruicesar · 0 comments
Owner

🔍 Contexto

Auditoria completa do ecossistema de IA/Chatbot/Secretária Virtual realizada em 12/05/2026. Foram identificados dois sistemas de IA paralelos sem integração, gaps críticos na entrega automática de respostas via WhatsApp, e ausência de feedback visual no inbox.


🏗️ Arquitetura Atual

Sistema Arquivo Descrição Status
Chatbot Rápido backend/src/modules/chatbot/chatbot.service.ts Gemini Flash, ativado automaticamente no MessageHandler Funciona
Secretária IA plugins/secretaria/brain.ts ProtocolEngine multi-provider com tool calling ⚠️ Não auto-disparada
Ponte ext-api plugins/ext-api/backend/routes.ts /secretaria/ask — ponto de entrada externo ⚠️ Não envia reply WA

Problema central: A Secretária IA não tem loop automático. Para funcionar end-to-end, depende de:

  1. Webhook externo configurado
  2. Webhook chama /api/ext/v1/secretaria/ask
  3. Webhook recebe reply e chama /api/ext/v1/send-text separadamente

Se qualquer um desses passos falhar (sem webhook, sem API key ext-api), a secretária fica completamente muda.


🚨 P0 — Crítico (bloqueiam funcionamento)

  • [SEC-01] Secretária não envia reply automaticamente via WhatsApp

    • plugins/ext-api/backend/routes.ts:738-750: /secretaria/ask retorna { reply } mas NÃO chama sock.sendMessage() de volta
    • A resposta da IA fica presa no servidor — nunca chega ao usuário no WhatsApp
    • Fix: Após brain.chat(), chamar manager.getSocket(instanceId)?.sendMessage(jid, { text: reply }) e persistir a mensagem
  • [SEC-02] Secretária não é disparada automaticamente por mensagens recebidas

    • MessageHandler.ts:703-714: só chama chatbotService (chatbot rápido), nunca o ProtocolEngine
    • A Secretária só pode ser invocada via POST /api/ext/v1/secretaria/ask por webhook externo
    • Fix: Adicionar integração direta no MessageHandler para instâncias com a Secretária configurada como provider ativo, ou criar um hook interno hooks.on('ext:message.new') dentro do plugin secretaria
  • [SEC-03] Secretária e Chatbot Rápido podem disparar ao mesmo tempo

    • Sem mecanismo de exclusão mútua: se uma instância tem ambos configurados, os dois tentam responder a mesma mensagem
    • Fix: Verificar se instância tem Secretária ativa antes de invocar ChatbotService; ou vice-versa

⚠️ P1 — Alto (degradam UX)

  • [SEC-04] Indicador visual de "bot ativo/pausado" ausente no inbox

    • chatStore.ts:415-416: evento bot:escalated atualiza chat.botPaused = true no store, mas nenhum componente exibe isso
    • frontend/components/ChatListItem.tsx: sem badge, ícone ou cor diferente para chats com bot pausado
    • Fix: Adicionar indicador visual (ex: ícone 🤖 barrado ou badge "Aguardando humano") em ChatListItem.tsx quando chat.botPaused === true
  • [SEC-05] botPaused não é mapeado na bridge legada

    • hooks/inbox/useNewInboxBridge.ts: chatToLegacy() não inclui botPaused no objeto retornado
    • O inbox legado não consegue exibir o estado mesmo que o componente fosse atualizado
    • Fix: Adicionar bot_paused: c.botPaused no chatToLegacy()
  • [SEC-06] ChatbotService usa apenas Gemini — sem fallback

    • chatbot.service.ts:9: importa GoogleGenerativeAI hardcoded
    • O schema AICredential suporta LLMProvider.OPENAI mas o service nunca usa OpenAI
    • Se quota Gemini esgotar → todas as respostas falham silenciosamente
    • Fix: Implementar fallback chain similar ao ProtocolEngine.callAI() do plugin secretaria
  • [SEC-07] LLMProvider enum desalinhado entre chatbot e secretaria

    • Backend Prisma: enum LLMProvider { GEMINI, OPENAI }
    • Plugin secretaria: suporta openai, anthropic, gemini, ollama
    • Anthropic e Ollama são inacessíveis pelo chatbot rápido e pelos endpoints /api/chatbot/*
    • Fix: Unificar ou documentar a divergência intencional

🔧 P2 — Médio (melhorias funcionais)

  • [SEC-08] /secretaria/ask cria nova conversa sem verificar se instância está conectada

    • ext-api/routes.ts:705-724: cria sec_conversation com ext_chat_id mas não valida se a instância WA está CONNECTED
    • Secretária pode acumular conversas órfãs para instâncias desconectadas
    • Fix: Validar status da instância antes de criar conversa
  • [SEC-09] POST /chatbot/bots/:instanceId retorna 409 sem mensagem amigável

    • chatbot.routes.ts: constraint @@unique([tenantId, instanceId]) causa 409 quando já existe bot
    • Mensagem de erro é genérica — usuário não entende que precisa editar o bot existente
    • Fix: Detectar P2002 e retornar mensagem clara: "Já existe um bot nesta instância. Use PUT para atualizar."
  • [SEC-10] credentialId não é validado no POST /bots

    • chatbot.routes.ts: cria bot com credentialId sem verificar se pertence ao mesmo tenantId
    • Potencial de associar credencial de outro tenant via força bruta de UUID
    • Fix: Verificar AICredential.tenantId === req.tenantId antes de criar
  • [SEC-11] Secretária não persiste mensagens no banco principal (Prisma)

    • brain.ts: armazena mensagens em sec_messages (SQLite via Knex) — tabela separada do DB principal
    • Mensagens da secretária NÃO aparecem na inbox do atendente
    • As mensagens enviadas pela IA chegam ao WhatsApp mas ficam invisíveis no histórico do sistema
    • Fix: Após sock.sendMessage(), criar registro em prisma.message igual ao que ChatbotService faz (linhas 175-188 do chatbot.service.ts)
  • [SEC-12] Resumo botSummary não é resetado ao retomar bot

    • chatbot.repository.ts:chatBotState.resumeBot(): só muda botPaused = false, não limpa botSummary
    • Após escalação e retomada, o contexto fica com resumo defasado
    • Fix: Limpar ou marcar botSummary como stale ao retomar

📊 P3 — Baixo (observabilidade)

  • [SEC-13] Sem telemetria de tokens no ChatbotService

    • chatbot.service.ts: não registra inputTokens, outputTokens por chamada
    • Plugin secretaria registra via conv.total_tokens
    • Fix: Adicionar log estruturado com tokens consumidos por sessão
  • [SEC-14] Sem indicador de "Respondendo..." enquanto IA processa

    • Usuário não sabe que a IA está gerando resposta (pode demorar 2-5s)
    • Fix: Emitir Socket.IO chat:typing antes de chamar a IA e cancelar após
  • [SEC-15] Página /bots e página /secretaria sem unificação

    • Dois sistemas completamente separados na UI sem nenhuma relação visual
    • Usuário não sabe qual usar, quando usar cada um, ou como eles interagem
    • Fix: Adicionar documentação inline ou unificar sob um único menu "IA"

📁 Arquivos Envolvidos

Arquivo Issues
backend/src/modules/chatbot/chatbot.service.ts SEC-06, SEC-13, SEC-14
backend/src/modules/chatbot/chatbot.routes.ts SEC-09, SEC-10
backend/src/modules/whatsapp/handlers/MessageHandler.ts SEC-02, SEC-03
plugins/secretaria/brain.ts SEC-11
plugins/ext-api/backend/routes.ts SEC-01, SEC-08
frontend/components/ChatListItem.tsx SEC-04
frontend/hooks/inbox/useNewInboxBridge.ts SEC-05
frontend/pages/bots/index.tsx SEC-15
frontend/pages/secretaria/index.tsx SEC-15
Schema Prisma AICredential/AIBot SEC-07

Componentes Consistentes (sem ação necessária)

  • Chat.botPaused / Chat.botSummary no schema Prisma
  • Integração MessageHandler → ChatbotService via setImmediate()
  • Emissão de bot:escalated via Socket.IO
  • chatStore.ts recebe e processa bot:escalated
  • Tool calling no ProtocolEngine (agendar, escalar, encerrar)
  • Fallback chain multi-provider no ProtocolEngine
  • Endpoint /sec/handoff/:chatId para controle manual
## 🔍 Contexto Auditoria completa do ecossistema de IA/Chatbot/Secretária Virtual realizada em 12/05/2026. Foram identificados **dois sistemas de IA paralelos** sem integração, gaps críticos na entrega automática de respostas via WhatsApp, e ausência de feedback visual no inbox. --- ## 🏗️ Arquitetura Atual | Sistema | Arquivo | Descrição | Status | |---|---|---|---| | **Chatbot Rápido** | `backend/src/modules/chatbot/chatbot.service.ts` | Gemini Flash, ativado automaticamente no MessageHandler | ✅ Funciona | | **Secretária IA** | `plugins/secretaria/brain.ts` | ProtocolEngine multi-provider com tool calling | ⚠️ Não auto-disparada | | **Ponte ext-api** | `plugins/ext-api/backend/routes.ts` | `/secretaria/ask` — ponto de entrada externo | ⚠️ Não envia reply WA | **Problema central:** A Secretária IA não tem loop automático. Para funcionar end-to-end, depende de: 1. Webhook externo configurado 2. Webhook chama `/api/ext/v1/secretaria/ask` 3. Webhook recebe `reply` e chama `/api/ext/v1/send-text` separadamente Se qualquer um desses passos falhar (sem webhook, sem API key ext-api), a secretária fica completamente muda. --- ## 🚨 P0 — Crítico (bloqueiam funcionamento) - [ ] **[SEC-01] Secretária não envia reply automaticamente via WhatsApp** - `plugins/ext-api/backend/routes.ts:738-750`: `/secretaria/ask` retorna `{ reply }` mas NÃO chama `sock.sendMessage()` de volta - A resposta da IA fica presa no servidor — nunca chega ao usuário no WhatsApp - **Fix:** Após `brain.chat()`, chamar `manager.getSocket(instanceId)?.sendMessage(jid, { text: reply })` e persistir a mensagem - [ ] **[SEC-02] Secretária não é disparada automaticamente por mensagens recebidas** - `MessageHandler.ts:703-714`: só chama `chatbotService` (chatbot rápido), nunca o `ProtocolEngine` - A Secretária só pode ser invocada via `POST /api/ext/v1/secretaria/ask` por webhook externo - **Fix:** Adicionar integração direta no MessageHandler para instâncias com a Secretária configurada como provider ativo, ou criar um hook interno `hooks.on('ext:message.new')` dentro do plugin secretaria - [ ] **[SEC-03] Secretária e Chatbot Rápido podem disparar ao mesmo tempo** - Sem mecanismo de exclusão mútua: se uma instância tem ambos configurados, os dois tentam responder a mesma mensagem - **Fix:** Verificar se instância tem Secretária ativa antes de invocar ChatbotService; ou vice-versa --- ## ⚠️ P1 — Alto (degradam UX) - [ ] **[SEC-04] Indicador visual de "bot ativo/pausado" ausente no inbox** - `chatStore.ts:415-416`: evento `bot:escalated` atualiza `chat.botPaused = true` no store, mas nenhum componente exibe isso - `frontend/components/ChatListItem.tsx`: sem badge, ícone ou cor diferente para chats com bot pausado - **Fix:** Adicionar indicador visual (ex: ícone 🤖 barrado ou badge "Aguardando humano") em `ChatListItem.tsx` quando `chat.botPaused === true` - [ ] **[SEC-05] botPaused não é mapeado na bridge legada** - `hooks/inbox/useNewInboxBridge.ts`: `chatToLegacy()` não inclui `botPaused` no objeto retornado - O inbox legado não consegue exibir o estado mesmo que o componente fosse atualizado - **Fix:** Adicionar `bot_paused: c.botPaused` no `chatToLegacy()` - [ ] **[SEC-06] ChatbotService usa apenas Gemini — sem fallback** - `chatbot.service.ts:9`: importa `GoogleGenerativeAI` hardcoded - O schema `AICredential` suporta `LLMProvider.OPENAI` mas o service nunca usa OpenAI - Se quota Gemini esgotar → todas as respostas falham silenciosamente - **Fix:** Implementar fallback chain similar ao `ProtocolEngine.callAI()` do plugin secretaria - [ ] **[SEC-07] LLMProvider enum desalinhado entre chatbot e secretaria** - Backend Prisma: `enum LLMProvider { GEMINI, OPENAI }` - Plugin secretaria: suporta `openai, anthropic, gemini, ollama` - Anthropic e Ollama são inacessíveis pelo chatbot rápido e pelos endpoints `/api/chatbot/*` - **Fix:** Unificar ou documentar a divergência intencional --- ## 🔧 P2 — Médio (melhorias funcionais) - [ ] **[SEC-08] `/secretaria/ask` cria nova conversa sem verificar se instância está conectada** - `ext-api/routes.ts:705-724`: cria `sec_conversation` com `ext_chat_id` mas não valida se a instância WA está `CONNECTED` - Secretária pode acumular conversas órfãs para instâncias desconectadas - **Fix:** Validar status da instância antes de criar conversa - [ ] **[SEC-09] POST /chatbot/bots/:instanceId retorna 409 sem mensagem amigável** - `chatbot.routes.ts`: constraint `@@unique([tenantId, instanceId])` causa 409 quando já existe bot - Mensagem de erro é genérica — usuário não entende que precisa editar o bot existente - **Fix:** Detectar P2002 e retornar mensagem clara: "Já existe um bot nesta instância. Use PUT para atualizar." - [ ] **[SEC-10] credentialId não é validado no POST /bots** - `chatbot.routes.ts`: cria bot com `credentialId` sem verificar se pertence ao mesmo `tenantId` - Potencial de associar credencial de outro tenant via força bruta de UUID - **Fix:** Verificar `AICredential.tenantId === req.tenantId` antes de criar - [ ] **[SEC-11] Secretária não persiste mensagens no banco principal (Prisma)** - `brain.ts`: armazena mensagens em `sec_messages` (SQLite via Knex) — tabela separada do DB principal - Mensagens da secretária NÃO aparecem na inbox do atendente - As mensagens enviadas pela IA chegam ao WhatsApp mas ficam invisíveis no histórico do sistema - **Fix:** Após `sock.sendMessage()`, criar registro em `prisma.message` igual ao que `ChatbotService` faz (linhas 175-188 do chatbot.service.ts) - [ ] **[SEC-12] Resumo `botSummary` não é resetado ao retomar bot** - `chatbot.repository.ts:chatBotState.resumeBot()`: só muda `botPaused = false`, não limpa `botSummary` - Após escalação e retomada, o contexto fica com resumo defasado - **Fix:** Limpar ou marcar `botSummary` como stale ao retomar --- ## 📊 P3 — Baixo (observabilidade) - [ ] **[SEC-13] Sem telemetria de tokens no ChatbotService** - `chatbot.service.ts`: não registra `inputTokens`, `outputTokens` por chamada - Plugin secretaria registra via `conv.total_tokens` - **Fix:** Adicionar log estruturado com tokens consumidos por sessão - [ ] **[SEC-14] Sem indicador de "Respondendo..." enquanto IA processa** - Usuário não sabe que a IA está gerando resposta (pode demorar 2-5s) - **Fix:** Emitir Socket.IO `chat:typing` antes de chamar a IA e cancelar após - [ ] **[SEC-15] Página `/bots` e página `/secretaria` sem unificação** - Dois sistemas completamente separados na UI sem nenhuma relação visual - Usuário não sabe qual usar, quando usar cada um, ou como eles interagem - **Fix:** Adicionar documentação inline ou unificar sob um único menu "IA" --- ## 📁 Arquivos Envolvidos | Arquivo | Issues | |---|---| | `backend/src/modules/chatbot/chatbot.service.ts` | SEC-06, SEC-13, SEC-14 | | `backend/src/modules/chatbot/chatbot.routes.ts` | SEC-09, SEC-10 | | `backend/src/modules/whatsapp/handlers/MessageHandler.ts` | SEC-02, SEC-03 | | `plugins/secretaria/brain.ts` | SEC-11 | | `plugins/ext-api/backend/routes.ts` | SEC-01, SEC-08 | | `frontend/components/ChatListItem.tsx` | SEC-04 | | `frontend/hooks/inbox/useNewInboxBridge.ts` | SEC-05 | | `frontend/pages/bots/index.tsx` | SEC-15 | | `frontend/pages/secretaria/index.tsx` | SEC-15 | | Schema Prisma `AICredential/AIBot` | SEC-07 | --- ## ✅ Componentes Consistentes (sem ação necessária) - `Chat.botPaused` / `Chat.botSummary` no schema Prisma ✅ - Integração `MessageHandler → ChatbotService` via `setImmediate()` ✅ - Emissão de `bot:escalated` via Socket.IO ✅ - `chatStore.ts` recebe e processa `bot:escalated` ✅ - Tool calling no `ProtocolEngine` (agendar, escalar, encerrar) ✅ - Fallback chain multi-provider no `ProtocolEngine` ✅ - Endpoint `/sec/handoff/:chatId` para controle manual ✅
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: ruicesar/clube67_newwhats.local#14