Arquitetura IA Vendas

v2.1 — 19 PRs Atualizado 2026-04-02 Diagrama de Fluxo Diário de PRs Dashboard
PR Changelog — 19 correções pós-refactor
Mais recente primeiro · Todos mergeados em produção
#19featBadge LEGACY no dashboard + migração em lote — messageRouter seta Redis flag legacy, dashboardApi batch mget, index.html badge roxo LEGACY
#18fix3 bugs de progressão de funil — REAGENDADO + frases temporais + oferta duplicada
#17fixMP fallback rejeita XXXXXXXXXXX e verifica nome conflitante
#16fixMP name match exige valor quando sem CPF/email
#15fixCOMPROVANTE_RECEBIDO só transita com comprovante válido
#14fixENCERRAR bloqueado em AGUARDANDO_PAGAMENTO
#13fixREAGENDADO preserva Status Kommo existente na coluna G
#12fix'vou pensar' → REAGENDAR:1 pergunta melhor dia
#11fixDetecta intenção futura antes de disparar RESERVAR
#10fixAdiciona 'próxima semana' a SCHEDULING_PATTERNS
#9fixDespedida educada → ENCERRAR em vez de REAGENDAR
#8fixFU1 dedup avança para FU2 quando lead já respondeu
#7docsUpdate CLAUDE.md com contexto de sessão
#6fixProativo respeita REAGENDADO da planilha
#5fixREAGENDADO smart check — emoji/ok não cancela agendamento
#4fixLegacy check + AGUARDANDO_PAGAMENTO + métricas vendas + Kommo webhook nome
#3fixReagendado indevido + proativo FU step correto
#2fixExclui leads teste das métricas diárias
#1featPainel de métricas diárias no dashboard
1
Filosofia do Sistema
Princípio central: IA gera texto, código decide

A IA NÃO é o cérebro. A IA é uma funcionária.

1.
IA gera texto, código decide.
A Gemini gera a mensagem de venda. Mas quem decide se o pagamento é válido, se o pedido pode ser criado, se a mensagem pode ser enviada — é o código determinístico. A IA NUNCA confirma pagamento, NUNCA cria pedido, NUNCA bloqueia lead. Ela sugere, o código valida e executa.
2.
Estado é determinístico, não inferido.
Antes: o stage do lead era "adivinhado" por string matching no histórico. Agora: LeadStateService mantém o stage real em Redis com transições explícitas. Se o stage diz AGUARDANDO_PAGAMENTO, é porque alguém (código) transitou para lá com um trigger documentado.
3.
Modular: cada handler faz UMA coisa.
Antes: webhookService.ts tinha 1569 linhas fazendo tudo. Agora: 6 handlers especializados. messageRouter roteia, imageHandler processa imagens, replyGenerator gera respostas, actionParser extrai ações, actionExecutor executa, paymentTextChecker detecta pagamento por texto.
4.
Fail-open com rollback instantâneo.
9 feature flags no Redis com cache de 30s. Se algo der errado, desliga a flag é o sistema volta ao comportamento anterior em menos de 1 minuto. Zero downtime, zero deploy.
2
Arquitetura em 3 Camadas
Directives → Orchestration → Execution
Camada 1

Directives (SOPs)

Regras de negócio em Markdown — o "manual" da Luisa

5 documentos Markdown em src/directives/ que definem COMO o sistema deve se comportar. Não é código — é documentação executável que alimenta prompts e validações.

🤖 ai_behavior.md
Persona, tom, progressao, formato JSON, micro-CTAs
src/directives/ai_behavior.md
O que é: O "manual de comportamento" da Luisa. Define como ela fala, o tom de voz, quando deve ficar em silêncio, é como conduzir o lead rumo a compra. E como o treinamento que uma vendedora real recebe antes de começar a trabalhar — só que em formato digital.
  • Define a persona "Luisa" — closer elegante, simpatica, focada em conversao
  • Prompt V2: ~150 linhas dinâmico por stage (vs 700 legacy)
  • Pipeline: Planner → Operator → Guardian
  • Regras de NAO_RESPONDER (emoji solo, msgs sem resposta, situacao sensivel)
  • Progressao: max 2 msgs na mesma etapa, micro-CTA obrigatorio
  • Saida JSON: { message, actions, nextTask, nextTaskDays }
📊 lead_states.md
13 stages, transições validas, triggers, proteções
src/directives/lead_states.md
O que é: O "mapa de etapas" da venda. Cada lead está em uma etapa específica — como uma ficha que vai passando de mesa em mesa: primeiro chega (NOVO_LEAD), depois conversa (EM_CONVERSA), depois reserva, paga, e finalmente recebe o produto. Este documento define TODAS as etapas possíveis e quais transições são permitidas entre elas.
  • 13 stages: NOVO_LEAD até PERDA
  • Fonte de verdade: LeadStateService (Redis)
  • Transições explícitas com trigger documentado
  • Proteção earlyStages: stages avançados NÃO regridem
  • Fail-open: transição inválida = warning, não bloqueio
  • CollectedData: preenchido incrementalmente
