Ondas 4 e 5, que fecham o conserto: o controle da tela passa a valer, o sistema paralelo morto sai, e um bloqueio deixa de abandonar o lead. `DESKCOMM_GOV_INVARIANTS_EDIT=1` — dois invariantes MODIFICADOS, e a razão: `vocabulario-banco-x-typescript` ganhou o par `ModoDeOrcamento` (coluna nova com CHECK precisa de par no TypeScript, senão o job `invariants` reprova), e `orcamento-apos-backfill` acompanhou a mudança do piso. O invariante NOVO (`orcamento-nasce-desarmado`) não precisa da flag. ## Os três achados que valeram mais que a feature **1. A escolta era inalcançável no caso dominante.** `classifyStage` roda em todo turno e estourava ANTES da escolta — que, portanto, nunca protegia o caminho normal. Movida para `runAgentTurn`, que envolve o turno inteiro. A guarda antiga contava `runModelCall(` no texto e era cega para helpers; agora conta call sites e a fronteira dos auxiliares. **2. A escada era contornável pela REST do Supabase** (migration 0160). O PATCH exige `off → avisar → bloquear`, mas `ai_budgets` aceitava escrita direta de `authenticated` — qualquer cliente com a anon key pulava a escada e armava bloqueio imediato. `revoke insert/update/delete`, SELECT fica. **3. O texto mandava clicar num botão que não existe.** A mensagem que o cliente lê quando a IA para dizia "Retomar atendimento automático"; o componente renderiza **"Devolver ao automático"**. Corrigido em 7 arquivos, e a guarda nova **lê o rótulo do componente** em vez de guardar uma cópia — cópia de rótulo é a próxima mentira esperando envelhecer. ## O dropdown decorativo saiu "Ação ao atingir 100%" oferecia "Pausar" vs "Desabilitar" e o produto entregava sempre a mesma coisa. Era o defeito que este trabalho existe para matar, sobrevivendo dentro do conserto — um juiz reprovou um desenho inteiro por mantê-lo. Ou entrega os dois futuros, ou sai. Saiu. ## O lead não fica mais no vácuo Quando o orçamento barra, o turno vai para `performHumanHandoff` com contexto, e o job é **cancelado** (`cancelJob`), não falhado com retry: repetir uma chamada que o teto recusa é gastar de novo para receber a mesma recusa. O caminho legado ganhou o mesmo veto — e depois dos gates que reconhecem "quero falar com um atendente", não antes, senão pedir humano viraria silêncio. ## Sabotagem: 10 previsões, 10 acertos escolta fora do turno 3×3 · piso só para bloquear 3×3 · não zerar a carência 2×2 · veto antes dos gates 1×1 · sem handoff 1×1 · ressalva de medição sumida 1×1 · rótulo do período revertido 2×2 · flag de gasto incompleto fixa 1×1 · janela do mês removida 1×1 · botão renomeado 3×3. ## Uma discordância mantida, com evidência O KPI de plataforma fica na coluna acumulada. A alternativa barata seria um `group by` inline — a segunda régua de gasto que `orcamento-uma-regua-de-gasto` existe para impedir, e o gate provou o ponto reprovando o próprio comentário do implementador quando ele escreveu a query em PROSA. Mitigado: nunca `critical`, rótulo "acumulado", divergência escrita no arquivo e link para a tela que tem a régua certa. ## Bateria typecheck 0 · lint 0 erros · lint:channels 0 · test:shell 0 · build 0 · test:unit **3347 passam**, 1 falha — a baseline do `.env.local` deste worktree, que não cita orçamento, budget, handoff nem money. ## NÃO MEDIDO, declarado - `tests/invariants/orcamento-nasce-desarmado.test.ts` é **novo e nunca foi executado** (15 casos, e é a primeira vez que `SQL_ORCAMENTO` roda contra Postgres em todo o repo). É o maior risco de CI vermelho desta entrega, e está escrito aqui porque dívida declarada não é defeito — dívida presumida é. - O `revoke` da 0160 não foi provado contra PostgREST vivo: o achado veio de leitura de grants. - **DoD 12 (prova pela tela): NÃO MEDIDO.** Radio, kill switch e badge estão provados por unidade em jsdom e por `build`, não por browser em ambiente fresco estilo VPS. - `test:db`, `e2e` e `build-and-size`: quem prova é o CI. Nota de release em `docs/release/teto-de-orcamento.md`; mapa vivo em `docs/architecture/teto-de-orcamento.architecture.json` (26 nós, 43 arestas). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TCiffR3ugjQbxsfceQE2GB
25 KiB
Changelog
Todas as mudanças relevantes deste projeto são documentadas aqui.
O formato segue Keep a Changelog e o versionamento segue SemVer.
Se você roda o DeskcommCRM numa VPS, leia a seção da versão para a qual está atualizando antes de rodar bash update.sh. Mudanças que exigem ação manual aparecem sob ⚠️ Requer atenção.
Não lançado
Adicionado
-
O agente de atualização passa a fixar sozinho a versão que ficou solta, em até 5 minutos, sem você fazer nada — ele grava a versão que já está rodando. O que ele nunca faz é mexer numa configuração que você escreveu à mão: se você escolheu acompanhar um canal de propósito, ele respeita e só avisa.
Isso não vale para quem está na 1.3.0 — entrou depois dela. Até a próxima versão sair, a instrução da 1.3.0 continua sendo a única verdadeira: rode o
update.shduas vezes. -
O limite de gasto com IA passa a valer de verdade — e nasce desligado. Até agora a tela de Uso de IA › Orçamento deixava você escrever um limite mensal, mas quem barrava a chamada olhava para outro lugar: nenhuma instalação estava protegida, e a tela dizia que estava. Agora o número que você digita é o número que decide. Para que ligar isso não corte o atendimento de ninguém por engano, a proteção começa desligada em todo mundo e só liga em três passos, na tela: Só acompanhar → Me avisar → Parar a IA no limite. Não dá para pular direto para a parada, e quando você a arma ela só começa a valer 72 horas depois (dá para renunciar a essa espera marcando a caixa). Você não precisa fazer nada — quem não abrir essa tela continua exatamente como está hoje.
-
Quando o limite para a IA, ninguém fica sem resposta. As conversas que estavam sendo atendidas vão para a fila de atendimento humano, com um aviso na Central explicando o que aconteceu. Cada uma volta ao automático pelo botão "Devolver ao automático" no cabeçalho da conversa. Aumentar o limite evita paradas novas, mas não devolve sozinho as conversas que já pararam.
-
Um aviso na Central quando o gasto passa do ponto que você escolheu, antes de qualquer parada — e ele se apaga sozinho quando o gasto volta para baixo do limite ou o mês vira.
Corrigido
- ⚠️ Requer atenção — o valor do orçamento de IA sempre foi em DÓLAR, e a tela dizia real. Quem lia "R$ 50,00" tinha, na verdade, um limite de US$ 50,00 — cerca de cinco vezes maior do que imaginava. Nada mudou no seu gasto nem no seu limite: mudou o que a tela confessa. O rótulo agora diz US$ nas telas de Uso de IA, Execuções, Evolução e nos painéis de administração. Confira o número antes de ligar a parada automática: se você escolheu "50" pensando em reais, o que está armado é cinco vezes isso.
- O gasto exibido era o acumulado desde a instalação, não o do mês. O contador antigo somava tudo e nunca zerava, então numa instalação com alguns meses de uso o card comparava meses de gasto contra um limite mensal. Agora o número é o do mês corrente, e é o mesmo número que decide se a IA para.
- O seletor "Ação ao atingir 100%" saiu da tela. Ele oferecia "Pausar" e "Desabilitar" como se fossem coisas diferentes; não eram — nada no produto os distinguia, e a escolha não tinha efeito nenhum. Quem quiser que a IA pare no limite usa a opção "Parar a IA" da escada nova.
- Os avisos de orçamento apareciam e não sumiam. O alerta de "limite atingido" ficava aceso mesmo depois de o mês virar ou de você aumentar o limite. Agora ele se retrata sozinho.
- No painel de administração, o alerta de orçamento parou de gritar "crítico" sobre um número que não é o do mês. Ele continua avisando, com o rótulo dizendo que o valor é acumulado, e leva direto para a tela de saúde do cliente, que mostra o número real.
[1.3.0] — 2026-08-13
Esta versão mexe em como o sistema chega e se atualiza no seu servidor. Em uso, três coisas mudam para melhor: a instalação deixa de ter uma etapa que podia falhar por falta de memória no meio (o servidor não compila mais nada — tudo vem pronto), fica bem mais rápida, e o agente de IA passa a receber as correções de cada versão. A recomendação de servidor continua exatamente a mesma: o que consome memória é operar o sistema no dia a dia — 7 serviços e cerca de 150 MB por número de WhatsApp conectado —, e isso não mudou nem um pouco.
Corrigido
- O agente de IA nunca recebia atualização. O worker — o processo que faz o agente
atender 24 horas por dia — era compilado dentro do seu servidor no dia da instalação, e
nenhuma atualização o reconstruía. Na prática: você atualizava o CRM, o site mudava, e o
agente continuava rodando exatamente o código do dia em que você instalou, para sempre.
Correções e melhorias do agente não chegavam. Agora ele é uma imagem pronta, publicada
junto com o resto, e o
update.sha traz como traz o app. - Duas instalações "na mesma versão" rodavam código diferente. Uma instalação nova ficava
apontada para o canal
latest, que — apesar do nome — acompanha o desenvolvimento em andamento, não a última versão lançada. Quem instalou em semanas diferentes tinha software diferente, e não havia como dizer qual. Agora o instalador grava o número da versão (ex.:1.2.1), e é essa versão que fica no seu servidor até você decidir atualizar. - O CRM podia não subir por causa de um serviço externo fora do ar. A configuração pedia ao Docker que verificasse o registro de imagens a cada subida; se ele não respondesse, o contêiner não subia — mesmo com a imagem já baixada no seu disco. Agora que o seu servidor fica numa versão fixa, essa verificação deixa de ser feita na sua instalação (quem acompanha um canal móvel continua com ela, que é onde ela serve para alguma coisa).
- O agendador de tarefas dependia da internet para voltar. A cada reinício ele baixava dois programas antes de começar. Sem internet no momento do reboot — justo quando a máquina está se recuperando de alguma coisa —, as tarefas automáticas não voltavam. Agora já vêm dentro da imagem.
- A versão mostrada em
/api/v1/healthera sempre0.1.0, em qualquer instalação. Agora é a versão de verdade. - O WhatsApp (WAHA) e o serviço de limites deixaram de acompanhar automaticamente qualquer versão nova publicada por terceiros. Passam a mudar só quando nós testamos e lançamos.
⚠️ Requer atenção
Se o seu servidor foi instalado antes desta versão, rode o update.sh DUAS vezes.
As duas execuções são necessárias nesta versão. O agente que corrige isso sozinho entrou depois da 1.3.0 (está em Não lançado) — se você está atualizando para a 1.3.0, ele não existe no que você vai instalar. Esta nota já disse o contrário, e a frase teria feito você esperar cinco minutos por algo que nunca ia acontecer. Medido em ensaio numa VPS: a primeira execução traz o agente novo, mas deixa a versão dele "solta" — acompanhando o canal em vez de ficar fixa, como o resto do sistema. Isso faria o agente saltar sozinho para a versão seguinte num reinício futuro, enquanto o resto do servidor continuaria onde está. A segunda execução fixa tudo na mesma versão.
Para saber em que pé você está, sem mexer em nada:
curl -fsSL https://raw.githubusercontent.com/melgarafael/DeskcommCRM/main/hostgator-setup-kit/diagnostico.sh | bash
Ele só lê e explica — não escreve, não reinicia, não atualiza. Se disser que está afetada,
o passo a passo (com como voltar atrás) está em docs/runbooks/remediar-worker-congelado.md.
Fora isso, nada exige ação sua. Um .env antigo continua funcionando: as configurações
novas têm valor padrão e o próprio update.sh as acrescenta.
1.2.1 — 2026-08-12
Versão de segurança. Se você roda o DeskcommCRM numa VPS, atualize.
Um usuário da comunidade auditou o código e mandou um relatório. Parte do que ele apontou já tinha sido corrigida nas versões seguintes à que ele analisou — mas seis problemas estavam de pé, e um deles deixava dados de uma empresa visíveis para outra. Todos foram corrigidos, cada um com um teste automático que impede o problema de voltar.
Corrigido
- Uma empresa conseguia ler a base de conhecimento de outra, e escrever no histórico dela. Duas funções internas aceitavam o identificador da empresa como se fosse confiável, sem conferir se quem pediu era mesmo de lá. O isolamento entre empresas estava de pé em todo o resto — o furo era só nessas duas portas, e elas agora conferem.
- Quem tinha permissão de apenas visualizar conseguia mudar configurações importantes. Um usuário "visualizador" podia reescrever as instruções do agente de IA (o texto que ele fala com o seu cliente), desligar o canal de WhatsApp, mexer no limite de gastos e apagar a chave do provedor de IA — bastava falar direto com o banco de dados, sem passar pelas telas. Agora essas mudanças exigem administrador, como as telas já exigiam.
- A verificação em duas etapas do administrador valia só na tela. Quem tinha a senha de um administrador, mas não o segundo fator, ficava barrado na interface e mesmo assim alcançava as funções sensíveis por fora dela — criar chave de API, convidar gente para a equipe, pedir exportação de dados. Agora o servidor confere o segundo fator em todas elas.
- Link de login podia levar para um site estranho. Um endereço preparado por terceiros fazia você digitar a senha no site certo e, logo depois de entrar, ser jogado para outro lugar — o momento em que se confia mais na próxima tela.
- Envio de arquivo na conversa não conferia permissão. Era a única ação de escrita da conversa sem essa checagem; um usuário "visualizador" podia enviar arquivos de até 50 MB.
- Automação de webhook podia alcançar a rede interna do servidor. A checagem olhava só o texto do endereço; um domínio preparado para apontar "para dentro" passava, e alcançava serviços internos e a área de credenciais do provedor de nuvem. Agora o endereço é resolvido de verdade antes de qualquer envio.
⚠️ Requer atenção
- Administradores vão precisar entrar de novo, com o código do aplicativo. Se você já tem a verificação em duas etapas cadastrada e está com a sessão aberta, as ações de administrador passam a pedir o segundo fator. Sair e entrar novamente resolve. Quem ainda não cadastrou o segundo fator não é afetado e continua conseguindo cadastrá-lo normalmente.
- Usuários "visualizador" e "gerente" perdem a escrita em configuração de IA e canais. Se alguém do seu time mexia nessas telas sem ser administrador, promova a pessoa a administrador antes de atualizar — ou ela vai encontrar as ações bloqueadas.
- Nenhuma ação manual no banco é necessária. O
update.shaplica tudo sozinho.
1.2.0 — 2026-08-11
A maior versão até aqui: 126 novidades e 205 correções desde a 1.1.0 (contadas por commit). Dois temas.
O primeiro é o agente de IA deixar de ser um respondedor e virar parte da operação: ele ganha papéis separados, capacidades declaradas, um follow-up que não deixa conversa morrer no silêncio, e um painel onde você escolhe qual inteligência atende cada parte do sistema.
O segundo é o sistema parar de mentir quando algo dá errado: falha de IA deixa rastro em vez de sumir, botão que não controlava nada foi ligado (ou removido), e erro de rede diz onde mexer em vez de mandar reiniciar o que nunca caiu.
Adicionado
O agente ganha papéis
- Três papéis em vez de um — Conversador, Operador e Segurança. Quem fala não é quem executa, e o disparo de ação passou a ser imposto pelo sistema, não decidido pelo modelo. Efeito medido: a taxa de resposta em que dado interno vazava para o cliente (URL de sistema, UUID, jargão de CRM) caiu de 3 em 10 turnos para 1 em 10 — mesmos cenários, ferramentas executadas contra dados reais, controle calibrado contra a linha de base.
- O agente publicado tem lugar próprio, entre atendente e gerente: assume o lead, devolve para uma pessoa quando precisa, e a volta aparece na linha do tempo em vez de sumir.
- Capacidades declaradas. Você escolhe o que ele pode fazer, vê quantas vezes usou cada uma, e ele avisa quando falta uma capacidade em vez de falhar calado.
- Roteador de intenção por número — um WhatsApp só passa a atender vários assuntos — agora com escolha do modelo (e do provedor) que identifica a intenção.
Follow-up: nenhuma conversa morre no silêncio
- O follow-up nasce sozinho quando o negócio entra numa etapa do funil, ou quando o agente abre um caso pedindo ajuda — e morre quando o caso fecha.
- Ramos nomeados no canvas: cada regra é uma bolinha com nome, e publicar exige cobertura por ramo, dizendo qual ramo ficou descoberto.
- Pausar, retomar, adiar e pular um follow-up sem matá-lo.
- Tempo adaptativo — a IA escolhe o intervalo e a tela mostra qual foi, e se bateu no seu limite.
- Dossiê do follow-up: o que já foi tentado, com o que o motor realmente fez.
- O painel inteiro fala português — UUID saiu da tela.
Escolher a sua IA
- Painel de Provedores (Agente de IA → Provedores): a tela onde se vê e se escolhe qual
inteligência atende cada uma das 23 partes do sistema que usam IA — conversar, classificar
sentimento, indexar conhecimento, ouvir áudio. Antes disso a escolha existia só no
.env. - OpenRouter completa — uma chave só, com catálogo que se atualiza sozinho contra a origem (cerca de 400 modelos na sincronização de referência; o número acompanha o que eles publicam).
- O instalador pergunta qual IA vai atender (OpenRouter, Anthropic ou OpenAI) e valida a chave na hora, em vez de assumir uma e falhar semanas depois.
- Catálogo de modelos atualizado nos provedores — quem instala não escolhe mais entre modelos de duas gerações atrás, pagando mais caro por pior.
Ver o que a IA fez
- Tela de Execuções (Agente de IA → Execuções): o que a IA fez e, quando falhou, o que aconteceu e o que fazer a respeito.
- Falha de IA deixa rastro. Antes, um erro no meio do caminho sumia — o log mentia por omissão e a operação não tinha como saber que algo não rodou.
A conversa vira CRM sozinha
- A conversa vira lead sem alguém transcrever nada à mão.
- A IA propõe o dado que o cliente disse — telefone, e-mail, nome — e não grava nada: o dado espera numa fila até uma pessoa confirmar na tela.
- Demandas viram entidade de primeira classe: nascem no ponto de entrada, aparecem no painel de quem atende, e o Radar mostra as que estão sem próximo passo — o que corre risco de morrer sem resposta.
- Escopo de funil do agente: você marca em quais funis ele mexe, e ele só escreve nesses.
Medir a operação
- Índice de Atrito (Desempenho) — o sistema passa a medir o próprio propósito.
- Abandono, repergunta e espera calada — as perdas de que ninguém reclama, agora contadas.
Atendimento
- Fila de leads por atendente, com rodízio. A distribuição deixa de ser combinada por fora e vira porta na tela.
- Colar imagem no composer com Ctrl+V.
- Declarar desde quando o número é usado e poder pular o aquecimento — um número antigo não precisa ser tratado como recém-nascido.
- Aviso de mensagem presa. Uma tarefa automática detecta mensagem que ficou "enviando" e abre um aviso na Central, em vez de deixar o cliente sem resposta em silêncio.
Corrigido
- Duas partes do sistema respondiam à mesma mensagem do cliente. Agora há um dono só.
- "O WhatsApp está fora do ar" quando o serviço estava de pé. Toda falha de rede caía na mesma frase, mandando reiniciar um container que nunca havia caído. Agora a mensagem distingue endereço errado de serviço parado e diz onde mexer.
- Escolher OpenRouter ou OpenAI no instalador tornava a instalação impossível — e, num segundo defeito, a escolha era decorativa: aceita na pergunta e ignorada depois.
- O instalador perdia a chave que você tinha configurado à mão no
.env, e a segunda execução desfazia a entrevista já respondida. - O papel Operador escrevia no CRM depois de o humano assumir a conversa — era o único turno sem a guarda.
- A telemetria da IA voltou a dizer a verdade (5 defeitos de uma unificação anterior), e a troca de modelo voltou a ser auditada — o registro era engolido em silêncio.
- Duas mutações perdiam a auditoria caladas por chave natural gravada em coluna
uuid. - A aba "Minhas" mostrava tudo que o atendente já tinha fechado.
- O filtro por tag da tela não filtrava — a rota ignorava o parâmetro.
- O menu passava da dobra em telas de 900px depois que as telas novas entraram.
- O roteador recusava um número que existia, com a mensagem "não encontrado nesta organização", quando na verdade a consulta é que havia falhado.
- A tela de funis misturava organizações do mesmo usuário.
- Excluir um canal apagava o roteador junto, sem avisar, e deixava a Meta ainda entregando mensagens. Reconectar dizia "conectado" com a linha ainda arquivada.
- Erro ao publicar o agente no onboarding criava um agente novo a cada clique.
- O custo de IA sem agente dono sumia da auditoria — as telas de consumo mostravam zero numa instalação com tráfego real e provedor pago.
- Mover um lead pelo assistente deixou de pular o que mover pela mão aciona.
- Telefone descoberto depois estourava a restrição de unicidade e a mensagem do cliente sumia.
- O
update.shinventava gasto de IA e podia pausar o agente de quem estava atualizando. - Uma migration anterior apagou três tipos de aviso da Central — corrigido, e agora há um gate que compara.
Segurança
- 8 de 25 funções internas do banco estavam executáveis pela chave pública que vai para o navegador, incluindo uma que escreve recebendo a organização por parâmetro, sem checar se você pertence a ela. Todas fechadas, com uma varredura que reprova a próxima.
- Desligar uma camada de proteção do agente era escrita de qualquer membro da organização — agora exige papel de gestão.
- Expressão regular vulnerável a ReDoS na leitura do telefone dentro da conversa.
- O limitador de requisições vazava uma chave por janela em memória.
- O Sentry da comunidade recebia sessão além de erro — agora recebe só o relatório de erro, como o README sempre descreveu.
⚠️ Requer atenção
Esta versão traz 51 mudanças de banco (migrations 0087 a 0148). O update.sh aplica tudo
sozinho e faz backup antes — você não precisa rodar nada à mão. Se a sua instalação está há
muito tempo sem atualizar, é normal a etapa do banco demorar mais e imprimir vários avisos de
"já existe": eles são esperados, e o script só destaca o que não for.
Se você instalou entre 30/07 e hoje, seu servidor já roda este código (a instalação acompanha a
main) — esta tag existe para que a atualização pela tela e o update.sh voltem a ter um alvo
publicado para comparar.
1.1.0 — 2026-07-30
Adicionado
- Atualização pela própria tela. O dono da instalação vê a versão instalada no rodapé do menu e, quando há versão nova, atualiza com um clique — sem abrir terminal. A tela mostra o que muda, avisa quanto tempo o sistema fica fora do ar e faz uma cópia de segurança antes.
Alterado
- A atualização passa a instalar a última versão publicada, não o topo do código em
desenvolvimento. O
update.shrecusa instalar uma versão anterior à que já está no servidor (voltar no tempo continua possível com--force) e grava a imagem escolhida no.env— assim umdocker compose up -drodado depois não traz o app de volta para alatest.
⚠️ Requer atenção
Quem já tem o CRM instalado precisa rodar bash hostgator-setup-kit/update.sh duas vezes pelo
terminal para ativar o botão. Não é engano: a primeira execução ainda é a do programa antigo, que
baixa o novo mas não sabe ligar o agente da tela; a segunda já roda o programa atualizado e liga.
Depois disso, nunca mais é preciso o terminal.
1.0.0 — 2026-07-27
Primeira versão marcada do DeskcommCRM. O projeto vinha sendo desenvolvido publicamente desde abril de 2026 sem tags; esta release estabelece o ponto a partir do qual toda mudança passa a ser versionada e descrita — porque quem hospeda o próprio sistema precisa saber o que muda antes de atualizar.
Plataforma
- Multi-tenancy com RLS em toda tabela tenant-aware, resolvida por
fn_user_org_ids(). - RBAC de 4 papéis (
viewer<agent<manager<admin), aplicado no servidor. - Autenticação via Supabase Auth com MFA TOTP obrigatório para administradores.
- Log de auditoria append-only com retenção de 5 anos.
- Onboarding de organização e ciclo completo de convite de membros.
Atendimento WhatsApp
- Inbox de 3 painéis em tempo real, com múltiplos números via WAHA.
- Mídia servida por Storage com URLs assinadas; transcrição de áudio.
- Proteção anti-banimento: ritmo com variação, teto por número, janela de horário, aquecimento gradual e variação de texto.
- Detecção de pedido de descadastro (STOP) no inbound, com bloqueio automático.
CRM
- Funil kanban com indexação fracionária de posição.
- Vocabulário configurável por funil — o mesmo núcleo atende e-commerce, clínica, imobiliária, infoproduto e serviços.
- Customer 360, contatos, etiquetas e linha do tempo unificada.
- Integração com Nuvemshop para a vertical de e-commerce.
Agentes de IA
- Agentes com RAG por organização (pgvector), análise de sentimento e controle de orçamento por organização.
- IA como responsável de primeira classe, sujeita às mesmas regras de governança de um humano.
- Handoff IA→humano auditado, entregando resumo contextual (não a conversa crua).
- Cadeia de 7 verificações antes de cada envio, em ordem fixa: descadastro, LGPD, anti-banimento, variação de texto, promessa determinística, promessa semântica e disclosure. Cada avaliação vira registro durável e auditável — inclusive as que barram o envio.
- Servidor MCP interno.
Governança de atendimento
- Atribuição e transferência auditadas, fila com posição e roteamento automático.
- Escopo de visualização por papel, aplicado via RLS.
- Métricas por atendente.
Automação
- Fontes de captação: endpoint público por organização que recebe leads de landing pages, formulários e ferramentas externas.
- Regras QUANDO/SE/ENTÃO, que nascem pausadas até revisão.
- Webhooks de saída com proteção contra SSRF.
- Nenhum trigger de banco faz HTTP: eventos vão para
event_loge são drenados por rota agendada.
LGPD
- Exportação e anonimização em cascata via workers, com anonimização preferida sobre exclusão.
- Consentimento auditado.
Self-host
hostgator-setup-kit: instalação completa (app + WAHA + banco) com um comando.baseline.sqlidempotente e auto-curativo — atualização não quebra clone com dados legados.- 8 scripts de operação:
install,update,backup,restore,reset-password,reset-mfa,healthchecke o assistente de instalação em IA. - Imagem publicada em
ghcr.io/melgarafael/deskcommcrm— a VPS não compila nada.
Qualidade
- CI com dois portões obrigatórios:
verify(typecheck, lint, testes unitários) einvariants. - O portão
invariantssobe um Postgres limpo, aplica obaseline.sqlem modo install e update, e roda 364 testes de invariante em 56 arquivos — incluindo o teste de isolamento entre organizações, que prova que um usuário de uma organização não enxerga nenhuma linha de outra. - Suíte end-to-end em Playwright dirigindo o frontend.
⚠️ Requer atenção
- Node 22 é obrigatório para desenvolvimento. A suíte de invariantes instancia o cliente do Supabase, que exige o
WebSocketglobal — nativo apenas a partir do Node 22. Isso não afeta quem apenas hospeda: a VPS roda a imagem pronta.