Sistema MIA mapa completo
Seções ▾
  1. Visão geral
  2. As camadas
  3. Infra
  4. Canal
  5. Atendimento
  6. Cérebro (Claude)
  7. Dados
  8. Vitrine
  9. Como se alimenta
  10. Clientes
  11. Lacunas
Mapa do sistema · 18 jun 2026

Como a MIA funciona, de ponta a ponta

A MIA (da MiaConecta, dentro do Grupo Conecta) faz duas coisas: atende no WhatsApp os pacientes e leads de cada cliente em tempo real, e gera insights de melhoria a partir dessas conversas. O atendimento roda em Gemini Flash dentro do n8n; a análise roda em Claude de madrugada; tudo aparece num dashboard interno.

Canal
WhatsApp ↔ Evolution ↔ Chatwoot
A porta de entrada e saída de toda conversa.
evento (webhook)
Gemini Flash · tempo real Atendimento (n8n)
O bot que conversa com o paciente
Junta o burst, consulta histórico, decide a resposta, agenda/escala.
grava conversas e desfechos
Dados
Postgres :5433 · fork Chatwoot · Qdrant
A fonte de verdade — lida tanto pela vitrine quanto pelo cérebro.
↑ escreve fatos  ·  lê ↓
Claude · madrugada Cérebro de análise
Destila fatos e insights
Lê o que já aconteceu e escreve de volta. Read-only em produção.
Vitrine
Dashboard interno
Só lê e mostra. O Juca lê, decide e exporta pro cliente.
Infra: 2 máquinas — MIA-SUPORTE (estação local, roda os crons do Claude) e MIA-01 / Hetzner (produção: n8n, Chatwoot, Evolution, bancos, Qdrant, painel).

Levantado factualmente via 6 leitores independentes (infra, canal, atendimento, cérebro, dados, dashboard) + revisão adversarial. IDs e volumes valem para 18/06/2026 — verificar na fonte antes de tratar como verdade atual.

01 As camadas

Seis camadas, dois cérebros de IA com papéis que nunca se misturam: Gemini atende, Claude analisa.

CanalEvolution + Chatwoot

O caminho da mensagem. O paciente escreve no WhatsApp; a Evolution API (gateway sobre o protocolo Baileys) entrega no Chatwoot fork fazer.ai (onde a conversa vive), que dispara um webhook pro n8n. Na volta, o n8n responde pelo mesmo caminho.

Atendimenton8n · Gemini Flash

O bot em tempo real. Identifica o cliente, junta as mensagens do "burst", consulta o histórico, e um AI Agent rodando Gemini Flash decide a resposta — podendo buscar agenda, agendar, enviar mídia ou escalar pra humano. Não usa Claude.

CérebroClaude Opus · cron

A camada analítica, separada do atendimento. De madrugada o Claude headless lê as conversas já ocorridas + erros do n8n + Postgres e destila fatos, qualidade, comparação com o registro humano, insights, triagem e relatórios. Read-only em produção — só escreve em tabelas de análise. Não fala com paciente.

DadosPostgres + Qdrant

Onde tudo é persistido: Postgres :5433 (ciclo do paciente, fila de melhorias, config dos bots, schema por cliente), o Postgres do fork Chatwoot (mensagens reais) e o Qdrant (conhecimento dos bots, RAG).

VitrineNext.js · interno

O painel do Juca (painel.miaconecta.com.br) que só lê os dados. Não chama IA ao abrir tela nenhuma — funil e insights são SELECT + TypeScript determinístico. O relatório exportável é a peça que vai pro cliente.

Infra2 hosts

MIA-SUPORTE (estação local — roda os crons do Claude) e MIA-01 / Hetzner (produção — n8n, Chatwoot, Evolution, todos os Postgres, Qdrant e o painel). Traefik faz roteamento e TLS.

02 Infra — onde tudo roda

Duas máquinas no SSH config. Os crons do Claude rodam 100% na primeira; toda a produção roda na segunda.

HostEndereçoPapel
MIA-SUPORTE (local)204.168.225.110Estação de orquestração — roda os crons do Claude, code-server, CCR, backend do dashboard legado (inativo)
MIA-01 (prod, Hetzner)178.156.206.230Produção — n8n, Chatwoot fork, Evolution, todos os Postgres, Qdrant, painel
Notas Só o alias hetzner no SSH config. Nenhum host roda Ollama. Os crons do Claude rodam na MIA-SUPORTE, não no Hetzner.