💰 payment.md
Scoring determinístico, thresholds, dedup MP
src/directives/payment.md
O que é: As regras de como o sistema confere se um comprovante de pagamento e verdadeiro. Funciona como uma "pontuação": se o CNPJ da Luzzir aparece no comprovante, ganha 50 pontos. Se o Mercado Pago confirma que o dinheiro caiu, mais 50 pontos. Se a pontuação total chega a 50 ou mais, o pagamento e aprovado automaticamente — sem precisar de humano.
  • PaymentValidator: pontuação por sinais (CNPJ +50, MP +50, recebedor +30)
  • HIGH ≥50 auto-approve, MEDIUM 30-49 human review, LOW/NONE reject
  • Dedup: luzzir:mp:used:{paymentId} (TTL 30d)
  • Rollback: flag paymentValidator.primary
🛡️ guardian.md
4 violações criticas + revisão LLM + safety net
src/directives/guardian.md
O que é: O "fiscal de qualidade" que revisa TODA mensagem antes de enviar ao lead. Imagina um supervisor que lê cada mensagem antes de apertar "enviar": ele verifica se a IA não está confirmando um pagamento que não existe, ou enviando chave PIX para quem não pediu. Se encontrar algo errado, bloqueia a mensagem e avisa os donos.
  • 4 regras determinísticas (PAYMENT_NO_EVIDENCE, PIX_NO_CONTEXT, TRACKING_NO_ORDER, DATA_NOT_IN_HISTORY)
  • Revisão LLM: Planner plan vs Operator output
  • Safety net: >5% blocked/hora → auto-disable enforce
  • Fallback: 2 tentativas, depois envia como está (nunca silencia)
🛒 sales_flow.md
Funil completo: Abertura → Oferta → Reserva → Pagamento → Pedido
src/directives/sales_flow.md
O que é: O "roteiro de venda" completo, do primeiro contato até o pedido no Shopify. Define exatamente o que a Luisa deve fazer em cada momento: quando mandar fotos do produto, quando perguntar a forma de pagamento, quando enviar a chave PIX, é como fazer follow-up se o lead sumiu. E o script que uma vendedora seguiria passó a passo.
  • 7 etapas detalhadas com triggers e ações
  • Follow-up: FU1 (15min) até FU7 (16 dias → PERDA)
  • Acoes estruturadas: ENVIAR_OFERTA, RESERVAR, GERAR_BOLETO, CRIAR_PEDIDO
  • resolveConflicts: VIDEO > ENCERRAR > CRIAR_PEDIDO > BUSCAR_PRODUTOS
Camada 2

Orchestration (IA + Routing)

Roteamento de mensagens, geração de resposta, revisão

O orquestrador fino (webhookService.ts, 480 linhas) coordena 6 handlers especializados. A IA (Gemini) participa apenas na geração de texto — todas as decisões críticas são código.

🔀 webhookService Orchestrator
Orquestrador fino — coordena handlers na ordem certa
src/services/webhookService.ts · 480 linhas
O que é: O "maestro da orquestra". Ele não toca nenhum instrumento — ele coordena. Quando uma mensagem chega, o webhookService decide a ORDEM em que as coisas acontecem: primeiro verifica se pode responder, depois junta mensagens, depois gera resposta, depois extrai ações, depois executa. Cada passó é feito por um handler especializado. O webhookService só diz "agora você" para cada um na hora certa.
  • handleZapiMessage(): entry point principal
  • Fluxo: routeMessage → businessHours → buffer30s → paymentCheck → generateAndReview → parseActions → resolveConflicts → execute
  • detectPaymentSent(): função pura centralizada para detectar pagamento no texto
  • Transições pos-envio: RESERVADO, AGUARDANDO_PAGAMENTO, REAGENDADO
🧠 replyGenerator Pipeline IA
Planner → Operator → Guardian
src/handlers/replyGenerator.ts · 181 linhas
O que é: A "linha de montagem" da resposta. Funciona em 3 etapas como numa fábrica: (1) o Planner le a mensagem e cria um PLANO ("o lead quer comprar, oferecer o kit"), (2) o Operator escreve a mensagem seguindo esse plano, (3) o Guardian confere se a mensagem está correta antes de enviar. Se o Guardian reprova, o Operator reescreve. E como ter um estrategista, um redator e um revisor trabalhando juntos em cada mensagem.
  • Planner (Gemini Flash, temp 0.1): classifica intencao + define plano
  • Operator (Gemini Flash, temp 0.7): gera resposta JSON guiada pelo plano
  • Guardian: revisa critico (código) + revisa LLM
  • Retorna shouldSilence com silenceReason: planner_no_respond, ai_error, nao_responder, guardian_silenced
