Atualização do READ.ME

This commit is contained in:
2026-08-24 19:00:21 -03:00
parent c4d691b202
commit 568f185d8c
7 changed files with 240 additions and 34 deletions

127
README.md
View File

@@ -2264,11 +2264,13 @@ docker compose exec app bin/rails runner '
<details>
<summary><strong>📣 Notificações: WhatsApp por QR (Baileys) no lugar do Twilio + contatos, grupos e eventos — ETAPA 1 (24/08/2026)</strong></summary>
> ⚠️ **STATUS: implementado, NADA executado.** Não há Ruby/Bundler, Postgres nem Docker rodando na
> máquina de desenvolvimento. Foi conferida a sintaxe de todos os `.rb`/`.erb` (com um checker que
> emula o handler ERB do Rails, porque `<%= form_with … do %>` não passa no ERB da stdlib) e do
> `server.js` (`node --check`). **Migration, `npm install`, build do container, pareamento do QR e a
> suíte continuam pendentes** — roteiro no fim.
> **STATUS: NO AR no ambiente de teste (24/08/2026).** Migrations aplicadas, container da ponte
> buildado e **WhatsApp pareado por QR** — número `5511920051157`, conectado às 18:07, intervalo em
> 20s. Telas de contatos, grupos, eventos, envios e conexão validadas no navegador.
>
> ⚠️ **A suíte continua sem rodar** — não há Ruby/Bundler na máquina de desenvolvimento. A sintaxe
> de todos os `.rb`/`.erb` foi conferida (com um checker que emula o handler ERB do Rails, porque
> `<%= form_with … do %>` não passa no ERB da stdlib) e a do `server.js` com `node --check`.
> Esta é a **etapa 1 de 3**. Ver "O que NÃO está aqui" no fim.
@@ -2397,10 +2399,12 @@ docker compose exec app bundle exec rspec \
<details>
<summary><strong>🧱 Editor de blocos das mensagens — ETAPA 2 (24/08/2026)</strong></summary>
> ⚠️ **STATUS: implementado, NADA executado.** Sem Ruby/Bundler/Postgres/Docker na máquina de
> desenvolvimento. Conferida a sintaxe de todos os `.rb`, de todos os `.erb` (checker que emula o
> handler do Rails) e **do JavaScript do editor** (`node --check` sobre o `<script>` extraído).
> **Migration, `npm install` e a suíte continuam pendentes.**
> **STATUS: NO AR no ambiente de teste (24/08/2026).** Migration aplicada; a tela de eventos já
> mostra o ✓ dos canais com mensagem montada.
>
> ⚠️ **Não validado ainda**: o arrastar/soltar e o preview com dado real, na mão, no navegador — e a
> suíte. Sintaxe conferida em todos os `.rb`, `.erb` e **no JavaScript do editor** (`node --check`
> sobre o `<script>` extraído).
### 🎯 O que mudou
Na etapa 1, o corpo das mensagens ainda era string interpolada em Ruby — mudar uma palavra exigia
@@ -2498,9 +2502,10 @@ gatilhos hoje só dispara pelo botão manual.
<details>
<summary><strong>🔔 Gatilhos: valor alterado, operação mudou e resumo agendado — ETAPA 3 (24/08/2026)</strong></summary>
> ⚠️ **STATUS: implementado, NADA executado.** Sem Ruby/Bundler/Postgres/Docker na máquina de
> desenvolvimento. Sintaxe conferida em todos os `.rb`, `.rake` e `.erb`. **2 migrations, o
> `whenever --update-crontab` e a suíte continuam pendentes.**
> **STATUS: migrations no ar (24/08/2026).**
>
> ⚠️ **Não validado ainda**: um disparo real de cada gatilho, o `whenever --update-crontab` e a
> suíte. Sintaxe conferida em todos os `.rb`, `.rake` e `.erb`.
### 🎯 O que faltava
Nas etapas 1 e 2, `valor_alterado`, `operacao_alterada` e `agendado` existiam como opção de gatilho
@@ -2593,3 +2598,101 @@ docker compose exec app bundle exec rake notificacao:mudancas_operacao
```
</details>
---
<details>
<summary><strong>🛠️ Deploy das notificações: os 3 tropeços e as correções (24/08/2026)</strong></summary>
Registro do que quebrou entre "implementado" e "no ar", porque os três são armadilhas que voltam.
### 1. `PG::UndefinedTable: relation "grupo_contatos" does not exist`
`t.references :grupo_contato, foreign_key: true` faz o Rails **pluralizar** o nome para achar a
tabela alvo. O Inflector não fala português: `grupo_contato` → `grupo_contatos` e
`evento_notificacao` → `evento_notificacaos`. As tabelas reais são `grupos_contato` e
`eventos_notificacao` (plural no **primeiro** termo).
**Correção:** `foreign_key: { to_table: :grupos_contato }` nas 5 referências afetadas. `user` e
`contato` pluralizam certo e não precisaram.
> É a MESMA armadilha que já tinha aparecido nas rotas (`grupos`/`eventos`/`envios` em vez dos nomes
> dos controllers). Sempre que uma tabela em português tiver o plural no primeiro termo, `to_table:`
> e nome de rota explícito são obrigatórios.
### 2. `npm error syscall spawn git / ENOENT` na build da ponte
`errno -2` = o **binário** `git` não existe na imagem. O `node:20-alpine` não traz git, e o Baileys
resolve `libsignal` de um **repositório git**, não do registry do npm.
**Correção:** `apk add --no-cache git` no `whatsapp/Dockerfile`. Não é erro de rede, de firewall nem
de versão do pacote — e a linha do `apk` tem comentário explicando, para não ser "limpa" depois.
### 3. Não havia como escolher o provedor
As colunas `whatsapp_provedor`, `baileys_url`, `baileys_token` e `whatsapp_intervalo_segundos`
nasceram na migration, mas a tela **Configurações → Notificações** continuou 100% Twilio. Como o
padrão da coluna é `twilio`, o caminho do QR ficava **inalcançável pela interface** — dava para
parear e nada usaria a ponte. Pior: a tela do QR linkava para lá dizendo que o intervalo se
configurava ali, o que era falso.
**Correção:** seletor de Provedor, campo de intervalo e bloco "Modo QR code" (endereço + token, em
branco caem no `.env`) na tela de configuração; e `Notificacao::TesteWhatsapp` passou a ramificar
pelo provedor em vez de ir direto ao Twilio.
### 4. Evento criado pelo ADM não disparava
`Despachante.disparar(chave:)` buscava **um** evento pela chave. Como o código de negócio chama com
a chave fixa (`'consolidacao_finalizada'`…), só o evento de **sistema** disparava: um evento criado
na tela com o mesmo gatilho ficava mudo para sempre, **sem erro nenhum**. A tela oferecia o gatilho
e não acontecia nada.
**Correção:** `Despachante.disparar_gatilho(gatilho:)` dispara **todos** os eventos ativos daquele
gatilho, cada um com seus grupos e sua mensagem — que é justamente o ponto de poder cadastrar
eventos. O `disparar(chave:)` continua existindo para o botão "disparar agora", que mira um evento
específico.
</details>
---
<details>
<summary><strong>💡 Ideias para o editor de mensagens — backlog priorizado</strong></summary>
Levantado com a tela já em uso. Ordenado por **valor ÷ esforço**; nada aqui está implementado.
### A. Chegar até o editor
O problema, olhando a tela de eventos hoje: os acessos são **dois links de texto cinza**
("WhatsApp" e "E-mail") do lado de "Editar", com o mesmo peso visual. Nada diz que ali se
**escreve a mensagem** — parece mais um filtro de canal. E o ✓ de "já tem mensagem montada" é
pequeno demais para ser lido de relance.
| # | Ideia | Esforço |
|---|---|---|
| A1 | **Botão "Montar mensagem"** com ícone, no lugar dos dois links soltos. Abre o editor com abas WhatsApp/E-mail **dentro** dele, em vez de duas portas separadas. | baixo |
| A2 | **Estado como badge colorido** — `WhatsApp ✓ · E-mail —` em verde/cinza, não link. Mostra num relance o que falta. | baixo |
| A3 | **Miniatura do preview no card do evento**: as 2 primeiras linhas da mensagem renderizada. Responde "o que esse evento manda?" sem entrar. | médio |
| A4 | **Passo seguinte explícito**: ao salvar um evento novo, redirecionar para o editor com "Agora monte a mensagem". Hoje você cria o evento e fica sem pista do que fazer. | baixo |
| A5 | **Item "Mensagens" no menu** — tabela evento × canal com o estado de cada um. Hoje só se chega pelo evento. | médio |
| A6 | **Alerta de evento mudo**: ativo, com grupo assinante e sem mensagem própria → avisar que vai usar o texto padrão do sistema. | baixo |
### B. Design das mensagens
Hoje: 7 blocos, cores fixas no renderizador, só texto.
| # | Ideia | Esforço | Observação |
|---|---|---|---|
| B1 | **Ocultar bloco quando a variável estiver vazia** — checkbox por bloco. Resolve o "⚠️ Alterações: " sem nada depois, que hoje aparece. | baixo | O ganho de qualidade mais barato da lista. |
| B2 | **Enviar teste direto do editor** — "mandar para o meu WhatsApp" sem sair da tela. Hoje: salvar → eventos → disparo manual. | baixo | |
| B3 | **Modelos prontos** ("Aviso de fechamento", "Resumo diário", "Alteração de valor") — começar de um layout em vez da folha em branco. | médio | |
| B4 | **Duplicar template** entre canais e entre eventos ("copiar do WhatsApp para o e-mail"). | baixo | |
| B5 | **Cor de destaque configurável** — hoje o laranja está fixo no `Renderizador`. | baixo | |
| B6 | **Logo no cabeçalho do e-mail** | médio | Precisa de URL absoluta pública ou embed em base64; cliente de e-mail bloqueia imagem remota por padrão. |
| B7 | **Bloco de lista** (bullets) — hoje só existe tabela rótulo/valor. | baixo | |
| B8 | **Preview em moldura de celular** para o WhatsApp e alternância desktop/mobile no e-mail. | médio | Hoje o preview do WhatsApp é um `<pre>` escuro. |
| B9 | **Contador de caracteres** no WhatsApp — mensagem longa vira "ler mais" e o começo é o que decide se abrem. | baixo | |
| B10 | **Bloco de imagem** | **alto** | No e-mail é `<img>`. No WhatsApp exige **enviar mídia**, e a ponte hoje só faz `sendMessage` de texto — mexe no `server.js`, no cliente Ruby e no log de envios. |
| B11 | **Versões do template** — voltar à anterior depois de estragar. | médio | |
### Se fosse escolher três
**A1 + A2** (o editor deixa de ser escondido) e **B1** (mensagem sem buraco quando a variável vem
vazia). Juntos são baixo esforço e resolvem o que mais incomoda no uso diário.
</details>