MIA-01 / Hetzner — containers principais (de 19)

ContainerImagemPapelPorta
n8n-coolify-n8n-editor-1n8nio/n8n:2.21.7n8n produção — editor + worker + queue no mesmo container5678
chatwoot-baileys-rails-1chatwoot-pro v4.14 fazer-aiChatwoot fork fazer.ai (canônico)3000
chatwoot-baileys-sidekiq-1chatwoot-proWorker Sidekiq do fork3000
chatwoot-baileys-evolution-api-1evolution-api:2.4.0-rc2Evolution API (gateway WhatsApp/Baileys)8080
chatwoot-baileys-postgres-1pgvector/pgvector:pg16Postgres do fork + Evolution5432
postgres_postgres.1…postgres:16Postgres :5432 — banco n8n_queue (Swarm)5432
redis_redis.1…redis:7Redis do n8n (fila Bull / queue mode)6379
postgres-api-s2-postgres-principal-1postgres:16Postgres :5433 — schemas cliente / mia_ciclo / mia_demandas / mia_internal5433
qdrant_qdrant.1…qdrant/qdrantQdrant (vetorial — kb_*)6333
minio_minio.1…minio/minioMinIO (S3 — anexos do Chatwoot)9000
traefik-proxytraefik:v3.6Reverse proxy / TLS (80, 443)80/443
painel-miapainel-mia-painelPainel MIA (Next.js)3100

Domínios → backend

DomínioBackendHost
n8n + webhook.miaconecta.com.brn8n editor (:5678)Hetzner
chatwoot.miaconecta.com.brChatwoot fork :3000 (canônico)Hetzner
chat / evopanel.miaconecta.com.brEvolution API :8080Hetzner
painel.miaconecta.com.brpainel-mia:3000Hetzner
code / ccr.miaconecta.com.brMIA-SUPORTE :3030 / :3456MIA-SUPORTE
Três stacks Postgres distintos :5432 Swarm = n8n_queue · fork (pgvector) = Chatwoot + Evolution · :5433 = schemas de cliente / mia_ciclo / mia_demandas / mia_internal. O n8n não tem worker em container separado (o n8n-...-worker-1 citado em docs antigos não existe). Chatwoot só existe como fork fazer.ai; o antigo cwmkt está morto desde 05/05/2026.

03 Canal — WhatsApp ↔ Evolution ↔ Chatwoot ↔ n8n

Dois componentes: a Evolution API (gateway WhatsApp) e o Chatwoot fork fazer.ai (inbox + fonte dos eventos).

Ida — paciente → IA

O paciente manda WhatsApp pro número do cliente. A Evolution recebe via Baileys e encaminha pro Chatwoot por webhook interno (entra como message_type=0, incoming). O Chatwoot dispara o webhook account-levelwebhook.miaconecta.com.br/webhook/chatwoot-front, que alimenta o n8n. O agent_bots.outgoing_url fica NULL de propósito, pra evitar webhook concorrente.

Volta — IA → paciente

O n8n posta a resposta no Chatwoot via API REST (message_type=1, outgoing). O Chatwoot repassa pra Evolution, que envia ao WhatsApp.

Gotcha real A evolution-api resolve pra IP privado do Docker; o ssrf_filter do fork bloqueava isso e jogava o WebhookJob em loop (incidentes 26/05 e 01/06). Fix = initializer zz_safe_fetch_allow_evolution.rb (allowlist).

Mapa cliente → conta / inbox (tudo no fork)

Clienteaccountinboxinbox nameschema (:5433)
Dr Hugo318hugodr_hugo_ximenes
Dra Nathalya219nathalyadra_nathalya
Dr Carlos517carlosdr_carlos_hog
Mais Saúde616mais-saudemais_saude
Explow415explowexplow
Dr Thiago714thiagodr_thiago_valle

Contas extras (fora dos 6): acc 1 = MIA / inbox 12 mia-test · acc 8 = Juca Pessoal / inbox 13 juca-pessoal (onde vivem os grupos de suporte MIA - <Cliente>) · acc 9 Jess · acc 10 HEALIX · acc 11 CEAFI_GERUZA. Total: 11 contas / 9 inboxes.