📝 aiService Gemini
Prompt V2 dinâmico por stage com 3 niveis de fallback
src/services/aiService.ts · ~800 linhas
O que é: O "cérebro linguístico" — é quem realmente conversa com a Gemini (a IA do Google). Monta as instruções certas dependendo da etapa do lead: se e um lead novo, manda instruções de abertura. Se já está negociando, manda instruções de fechamento. Se a instrução nova falhar, tem 3 planos B: tenta com o prompt antigo, tenta de novo, é como último recursó usa o formato legado de 700 linhas que já funcionou antes.
  • Flag prompt.v2: true = 150 linhas dinâmico, false = 700 linhas legacy
  • buildSystemPrompt(stage): PERSONA + CONTEXT_BY_STAGE + CORE_RULES + ACTIONS
  • Fallback 1: buildSystemPrompt erro → legacy
  • Fallback 2: Gemini falha com V2 → retry com legacy
  • Fallback 3: resposta vazia → retry com legacy
  • Stage lookup via getStateByPhone()
Camada 3

Execution (Código Determinístico)

Validação, staté machine, pagamento, pedidos — tudo código puro

Nenhuma decisão crítica depende de LLM. Pagamento é validado por score, stage é transitado por triggers explícitos, pedidos são criados por código com dados verificados.

🔄 LeadStateService Staté Machine
13 stages, transições explícitas, CollectedData
src/v2/services/leadStateService.ts · ~300 linhas
O que é: O "cartório" do sistema — registra oficialmente em que etapa cada lead esta. Imagine uma ficha que acompanha o lead durante toda a jornada: quando ele chega, a ficha marca "NOVO_LEAD". Quando começa a conversar, marca "EM_CONVERSA". Quando paga, marca "PAGAMENTO_CONFIRMADO". Essa ficha fica salva no Redis e é a ÚNICA fonte de verdade sobre o estado do lead. Ninguém adivinha — a ficha diz.
  • Redis: luzzir:state:{leadId} + phone index
  • transition(leadId, newStage, trigger): fail-open com logging
  • markAsAguardandoPagamento(): entry point único para pagamento
  • mergeExtractedData(): no-overwrite para campos identidade
  • earlyStages check: stages avançados NÃO regridem
💳 PaymentValidator Pure PR #17PR #16PR #15
Score-based, 0 LLM, thresholds fixos
src/services/paymentValidator.ts · 230 linhas
O que é: O "caixa do banco" que confere comprovantes. Funciona por pontuação fixa — sem IA, sem achismo. Se o CNPJ da Luzzir aparece no comprovante: +50 pontos. Se o Mercado Pago confirma que o dinheiro caiu: +50 pontos. Passou de 50? Pagamento aprovado automaticamente. Não passou? Avisa os donos para conferir manualmente. E como uma balança: coloca as evidências de um lado e se pesar o suficiente, aprova.
  • CNPJ match: +50pts (decisivo)
  • Recebedor "Lu Basic"/"Luzzir": +30pts
  • MP confirmou: +50pts (decisivo)
  • ≥50 = HIGH (auto-approve), 30-49 = MEDIUM (review), <30 = reject
  • Rollback: paymentValidator.primary = false → regex legacy
🛡️ Guardian Enforce
4 regras determinísticas + safety net automatico
src/v2/services/guardian.ts · ~380 linhas
O que é: O "segurança na porta" que impede erros graves ANTES de chegar ao lead. São 4 regras fixas no código (não IA): se a Luisa tenta confirmar um pagamento que não existe, BLOQUEIA. Se tenta enviar chave PIX para quem nunca pediu, BLOQUEIA. Se o Guardian bloqueou muitas mensagens na última hora (mais de 5%), ele se desativa sozinho para não travar o sistema — é como um disjuntor que desarma automaticamente.
  • Critical check: código puro, ANTES do LLM
  • PAYMENT_NO_EVIDENCE, PIX_NO_CONTEXT, TRACKING_NO_ORDER, DATA_NOT_IN_HISTORY
  • Safety net: >5% blocked/hora → auto-disable
  • Enforce = true: bloqueia + notifica owners + escala
📦 dataExtractor Pure
Extrai CPF, email, CEP, endereco de cada mensagem
src/services/dataExtractor.ts · 155 linhas
O que é: O "secretario" que vai anotando tudo que o lead informa ao longo da conversa. Quando o lead manda "Meu CPF e 123.456.789-00", o extrator anota. Quando manda "Rua das Flores, 42, CEP 30100-000", anota tambem. Vai construindo aos poucos uma ficha completa com nome, CPF, email, endereco — tudo que precisa para criar o pedido no Shopify. E importante: dados de identidade (CPF, nome) nunca são sobrescritos — o primeiro que chega fica.
  • extractFromMessage(): CPF, email, ZIP, rua, numero, complemento, bairro, cidade, UF, metodo pagamento
  • extractFromVisionFields(): cpf_pagador, pagador
  • Validação: isValidCpf, isValidEmail, isValidZip, isValidUF
  • Merge com no-overwrite para campos de identidade
