From e272b96d0cb8877f07135457d9d2bebe8ecfe5f4d93c69127b68a366fc922206 Mon Sep 17 00:00:00 2001 From: victor Date: Tue, 25 Aug 2026 01:06:19 -0300 Subject: [PATCH] =?UTF-8?q?Atualiza=C3=A7=C3=A3o=20do=20READ.me?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 175 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) diff --git a/README.md b/README.md index 42f9714..73657f4 100644 --- a/README.md +++ b/README.md @@ -2770,3 +2770,178 @@ docker compose exec app bin/rails db:migrate ``` + +--- + +
+🎨 Ponte desatualizada, nome do Baileys fora da tela e padronização visual (25/08/2026) + +> ⚠️ **STATUS: implementado, não executado.** Sem migration. Sintaxe conferida nos 16 `.erb` +> tocados e nos 2 `.rb`. **Testes não rodados** — não há bundler na máquina de desenvolvimento, +> só no container. + +### 1. `rota desconhecida` ao buscar os grupos + +O botão "Buscar grupos" do cadastro de contato respondia **`rota desconhecida`**. Não era bug do +Rails: é o 404 da própria ponte (`whatsapp/server.js`, fallback de rota inexistente) repassado cru +para a tela. + +A rota `GET /grupos` existe no código desde o commit `568f185`, mas **o container `whatsapp` do +ambiente de teste rodava uma imagem construída antes dele**. O deploy subiu o `app` e reaproveitou +a imagem em cache da ponte. + +**Correção no servidor:** +```bash +docker compose up -d --build whatsapp +# se o cache ainda entregar a imagem velha: +docker compose build --no-cache whatsapp && docker compose up -d whatsapp +``` +O volume `whatsapp_auth` é preservado — **não precisa ler o QR de novo**. + +> 🔁 **A armadilha que volta:** toda vez que `whatsapp/server.js` ganha rota nova, a ponte precisa +> de rebuild próprio. `docker compose up -d --build` sem nomear o serviço pode reaproveitar a +> camada em cache, e o sintoma é sempre este: a tela nova chama uma rota que a ponte em pé não +> conhece. Vale conferir também que o `whatsapp/server.js` foi junto no merge para a `main` — o +> recurso de grupos ainda **não está lá**. + +**Correção no código:** o 404 da ponte deixou de aparecer cru. `ClienteWhatsapp#mensagem_de_erro` +agora traduz para *"Ponte do WhatsApp desatualizada (não conhece esta rota) — refaça o build do +container `whatsapp`"*. É cosmético e **não substitui o rebuild**; serve para a próxima vez o erro +dizer o que fazer. + +### 2. O nome "Baileys" saiu da interface + +Nenhum texto que o usuário lê cita mais a biblioteca. A env var mostrada na tela de configuração +virou **`WHATSAPP_URL`**, e `baileys_url_efetiva` lê nesta ordem: + +``` +banco → ENV['WHATSAPP_URL'] → ENV['BAILEYS_URL'] → 'http://whatsapp:3001' +``` + +O nome antigo continua sendo lido de propósito: **nenhum `.env` já em produção quebra**. + +> **Ficou de fora, de propósito:** as colunas `baileys_url` / `baileys_token` e os métodos +> `baileys?`, `baileys_pronto?`, `BAILEYS_URL_PADRAO` mantêm o nome no banco e no código. +> Renomear exigiria migration + model + controller + service + specs, e **nada disso aparece na +> tela** — os rótulos que o usuário lê já eram "Endereço da ponte" e "Token da ponte". O valor +> `'baileys'` do seletor de provedor também continua: é chave interna, o rótulo visível é +> "QR code (grátis, não oficial)". + +### 3. Padronização visual das telas de notificação + +As 9 telas do módulo nasceram com um dialeto próprio e destoavam do resto do admin. O padrão de +referência é **Usuários** — a tela mais madura. O que mudou: + +| Antes (telas de notificação) | Agora (padrão do admin) | +|---|---| +| Botão `bg-orange-500 text-black`, `py-2.5` | `bg-[#f97316] text-white` com ícone, `min-h-[48px]` | +| `thead` com `bg-white/5`, `py-3`, `font-medium` | `border-b border-white/10`, `py-4`, `font-semibold` | +| Ações "Editar"/"Excluir" em texto | Ícones com `opacity-0 group-hover:opacity-100` | +| Vazio: `