Mecânica de status — inverte o default do Chatwoot pending = IA conduzindo · resolved = fechada (reabre se o paciente escrever) · open = humano assumiu, bot cala. Handoff oficial = mudar pra open. Atribuir um agente não pausa o bot. Em workflows de IA, a chave de sessão é o conversation_id do Chatwoot (nunca o telefone sozinho, por causa de LID/fake_pn).

04 Atendimento em tempo real — a arquitetura do bot

O cérebro de atendimento não é por cliente — é um par central na pasta Universais. Cada cliente só tem seu Config Loader + a suíte de ferramentas que o agente chama.

Os passos de uma mensagem

Chatwoot Trigger (1 por conta)
  → Config do cliente (chama o Config Loader)  → Filter  → IF horário comercial (só Hugo/Carlos)
  → Abrir Conversa (pending→open)  → Encaminhar pro Universal
  → Info  → IF tem mídia? (Gemini Mídia transcreve áudio / descreve imagem)
  → INSERT na filaWait (debounce)  → DELETE RETURNING  → Consolidar o burst
  → Histórico Chatwoot  → Single Agent (AI Agent)  → Enviar Humanizada  → UPSERT status

Ferramentas do Single Agent (via $fromAI): informacoes_gerais (RAG), Buscar_janelas_disponiveis, Criar_agendamento, Atualizar_agendamento, Buscar_agendamentos_do_contato, Cancelar_agendamento, enviar_midia, Escalar_humano, Refletir.

Clientes × workflows

ClienteSuíte de workflows
Mais SaúdeConfig Loader + 03/04/06/08/10 + 11/12 lembretes (inativos)
Dr HugoConfig Loader + suíte clínica completa (03/04/06/08/10)
Dr CarlosConfig Loader + suíte clínica completa (03/04/06/08/10)
Dra NathalyaConfig Loader + suíte clínica completa (03/04/06/08/10)
Dr Thiagosó Config Loader — SDR-only
ExplowConfig Loader + 03. Enviar Mídia (eventos, não agendamento)
LLM do atendimento Default = Google Gemini Chat Model (Gemini Flash), índice 0 do Single Agent. Fallback = OpenRouter gemini-flash-lite, índice 1. Nenhum Claude aqui — Claude só na análise de madrugada.

05 O cérebro de análise — Claude, de madrugada

O Claude headless (claude -p, modelo herda o default do CLI = Opus) lê a operação já acontecida e destila entendimento. Read-only em produção — só escreve em tabelas de análise/demandas e nos arquivos de relatório mensal. Os scripts vivem em demandas-clientes/scripts/ e rodam todos na MIA-SUPORTE.

Cron (UTC)BRT / diasScriptO que produz
0 6 * * 2-603h ter–sábrun-cron.sh conversasClaude lê o fork → 4 blocos por conversa (fatos / qualidade / comparação / insight) → mia_ciclo.analise_conversas; insight recorrente (≥2) vira card em mia_demandas.demandas
0 7 * * 2-604h ter–sábprojetar-fatos.shNão é Claude — psql puro: UNNEST dos fatos → mia_ciclo.fatos_conversa (idempotente). 1h depois do anterior
0 15,21 * * 1-512h e 18h seg–sexrun-cron.sh diarioTria os grupos de suporte + varre erros do n8n nas últimas 24h (≥3 vira demanda) + digest no Telegram. 18h sempre; 12h só se houver novidade
0 21 * * 018h domingorun-cron.sh semanalColeta + qualidade do bot + insights + maturidade + hardening + resumo semanal
0 12 1 * *09h dia 1ºrun-cron.sh mensalEscreve a seção por cliente em clientes/<x>/demandas-AAAA-MM.md (mês anterior) + digest
0 13 * * *10h diáriohealthcheck-cron.shDead-man: alerta no Telegram se nenhum run terminou com sucesso há ≥36h
0 11 * * *08h diáriohealthcheck-qualidade.shMonitor proativo: cliente vivo sem análise / canal morto → alerta
Divergência conhecida O run-cron.sh ainda grava o status fazer_juntos, mas o painel já aposentou esse campo pra parecer_pronto (Fase 3, 18/06). Funciona com tolerância a legado, mas o script ainda não foi atualizado. O --permission-mode default é obrigatório nos runs (o settings global é bypassPermissions, que o CLI recusa rodando como root via cron).