3
Fluxo Principal — Lead Envia MensagemPR #5PR #4PR #19
Z-API Webhook
zapiWebhook.ts
messageRouter
Gatekeeping + Save
Buffer 30s
Acumula msgs
paymentCheck
detectPaymentSent
replyGenerator
Planner→Operator→Guardian
actionParser
parse + resolve
actionExecutor
Side effects
WhatsApp
Z-API send
Pra que serve: Esse diagrama mostra o caminho COMPLETO que uma mensagem percorre desde o momento que o lead manda no WhatsApp até a resposta chegar de volta. Sao 8 etapas em sequencia, como uma linha de montagem. Cada caixa e um "funcionario" especializado que faz sua parte e passa pro proximo. Se qualquer etapa decidir "nao responder" (lead bloqueado, IA pausada, mensagem só emoji), o fluxo para ali é a mensagem e apenas salva.
Fluxo detalhado: Webhook recebe → messageRouter valida (grupo? bloqueado? pos-venda? IA pausada? legado?) → salva no Redis SEMPRE → buffer 30s junta msgs → paymentTextChecker detecta mencao a pagamento → replyGenerator gera resposta via pipeline Planner/Operator/Guardian → actionParser extrai ações do JSON + resolveConflicts → actionExecutor executa side effects (media, Shopify, Kommo, reagendar) → stripAllTags → envia via Z-API → salva resposta no Redis

Fluxo de Imagem (comprovante)

Pra que serve: Quando o lead manda uma FOTO (comprovante de pagamento, imagem casual, PDF), o fluxo e diferente do texto. A imagem e baixada rapidamente (a URL do WhatsApp expira), salva no Google Drive como backup, e analisada pela Gemini Vision que "olha" a foto como um humano faria. Depois, o PaymentValidator da uma pontuação é o Mercado Pago faz uma dupla verificação. Se a pontuação for alta o suficiente, o pagamento e aprovado automaticamente.
Imagem recebida
messageRouter
Download + Drive
imageHandler
Gemini Vision
OCR + campos
PaymentValidator
Score-based
MP Cross-check
Dupla validacao
Decisao
HIGH/MEDIUM/LOW
4
Os 6 Handlers
webhookService 1569 → 480 linhas + 6 modulos
Antes: webhookService.ts era um monolito de 1569 linhas que fazia TUDO: roteamento, IA, imagens, ações, pagamento, envio.
Agora: 480 linhas de orquestracao fina + 6 handlers especializados em src/handlers/. Cada um faz UMA coisa bem feita.
🚦 messageRouter 410 linhas PR #19PR #5PR #4
Gatekeeping: quem pode entrar, o que fazer com cada msg
src/handlers/messageRouter.ts
O que é: O "porteiro" do sistema. Quando chega uma mensagem, ele é o primeiro a ver. Verifica: é de grupo? Ignora. Número bloqueado? Ignora. É cliente que já comprou? Redireciona. IA está pausada? Salva mas não responde. Só depois de todas essas verificações, a mensagem segue adiante para ser processada. Mesmo que não responda, ele SEMPRE salva a mensagem no histórico — nada se perde.
  • Filtra: grupos, LID, numeros bloqueados
  • Salva: TODA mensagem no Redis (independente de responder)
  • Verifica: comando "reset/bloquear", Pos-Venda, IA pausada, audio, Kommo lookup, legado
  • Imagens: delega para imageHandler + V2 DecisionEngine + Guardian
  • Transições: text_message_received → EM_CONVERSA (com earlyStages check)
  • Extrai: CollectedData de cada mensagem via dataExtractor
🖼️ imageHandler ~450 linhas PR #15
Download, Vision, PaymentValidator, MP cross-check
src/handlers/imageHandler.ts
O que é: O "analista de comprovantes". Quando o lead manda uma foto ou PDF, este handler: (1) baixa a imagem rapidamente (a URL do WhatsApp expira em poucas horas), (2) salva uma cópia no Google Drive como backup permanente, (3) pede pra Gemini Vision "olhar" a foto e extrair dados (valor, data, quem pagou, quem recebeu), (4) passa esses dados para o PaymentValidator dar a pontuação, (5) cruza com o Mercado Pago para dupla verificação. E como ter um assistente que confere cada comprovante recebido.
  • downloadAndAnalyzeImage(): Download + Drive upload + Gemini Vision + PaymentValidator
  • verifyPaymentForImage(): MP cross-check + markPaymentUsed
  • decideImageInstruction(): ASYNC, flag-controlled com fallback legacy
  • Extrai CPF/nome do Vision → CollectedData
  • Transições: comprovante_received → COMPROVANTE_RECEBIDO, payment_confirmed → PAGAMENTO_CONFIRMADO
