# Resumo Operacional GLPI (V2) — em produção Automação n8n que gera e envia ao Slack um resumo diário/semanal de chamados do GLPI, com números 100% determinísticos (SQL) e uma camada opcional de interpretação por IA (insights, nunca números). **Status atual: V2 ativada em produção** na instância `devn8n.gtigrupo.com.br` (não existe uma segunda instância n8n de produção — esta é a instância operacional até uma futura migração). V1 é mantida só como referência local (nunca foi implantada nesta instância). ## Princípio central > **SQL conta. IA entende.** Todo número no relatório (abertos, fechados, pendentes, saldo, alta prioridade) vem de query SQL determinística. A IA só recebe esses números prontos e uma lista limitada/redigida de chamados, e só pode produzir **insights interpretativos** (texto), nunca alterar ou inventar contagens. Se a IA falhar, atrasar ou responder algo inválido, o relatório continua com fallback determinístico — nunca quebra por causa da IA. ## Arquitetura (fonte de verdade local) ``` src/v2/ config.js — configuração central (thresholds, flags de ambiente) period.js — calendário operacional e janelas de baseline histórico queries.js — todas as queries SQL (somente leitura, geradas, nunca hardcoded) sqlGuard.js — bloqueia qualquer verbo de escrita numa query antes de rodar baseline.js — pivotamento de séries diárias para detecção de baseline anomaly.js — detecção determinística de spike/concentração/tendência insights.js — validação do output da IA, fingerprint, memória de insights aiSchema.js — contrato JSON schema + prompt da IA + contexto minimizado/redigido format.js — montagem da mensagem final (fallback e curta) sendGuard.js — guarda de envio real + idempotência (ver abaixo) pipeline.js — orquestra tudo (buildReport) — mesma lógica testada localmente e colada nos Code nodes do n8n (não há import no n8n remoto) tools/ build_v2_workflow.js — gera os Code nodes a partir de src/v2/*.js build_v2_workflow_assemble.js — monta o workflow n8n completo (30 nodes) smoke_test_generated_nodes.js — simula os Code nodes gerados via `vm`, localmente, antes de qualquer deploy test/ — 133 testes (`node:test`), cobrindo cada módulo + regressões estruturais do workflow gerado (executeOnce, sendGuard concatenado) Resumo Operacional GLPI v2 - IA.n8n.json — workflow gerado (saída de build_v2_workflow.js) ``` **Fluxo de mudança obrigatório:** editar `src/v2/*.js` → `node tools/build_v2_workflow.js` → `npm test` → `node tools/smoke_test_generated_nodes.js` → deploy no n8n (`n8n_update_partial_workflow`/`n8n_update_full_workflow`) → `n8n_validate_workflow`. Nunca editar o Code node direto no n8n sem refletir a mudança em `src/v2/`. ## Guarda de envio real e idempotência (`sendGuard.js`) ``` podeEnviar = SHADOW_MODE === false (absoluto) && DEV_MODE === false (absoluto) && SEND_ENABLED === true (absoluto) && (isScheduled || FORCE_SEND === true) (manual só envia com override explícito) ``` Identidade de um relatório para fins de duplicata = **`report_type + period_start + period_end + destination`** (sem `message_hash` — a IA não é determinística; incluir o hash na chave já causou envio duplicado real em produção, corrigido em 2026-08-25). O `message_hash` continua calculado e armazenado só para auditoria. Registro de sucesso na Data Table `dev_glpi_v2_send_log` só acontece **depois** da confirmação real do Slack (`ok:true`). Retry do mesmo período é sempre bloqueado, mesmo que a IA gere texto diferente. ## Configuração operacional atual (node `Config - V2`) | Flag | Valor | Efeito | |---|---|---| | `DEV_MODE` | `false` | produção ativa | | `SHADOW_MODE` | `false` | envio real habilitado | | `SEND_ENABLED` | `true` | chave mestra de envio | | `FORCE_SEND` | `false` (padrão) | execução manual não envia a menos que setado explicitamente | | `SLACK_DESTINATION` | `C0BJNBTPFT5` | canal onde o bot já é membro confirmado | | `EXTENDED_METRICS_ENABLED` | `false` | fora de escopo desta versão | Credenciais reaproveitadas (nenhuma criada nova): MySQL `GLPI` (`dsVj1nmOIXRvix9n`), OpenAI `OpenAI - Coordenador GLPI` (`WUGriAn5FgCiLza2`), Slack `Slack - Bot Coordenador (Chamados Suporte)` (`lNqwBBrtLfkRqw2X`, mesma credencial do workflow irmão "[DEV] Coordenador GLPI - Chamados Abertos v2 (Shadow)"). ## Calendário e agendamento Schedule Trigger: `0 8 * * 1-5`, timezone da instância (`America/Bahia`, sem conversão manual para UTC). - Segunda 08:00 → semana anterior completa (segunda a domingo) - Terça 08:00 → relatório de segunda-feira - Quarta 08:00 → relatório de terça-feira - Quinta 08:00 → relatório de quarta-feira - Sexta 08:00 → relatório de quinta-feira - `data_alvo` manual (campo em `Config - V2`) força um dia específico, ex.: `2026-08-20` ## GLPI Acesso **estritamente somente leitura** — `sqlGuard.js` bloqueia qualquer verbo de escrita (`INSERT/UPDATE/DELETE/ALTER/DROP/CREATE/TRUNCATE/REPLACE/GRANT/REVOKE`) antes de qualquer query chegar ao node MySQL. Filtro de categorias pelas árvores `7`, `16`, `17`, `18` via `ancestors_cache`. ## Rodando os testes ```powershell npm test ``` 133/133 devem passar. Após qualquer alteração em `src/v2/*.js`, rodar também: ```powershell node tools/build_v2_workflow.js node tools/smoke_test_generated_nodes.js ``` ## Fallback - IA indisponível/timeout/JSON inválido → indicadores determinísticos seguem no relatório, insights de IA são omitidos (nunca derruba a automação). - Baseline histórico indisponível → insight correspondente é omitido, resto do relatório segue normal. ## Workflows V1 (legado, referência local — nunca implantados nesta instância n8n) Mantidos apenas como referência histórica da lógica SQL original (a V2 herda a mesma lógica de `abertos`/`fechados`/filtro de categorias, validada linha a linha contra a V1): - `Resumo Diario GLPI - SQL Slack.n8n.json` — lógica de período diário/semanal automático que a V2 herda - `Resumo Semanal GLPI - SQL Slack.n8n.json` - `sql/indicadores_diario_glpi.sql`, `sql/indicadores_semana_glpi.sql` Não editar nem reativar sem necessidade comprovada — a V2 é a versão operacional. ## Subir o N8N localmente com Docker (ambiente de desenvolvimento) 1. Copie `.env.example` para `.env`. 2. Edite `.env` e troque `N8N_BASIC_AUTH_PASSWORD` e `N8N_ENCRYPTION_KEY`. 3. Suba o container: ```powershell docker compose up -d ``` 4. Acesse `http://localhost:5678`. 5. Para parar: `docker compose down`. Isso é independente da instância operacional (`devn8n.gtigrupo.com.br`), que já está ativada e não depende deste Docker local.