06 Dados — schemas e tabelas

O painel abre dois pools: dbSistema() → Postgres :5433 e dbFork() → Postgres do Chatwoot fork. Tudo read-only, exceto a decisão de demanda.

ObjetoTipoPapel / volume
mia_ciclo.fatos_conversatabelaFatos extraídos das conversas — base do funil por arquétipo (~453)
mia_ciclo.vw_funil_mesviewFunil mês a mês (chegou/agendou/compareceu/no-show). Só clínica
mia_ciclo.vw_reconciliacaoviewfatia_ia_pct — quanto dos agendamentos a IA fez vs equipe
mia_ciclo.analise_conversastabelaSaída do cron das 03h: fatos/qualidade/comparação em JSONB
mia_ciclo.eventostabelaHistórico de eventos do ciclo por contato (~4.003)
mia_ciclo.vw_crm_contatoviewFicha/CRM por contato — base das Fichas
mia_ciclo.kanban_cardstabelaEspelho do kanban fazer.ai (hoje só Hugo) — base do Quadro
mia_demandas.demandastabelaFila de demandas/reparos (~46). Única tabela escrita pelo painel
mia_demandas.maturidadetabelaDegraus M0–M6 por cliente (trilha de maturidade + upsell)
mia_demandas.runstabelaHistórico das varreduras do cron
mia_internal.tenantstabelaConfig dos bots: prompt, tools, KB, calendar_id, schema_pg, conta/inbox
mia_internal.tenants_historytabelaHistórico de mudanças (diff) — segredos nunca saem
<schema>.n8n_fila_mensagenstabela/clienteA fila de 25s — mensagens esperando resposta agora
fork messages / conversations / contactstabelasConversas reais, grupos MIA
Qdrant kb_* (ex.: kb_hugo)vetorialBase de conhecimento dos bots (RAG)

Arquétipos (fixos por slug em lib/funil.ts): clínica hugo · nathalya · carlos   SDR thiago   eventos explow   — mais_saude sem arquétipo (inativo).

07 Vitrine — as telas e de onde cada coisa vem

Auth scrypt + JWT (cookie mia_sessao). Navegação de 5 itens: Início · Reparos · Clientes · Conversas · Bots. Todas as telas server-side, com degradação graciosa. Nenhuma rota chama IA ao abrir.

Tela / rotaO que mostraFonte
barra de statusWhatsApp por cliente, erros 24h, reparos esperandoEvolution + n8n + mia_demandas
/ Início3 perguntas: tá de pé? / o que precisa de você? / como vai a operação? + alertashoje + saúde + alertas
/clientesOs 6 com saúde, última resposta, erros 24hsaúde + n8n
/cliente/[slug]4 abas: Visão · Insights (resumo determinístico + funil) · Relatórios · Históricosaúde + funil + insights + ciclo + confiança
…/melhoriasAnálises de conversa (cron 03h) + cards + gapsanalise_conversas + mia_demandas
…/quadroEspelho do kanban (só Hugo)kanban_cards
/reparosDecidir demanda: Aprovo / Não aprovo / Já comuniquei / Aguardarmia_demandas (escreve)
/numerosFunil mês a mês + atividade do assistenteciclo + atividade
/fichasBusca de pacientes + ficha + histórico do ciclo + conversaciclo + conversa
/conversasGrupos "MIA - <Cliente>" ao vivo (read-only, polling)fork (conta 8 / inbox 13)
/funil/[slug]Vitrine do funil agêntico por arquétipo + citações auditáveisfatos_conversa + vw_funil_mes
/bots + /bots/[slug]Gestor de IA: ativo, prompt, KB, fila/respostas, erros + diff de prompttenants + Qdrant + diff
/relatorio/[slug]Relatório mensal client-facing (PDF)ciclo + funil + melhorias
/semanal/[slug]Relatório semanal levefork

08 Como tudo se alimenta — os 2 fluxos

Um acontece na hora (atendimento, Gemini); o outro acontece em batch, de madrugada (análise, Claude). O primeiro gera os dados; o segundo os transforma em entendimento.

Fluxo A — atendimento em tempo real Gemini Flash

Paciente (WhatsApp)
   │
   ▼