🧠 replyGenerator 181 linhas PR #18
Pipeline de geracao: Planner → Operator → Guardian
src/handlers/replyGenerator.ts
O que é: A "fábrica de respostas" com 3 funcionarios em sequencia. Primeiro, o Planner (estrategista) analisa o que o lead disse e cria um plano: "o lead quer saber o preco, devemos enviar a oferta". Depois, o Operator (redator) escreve a mensagem real seguindo esse plano. Por último, o Guardian (revisor) confere se está tudo certo antes de enviar. Se algo não ficou bom, o Operator reescreve. E tambem pode decidir ficar em silêncio — por exemplo, se o lead só mandou um emoji.
  • generateAndReview(): orquestra o pipeline completo
  • Planner: classifica intencao + shouldRespond
  • Operator: gera JSON com message + actions[]
  • Guardian: revisa violações criticas + LLM review
  • Retorna: mensagem final OU shouldSilence com motivo
🏷️ actionParser 235 linhas PURE PR #12PR #11PR #9PR #10
Extrai ações, resolve conflitos, detecta media
src/handlers/actionParser.ts
O que é: O "interprete" da resposta da IA. A Gemini não só escreve a mensagem — ela tambem pode sugerir ações como "enviar oferta", "criar pedido", "reagendar". O actionParser le a resposta da IA e extrai TODAS essas ações. Depois, resolve conflitos: se a IA disse pra criar pedido E encerrar ao mesmo tempo (impossivel), ele decide quem ganha. Tambem remove TODAS as tags internas da mensagem — o lead NUNCA ve coisas como [CRIAR_PEDIDO] ou [REAGENDAR:7]. E 100% código puro, sem IA.
  • parseActions(): extrai todas as ações do JSON/texto
  • resolveConflicts(): VIDEO > ENCERRAR > CRIAR_PEDIDO > BUSCAR_PRODUTOS
  • stripAllTags(): barreira final de seguranca
  • detectMediaType(): oferta/kit/reserva (actions[] priority, keyword fallback)
  • detectReagendarFallback(): linguagem de agendamento
  • 100% funcoes puras — zero side effects
actionExecutor ~360 linhas PR #14PR #13
Executa side effects: media, Shopify, Kommo, block
src/handlers/actionExecutor.ts
O que é: O "faz-tudo" que executa as ações decididas. Quando o actionParser diz "enviar oferta", o executor manda as 3 fotos do kit + áudio da Luisa. Quando diz "criar pedido", ele cria o pedido no Shopify com os dados do lead. Quando diz "encerrar", envia mensagem de despedida + bloqueia o número + marca como PERDA. E o único que realmente "mexe nas coisas" — os outros apenas decidem O QUE fazer, este faz DE VERDADE.
  • sendVideoEarlyReturn(): video tem prioridade maxima
  • executeCreateOrder(): CollectedData-first + regex fallback → Shopify
  • executeEncerrar(): closing msg + Redis block + PERDA
  • executeBoleto(): extrai dados + gera boleto MP
  • sendMediaForReply(): imagens + audios da Luisa
  • Transições: shopify_order_created → PEDIDO_CRIADO, encerrar → PERDA
💬 paymentTextChecker 87 linhas
Detecta mencao a pagamento no texto do lead
src/handlers/paymentTextChecker.ts
O que é: O "ouvido atento" para mencoes de pagamento. Quando o lead escreve "ja fiz o pix", "transferi", "ja paguei" — este handler detecta a intencao e vai direto no Mercado Pago conferir se o dinheiro realmente caiu. Se confirma, passa essa informacao para a IA responder de forma adequada ("Recebi seu pagamento!"). E o menor dos 6 handlers (87 linhas) mas muito importante: sem ele, o lead ficaria esperando confirmacao mesmo já tendo pago.
  • checkPaymentMention(): keywords → MP verify → markPaymentUsed
  • "ja paguei", "fiz o pix", "transferi" → busca no MP
  • Se confirma: gera paymentContext string para a IA
  • Transicao via markAsAguardandoPagamento()
5
LeadStateService — Máquina de EstadosPR #15PR #14
13 stages, Redis, transições explícitas
O que é: Imagine um tabuleiro de jogo onde cada lead é uma pecinha. A pecinha só pode andar para frente nas casas permitidas: NOVO_LEAD → EM_CONVERSA → RESERVADO → AGUARDANDO_PAGAMENTO... Não pode pular casas nem voltar (exceto em casos especiais, como quando um lead que desistiu volta a escrever). O LeadStateService é quem controla esse tabuleiro — sabe exatamente em que casa cada lead esta, e só permite movimentos válidos.

Fonte de verdade: Redis luzzir:state:{leadId} + phone index.
Regra: Transições inválidas são logadas como warning mas PERMITIDAS (fail-open). O sistema nunca bloqueia por causa de stage.

Pre-Venda

NOVO_LEAD
AGUARDANDO_ABERTURA
EM_CONVERSA
RESERVADO

Pagamento

AGUARDANDO_PAGAMENTO
COMPROVANTE_RECEBIDO
PAGAMENTO_CONFIRMADO

Pos-Venda

PEDIDO_CRIADO
PEDIDO_ENVIADO
PEDIDO_ENTREGUE

Terminal (pode reabrir)

REAGENDADO
ENCERRADO
PERDA

Transições Principais