` solto fora da tabela | Linha na tabela, ícone `:vazio`, `py-16` | +| Situação em texto colorido | `badge_status_usuario` / `badge_com_icone` | +| Inputs `bg-[#1a1a1a]`, `py-2.5` | `bg-[#0a0a0a]`, `py-3`, `focus:ring` laranja | +| Checkbox de ativo/inativo | Toggle switch, igual ao de Usuários | +| Formulário solto na página | Card `rounded-2xl border` com seções divididas | + +**Correções de comportamento que vieram junto:** + +- **`render 'shared/flash'` nas telas que não tinham.** Mensagens de sucesso e erro simplesmente + **não apareciam** em Contatos, Grupos, Eventos e Envios — a ação dava certo e a tela ficava muda. +- **O aviso do "Buscar grupos" ganhou cor semântica** — verde no sucesso, vermelho no erro. Antes + toda resposta saía em cinza, então "5 grupos encontrados" e "não foi possível falar com a ponte" + tinham exatamente o mesmo peso visual. +- O rótulo do botão de busca virou um `` próprio: trocar o `textContent` do botão inteiro + apagava o ícone junto. + +**Ganhos de leitura:** avatar distingue pessoa de grupo em Contatos; os filtros de Envios ficaram +agrupados por "Situação" e "Canal" com pílulas; o ponto verde de "Conectado" pulsa; evento +desativado fica esmaecido na lista. + +### 📂 Arquivos +``` +app/models/configuracao_notificacao.rb (WHATSAPP_URL com fallback p/ BAILEYS_URL) +app/services/notificacao/cliente_whatsapp.rb (404 da ponte vira mensagem acionável) +.env.example (WHATSAPP_URL; nome antigo documentado) +app/views/admin/configuracao_notificacoes/show.html.erb (nome da lib fora da tela) +app/views/admin/contatos/{index,_form,new,edit}.html.erb +app/views/admin/grupos_contato/{index,_form,new,edit}.html.erb +app/views/admin/eventos_notificacao/{index,_form,new,edit}.html.erb +app/views/admin/notificacao_envios/index.html.erb +app/views/admin/whatsapp_sessoes/show.html.erb +app/views/admin/mensagem_templates/edit.html.erb +``` + +### ⏳ Pendente +```bash +docker compose up -d --build whatsapp # ⚠️ o que resolve o "rota desconhecida" +docker compose restart app # views mudaram → cache de views do Puma + +docker compose exec app bundle exec rspec + +# Conferir na tela: Notificações → Contatos → Novo contato +# → Tipo "Grupo do WhatsApp" → "Buscar grupos" → a lista deve vir com nome, +# nº de participantes e ⚠️ nos grupos restritos a admin. +``` + +### 🐛 Achado não corrigido +`app/views/admin/mensagem_templates/edit.html.erb` carrega o **SortableJS de +`cdn.jsdelivr.net`**. Se a CSP passar de `report_only` para enforcing (pendência já registrada +neste README), o **arrastar-e-soltar dos blocos morre** — o clique na paleta sobrevive, porque o +código tem `if (window.Sortable)`. O conserto é baixar o arquivo para `public/`. Não foi feito por +estar fora do escopo pedido. + +

+ +--- + +
+🧭 O que falta: gatilhos pela tela e blocos ricos na mensagem — backlog + +Complementa o backlog do editor já registrado acima. **Nada aqui está implementado.** + +### A. Criação de gatilhos pela tela + +**Como é hoje:** o ADM cria quantos **eventos** quiser, mas o **gatilho** sai de uma lista fixa de +seis — `manual`, `consolidacao_finalizada`, `pagamento_efetuado`, `valor_alterado`, +`operacao_alterada`, `agendado`. A tela diz isso ao usuário: *"o gatilho sai de uma lista fixa, +porque gatilho é código"*. E é verdade — cada gatilho tem uma chamada correspondente no código de +negócio (`Notificacao::Gatilhos`, `NotificacaoService`, controllers). + +**O que "criar gatilho pela tela" realmente significa** — três níveis, do barato ao caro: + +| # | Ideia | Esforço | Observação | +|---|---|---|---| +| A1 | **Gatilho agendado com filtro** — "todo dia 08h **se houver consolidação pendente**". Não é gatilho novo: é o `agendado` com uma condição escolhida numa lista. | baixo | Cobre boa parte do que se pede como "gatilho novo". | +| A2 | **Gatilho por limiar** — "quando o valor alterado passar de R$ X" ou "quando as notas fora da operação passarem de N". Campos: métrica (lista), operador, valor. | médio | Reusa `Analytics::ResumoOperacao` e `OperacaoSnapshot`, que já calculam as métricas. | +| A3 | **Gatilhos que faltam no domínio** — consolidação **arquivada**, contato **sem grupo** há X dias, envio **falhado** (avisar o ADM que o WhatsApp caiu). | médio | São gatilhos de código mesmo: uma constante + a chamada no ponto certo. O caminho já está pavimentado por `disparar_gatilho`. | +| A4 | **Condição livre por regra** (construtor de expressão na tela) | **alto** | Vira uma mini-linguagem: precisa de parser, sandbox e validação. **Não recomendado** — A1+A2 entregam quase tudo por uma fração do custo. | + +> ⚠️ **A armadilha aqui:** gatilho cadastrado na tela que **não tem chamada no código** fica mudo +> para sempre, sem erro nenhum — exatamente o bug nº 4 do deploy de 24/08. Qualquer caminho +> escolhido precisa de uma trava: ou a lista continua vindo do código, ou a tela avisa que o +> gatilho ainda não está ligado. + +### B. Mais opções na criação da mensagem + +**Como é hoje:** 7 blocos (`cabecalho`, `texto`, `tabela`, `aviso`, `botao`, `divisor`, `rodape`), +todos **só texto**, com cores fixas no renderizador. + +| # | Ideia | Esforço | Observação | +|---|---|---|---| +| B1 | **Seletor de emoji** nos campos de texto — hoje só colando do sistema. Emoji é o que dá cara de WhatsApp à mensagem. | baixo | Um picker pequeno, sem dependência externa (a CSP é restritiva). Inserir no cursor: a mecânica já existe, é a mesma dos chips de variável. | +| B2 | **Bloco de imagem no e-mail** — `` com URL ou upload. | médio | Cliente de e-mail bloqueia imagem remota por padrão → precisa de URL absoluta pública ou base64. | +| B3 | **Bloco de imagem no WhatsApp** | **alto** | A ponte hoje só faz `sendMessage` de **texto**. Exige `sendMessage(jid, { image })` no `server.js`, endpoint novo, envio multipart no `ClienteWhatsapp`, storage do arquivo e uma coluna no log de envios. **É o item mais caro da lista** — vale só se a demanda for real. | +| B4 | **Formatação do WhatsApp** (`*negrito*`, `_itálico_`, `~riscado~`, ``` `mono` ```) com botões — hoje o ADM precisa saber a sintaxe de cor. | baixo | No e-mail cada marca vira a tag equivalente. | +| B5 | **Bloco de lista com bullets** — hoje só existe tabela rótulo/valor. | baixo | Já estava listado como B7 no backlog anterior. | +| B6 | **Ocultar bloco com variável vazia** — resolve o `"⚠️ Alterações: "` sem nada depois. | baixo | Já listado como B1 antes; **continua sendo o melhor valor ÷ esforço do módulo inteiro**. | +| B7 | **Cor de destaque configurável** — o laranja está fixo no `Renderizador`. | baixo | | +| B8 | **Contador de caracteres no WhatsApp** — mensagem longa vira "ler mais", e o começo é o que decide se abrem. | baixo | | +| B9 | **Bloco de menção** (`@membro`) em grupo do WhatsApp | médio | Baileys exige passar os JIDs em `mentions` além do texto — não basta escrever `@`. | + +### Se fosse escolher três +**B6** (mensagem sem buraco quando a variável vem vazia), **B1** (emoji) e **B4** (formatação do +WhatsApp por botão). Os três são de esforço baixo e atacam o que mais se sente escrevendo mensagem +no dia a dia. **B3 (imagem no WhatsApp) fica por último** — é o único que mexe na ponte, no cliente +Ruby e no schema ao mesmo tempo. + +