Evolution API ──webhook──► Chatwoot fork (inbox do cliente)
                              │ webhook account-level
                              ▼
                  n8n: 01. Webhook-Loader  (identifica o cliente, Config Loader)
                              ▼
                  n8n: 02. Universal → INSERT fila → Wait (debounce) → DELETE RETURNING
                              ▼
                  Single Agent  ◄──  LLM: GEMINI FLASH  (fallback OpenRouter)
                   │   tools: buscar janela / criar agendamento / enviar mídia / escalar
                   ▼
                  Enviar Humanizada ──► Chatwoot ──► Evolution ──► WhatsApp (paciente)
                   └─► grava status + appointments/Calendar + fila

Fluxo B — análise / insight de madrugada Claude Opus

Cron na MIA-SUPORTE  (03h ter–sáb)
   ▼
run-cron.sh conversas   ◄──  LLM: CLAUDE (Opus), headless, READ-ONLY em prod
   │   lê: fork (conversas do dia) + erros do n8n + Postgres :5433
   │   destila por conversa:  FATOS · QUALIDADE · COMPARAÇÃO · INSIGHT
   ▼
escreve  mia_ciclo.analise_conversas
          └─ insight recorrente (≥2) ──► mia_demandas.demandas
   ▼  (04h — psql puro, NÃO Claude)
projetar-fatos.sh:  UNNEST ──► mia_ciclo.fatos_conversa
   ▼  (diário / semanal / mensal)
triagem dos grupos + maturidade + relatório por cliente
   ▼
DADOS ──SELECT determinístico (sem IA ao abrir)──► Painel ──► Juca lê, decide, exporta
Em uma frase O fluxo A gera a operação e os dados; o fluxo B lê esses dados e os transforma em entendimento; a vitrine mostra; o Juca decide. As conversas são a verdade, os relatórios são o motor, o dashboard é a vitrine.

09 Clientes & produto

ClienteArquétipoO que o bot fazEstado
Hugo · ortopedia/quadrilClínica que agendaBot Carol: atende, consulta Calendar, agenda/reagendaAtivo único com funil completo (compareceu 170 / no-show 15)
Nathalya · dermato/estéticaClínica que agendaBot Bia: rota clínica vs estética → cria evento no CalendarAtivo agendou 244
Carlos · cirurgia de colunaHíbrido tensão nos docsBot Ana: queixa → desambigua médico → qualifica (tools de agenda reativadas)IA dormente aguardando QR conectar; só agendou 4
Thiago · cirurgia plásticaSDR puroBot Sofia: qualifica via prompt, escala humano. Sem tool de agendaAtivo zero evento (cego no funil)
Explow · buffet infantilEventosBot Clara: qualifica, envia portfólio, passa pro consultorAtivo zero evento (cego no funil)
Mais Saúde · odontológicaClínica que agendaDetecta especialidade → busca janelas → agendamento (5 workflows)Inativo contrato encerrado 14/06; vira template

10 Lacunas honestas

O que ficou sem confirmar, ou que simplesmente ainda não existe. Sem maquiar.

  • Insight cruzado de jornada não existe. O sistema extrai fatos e insights por conversa e por cliente, mas não há (no código) um insight que cruze a jornada inteira de um paciente entre conversas — "confirmou e depois desmarcou" vira dois fatos soltos, ninguém costura.
  • Relatório é monomodal. A camada de entrega só serve clínica-que-agenda. SDR (Thiago) e Eventos (Explow) têm zero evento em mia_ciclo — a captura de "lead qualificado/handoff" e "orçamento respondido" não existe.
  • Cobertura parcial: só 3 de 6 clientes têm dados em mia_ciclo (Hugo, Nathalya, Carlos).
  • Tensão do Carlos não resolvida: agendamento ativo (doc do cliente) vs triagem/handoff (docs de produto). Precisa de decisão.
  • Temperatura do Gemini não verificada no node (convenção interna = 1.0).
  • Divergência script ↔ painel: o cron ainda grava fazer_juntos; o painel já migrou pra parecer_pronto.
  • A camada de confiança é hardcoded por cliente (hugo/nathalya/carlos), não derivada dos dados.
  • Autonomia agêntica (autogerencial): a ideia do sistema melhorar a própria estrutura no n8n é futuro declarado — não existe hoje.