NOVO_LEAD EM_CONVERSA RESERVADO AGU_PAGAMENTO COMPROV_RECEB PAG_CONFIRMADO PEDIDO_CRIADO PEDIDO_ENVIADO
earlyStages check: Texto recebido só transita para EM_CONVERSA se stage atual é NOVO_LEAD, AGUARDANDO_ABERTURA, REAGENDADO, ENCERRADO ou PERDA. Stages avançados (AGUARDANDO_PAGAMENTO, PEDIDO_CRIADO, etc.) NÃO regridem.
Recovery: PERDA → EM_CONVERSA e ENCERRADO → EM_CONVERSA (quando lead volta a escrever).

CollectedData (incremental)

📋 Campos
fullName cpf email phone address.street address.number address.complement address.neighborhood address.city address.state address.zip paymentMethod product
🔒 Regras
Identidade (fullName, cpf, email): NÃO sobrescreve
Operacional (paymentMethod, product): sobrescreve
Fontes: mensagem texto, Vision campos, CRIAR_PEDIDO
6
PaymentValidator — Sistema de ScoringPR #17PR #16PR #15
Determinístico, 0 LLM, rollback instantâneo
O que é: O sistema que decide se um comprovante de pagamento e válido. Funciona como uma prova de escola com pontuação: cada evidencia vale pontos. O CNPJ da Luzzir no comprovante vale 50 pontos. O Mercado Pago confirmando que o dinheiro caiu vale mais 50. Se a "nota" final chega a 50 ou mais, o pagamento e aprovado automaticamente é o pedido começa a ser processado. Se a nota for baixa, os donos são avisados para conferir manualmente. A IA NUNCA confirma pagamento sozinha — quem decide e esse sistema de pontuação, que e código puro sem inteligencia artificial.

Tabela de Scoring

SinalPontosTipo
CNPJ = 51763279000104+50Decisivo
Recebedor contem "Lu Basic" ou "Luzzir"+30Forte
Mercado Pago confirmou pagamento+50Decisivo
Tipo válido (Pix/Boleto/Transferencia/Cartao)+5Fraco
Valor entre R$1 e R$2000+5Fraco
Data dos últimos 30 dias+5Fraco
Valor baté com expectedAmount+10Moderado
"Nao e comprovante" detectado-20Penalidade

Thresholds de Decisao

ScoreConfidenceAprovadoAcao
≥50HIGHSimAuto-aprovado. markLeadAsWon + flagPendingOrder
30-49MEDIUMNaoOwners notificados. IA diz "estou verificando"
10-29LOWNaoOwners notificados. IA pede comprovante correto
<10NONENaoImagem casual ou nao-comprovante
7
Guardian — Fiscal de Qualidade
4 violações críticas (código) + revisão LLM
O que é: O Guardian é como um supervisor que le CADA mensagem da Luisa antes de apertar "enviar". Tem dois niveis: primeiro, 4 regras fixas no código (sem IA) verificam erros graves — como confirmar pagamento que não existe ou enviar chave PIX para quem não pediu. Se passar nesse teste, uma segunda verificação por IA compara a mensagem com o plano original. Se a mensagem falhar na revisao, o Operator reescreve. Se falhar de novo, envia assim mesmo — porque e melhor mandar uma mensagem imperfeita do que deixar o lead sem resposta.

Violações Críticas (determinísticas — if/else, NÃO LLM)

PAYMENT_NO_EVIDENCE
IA confirma pagamento ("Parabéns pela escolha") mas histórico NÃO tem evidência de pagamento confirmado
PIX_NO_CONTEXT
IA envia chave PIX mas lead nunca mencionou "pix", "pagar", "quero", "reserv"
TRACKING_NO_ORDER
IA menciona envio/rastreio mas histórico NÃO tem "[Pedido Shopify criado:]"
DATA_NOT_IN_HISTORY
IA diz "anotei endereço/dados" mas histórico NÃO tem endereço/CEP

Pipeline de Revisão

Operator gera msg Critical check (código) LLM review vs plano Aprovado
Se crítico bloqueado → mensagem NÃO enviada + owners notificados + lead escalado
Se LLM reprova → regenera 1x → se reprova de novo → envia como está (NUNCA silencia)
Safety net: >5% blocked/hora (min 10 msgs) → guardian.enforce desativado automaticamente
8
Prompt V2 — Dinâmico por Stage
~150 linhas vs 700 legacy · flag-controlled
O que é: O "manual de instruções" que o sistema envia junto com cada conversa para a Gemini. Antes, era um documento único de 700 linhas com TUDO — regras pra lead novo, pra quem já pagou, pra quem sumiu. Agora, o manual e montado sob medida: se o lead acabou de chegar, manda instruções de abertura. Se já está negociando, manda instruções de fechamento. Resultado: instruções mais curtas (~150 linhas), mais focadas, é a IA erra menos porque não precisa ignorar 500 linhas de regras que não se aplicam.
PERSONA (~35 linhas) + CONTEXTO_POR_STAGE (~20 linhas) + CORE_RULES (~25 linhas) + ACTIONS + JSON (~30 linhas) = ~150 linhas
👤 PERSONA
Tom: closer de vendas, elegante, simpatica, focada em conversao
O que é: A "personalidade" da Luisa. Define como ela fala: elegante mas acessível, simpática mas focada em vender, usa emojis com moderação, sempre chama pelo primeiro nome. Toda mensagem deve terminar com uma pergunta que empurra o lead pro próximo passó — nunca com "alguma dúvida?" que dá margem pra encerrar.
  • Estilo: 3 parágrafos, 1 pergunta que avança, micro-CTA obrigatório
  • Emojis com moderação: 🥰 🤍 ❤️ 😊 ✨
  • Primeiro nome apenas (Angela, não Angela Maria)
  • NUNCA: "Alguma dúvida?", "Fico à disposição", "O que achou?"
🎯 CONTEXTO POR STAGE
Injetado dinamicamente por buildSystemPrompt(stage)
O que é: A "pauta da reunião" que muda dependendo do momento da venda. Se o lead acabou de chegar, a IA recebe instruções de abertura ("pergunte se usa pérolas"). Se já está negociando, recebe instruções de fechamento ("avance direto pra reserva"). Se já pagou, recebe instruções de coleta de dados ("peça endereço para envio"). Cada etapa tem suas próprias regras — assim a IA não confunde o que deve fazer.
  • NOVO_LEAD: "Eii [Nome]!! Você já usa pérolas?"
  • EM_CONVERSA: Foco em fechar. Progressão obrigatória. Gatilhos de fechamento.
  • RESERVADO: Perguntar pagamento DIRETAMENTE
  • AGUARDANDO_PAGAMENTO: Aguardar comprovante. NÃO engajamento.
  • COMPROVANTE_RECEBIDO: Aguardar verificação. PROIBIDO perguntas.
  • PAGAMENTO_CONFIRMADO: Coletar dados de entrega.
  • REAGENDADO: Retomar com leveza mas INTENÇÃO de fechar.
📦 Templates (templates.ts)
Preços, links, textos fixos — zero hardcode no prompt
O que é: A "tabela de preços e textos prontos" do sistema. Antes, os preços e links de pagamento ficavam soltos dentro do prompt de 700 linhas — se alguém mudasse o preço no prompt errado, a IA mandava valor errado pro lead. Agora, tudo está centralizado num arquivo só: preços, links do Mercado Pago, textos de abertura, oferta, PIX, cartão. Se o preço mudar, altera num lugar e vale pra todo o sistema.
  • Kit: R$159 (de R$265), variant 43381813641304
  • Choker: R$119 | Brinco: R$99
  • Parcelas: 2x R$86,18 até 12x R$16,18
  • PIX CNPJ: 51763279000104
  • Cartão: mpago.la/2pySbei
  • Textos: abertura, oferta, pós-oferta, PIX, cartão, closing, engagement
Fallback em 3 niveis: buildSystemPrompt erro → legacy | Gemini falha com V2 → retry legacy | resposta vazia → retry legacy.
Flag: prompt.v2 = true ativa V2. false = prompt monolítico de 700 linhas.
9
Feature Flags — Rollback Instantâneo
Redis luzzir:v2:flags · cache 30s · efeito <1min
O que é: Imagine um painel com 9 interruptores de luz. Cada interruptor liga ou desliga uma funcionalidade do sistema. Se o novo validador de pagamento está dando problema, basta desligar o interruptor "paymentValidator.primary" é o sistema volta a usar o método antigo instantaneamente — sem precisar mexer no código, sem reiniciar o servidor. É como ter um "botão de desfazer" para cada parte nova do sistema. As flags ficam salvas no Redis e são consultadas a cada 30 segundos, então qualquer mudança faz efeito em menos de 1 minuto.
prompt.v2 Ativa prompt dinâmico por stage (~150 linhas). false = legacy 700 linhas.
guardian.enabled Ativa revisão LLM das respostas do Operator.
guardian.enforce Bloqueia mensagens com violações críticas. false = apenas log.
paymentValidator.primary Validador por pontuação. false = regex "VALIDO: SIM" legado.
decisionEngine.enforce.create_order Valida dados completos antes de criar pedido Shopify.
decisionEngine.enforce.confirm_payment Exige prova real antes de confirmar pagamento.
agents.pipeline.enabled Pipeline de 3 agentes (Planner/Operator/Guardian).
orchestrator.enabled V2 orchestrator pathway.
leadState.shadow LeadStateService em modo shadow (log-only).
10
Crons e ProativoPR #8PR #6PR #3
8 processos automáticos
O que é: São 8 "despertadores" que tocam automaticamente em intervalos fixos, sem precisar de ninguém. É como ter 8 funcionários que trabalham 24 horas: um verifica se tem lead pra fazer follow-up (a cada 5 min), outro sincroniza a planilha (a cada 1 min), outro verifica se algum pedido foi enviado pelos Correios (a cada 30 min). Mesmo que ninguém esteja olhando, o sistema continua trabalhando sozinho.
Cada 5 min
Proativo (FU)
Lê planilha, detecta tarefas vencidas, envia FU com proteções (pagou? sensível? ativo? bloqueado?)
Cada 1 min
Sheet Sync
Processa fila luzzir:sheet:queue, max 10/ciclo
Cada 1 min
Kommo Sync
Processa fila luzzir:kommo:sync:queue, max 10/ciclo
Cada 5 min
Auto Order
Busca luzzir:pedido:pendente:{phone}, extrai dados, cria Shopify
Cada 30 min
Fulfillment
Verifica pedidos Shopify despachados, envia rastreio ao lead
Cada 30 min
Health Check
Detecta comprovantes stuck (>24h) e leads inativos (>16d)
Cada 2 min
Payment Safety
Monitora safety net de pagamento
07:00 BRT
Learnings
Backup regras + análise 24h + gera sugestões IA

Timeline Follow-Up

FU115min
"Nome?"
FU24h
Áudio curiosidade
FU31 dia
Áudio urgência
FU42 dias
Áudio compromisso
FU53 dias
Mudo + texto
FU65 dias
Última chance
FU75 dias
PERDA
Proteções: já pagou? (histórico + pipeline Pós-Venda) | sensível? (hospital, luto, doença) | conversa ativa? (<2h) | REAGENDAR? | bloqueado? (Redis + ambas variantes com/sem 9)
11
Estrutura de Diretórios
src/ handlers/ — 6 handlers especializados (pos-refactor) messageRouter.ts 410 linhas — gatekeeping, roteamento, save Redis imageHandler.ts ~450 linhas — download, Vision, PaymentValidator, MP replyGenerator.ts 181 linhas — pipeline Planner→Operator→Guardian actionParser.ts 235 linhas — parse, resolveConflicts, stripAllTags (PURE) actionExecutor.ts ~360 linhas — Shopify, Kommo, media, block, boleto paymentTextChecker.ts 87 linhas — "ja paguei" → MP verify services/ webhookService.ts 480 linhas — orquestrador fino (era 1569) aiService.ts ~800 linhas — Gemini, prompt V2/legacy, fallbacks promptBuilder.ts ~160 linhas — buildSystemPrompt(stage) paymentValidator.ts 230 linhas — score-based, 0 LLM (PURE) dataExtractor.ts 155 linhas — CPF, email, ZIP, endereco (PURE) stateHealthCheck.ts 130 linhas — stuck comprovantes, leads inativos autoOrderService.ts ~210 linhas — cron 5min pedido automatico proactiveService.ts — FU engine, proteções, planilha shopifyFulfillmentService.ts — rastreio automatico v2/ services/ leadStateService.ts ~300 linhas — staté machine Redis, transições guardian.ts ~380 linhas — 4 violações criticas + LLM review types/ state.ts — 13 LeadStage enum, VALID_TRANSITIONS, CollectedData config/ featureFlags.ts — 9+ flags, cache 30s, Redis config/ templates.ts 96 linhas — precos, links, textos fixos directives/ — SOPs em Markdown (5 documentos) ai_behavior.md — persona, tom, progressao, formato lead_states.md — 13 stages, transições, triggers payment.md — scoring, thresholds, dedup guardian.md — 4 violações, pipeline revisao, safety net sales_flow.md — funil completo, FU, ações
12
Antes vs Depois
O que mudou na refatoração · Dashboard: PR #1PR #2PR #4PR #19

Antes (Monolito)

  • webhookService.ts: 1569 linhas fazendo tudo
  • Stage: inferido por string matching no histórico
  • Pagamento: LLM decidia se era válido (regex "VALIDO: SIM")
  • Prompt: monolítico 700 linhas, igual pra todos
  • Guardian: só LLM review, sem enforcement
  • Ações: parseadas por regex inline no webhook
  • Dados lead: extraídos na hora do pedido (falha frequente)
  • Rollback: nenhum — fix + deploy + reza
  • Conflitos: VIDEO e ENCERRAR ao mesmo tempo
  • Templates: hardcoded no prompt (precos errados)

Depois (Modular)

  • webhookService.ts: 480 linhas + 6 handlers
  • Stage: LeadStateService Redis com transições explícitas
  • Pagamento: PaymentValidator score-based (CNPJ +50, MP +50)
  • Prompt: V2 ~150 linhas dinâmico por stage
  • Guardian: 4 regras determinísticas + LLM + safety net
  • Ações: actionParser puro + resolveConflicts + actionExecutor
  • Dados lead: CollectedData incremental (cada msg)
  • Rollback: 9 feature flags Redis, efeito <1min
  • Conflitos: resolveConflicts com prioridades claras
  • Templates: templates.ts centralizado (96 linhas)
Redução total: webhookService 1569 → 480 linhas (-69%). Prompt 700 → 150 linhas (-78%). Pagamento de LLM → score puro. Stage de inferência → staté machine. 9 flags de rollback onde antes havia zero.