V2: guarda de envio real (SEND_ENABLED/FORCE_SEND), idempotencia por send_key e Slack nativo

- src/v2/sendGuard.js (novo): canSend() reduz SHADOW_MODE/DEV_MODE/
  SEND_ENABLED/FORCE_SEND a uma formula unica testada exaustivamente
  (secao 15 do ciclo final: matriz completa de guarda de seguranca).
  computeMessageHash/buildSendKey/isDuplicate implementam a chave
  logica de idempotencia da secao 13 (report_type+periodo+destino+hash).
- src/v2/config.js: SEND_ENABLED, FORCE_SEND, SLACK_DESTINATION.
- src/v2/pipeline.js: buildReport agora calcula envio.pode_enviar/
  motivo_guarda/duplicata_bloqueada/send_key a partir de triggerType
  (.mode) e sendLogRows (Data Table de log de envios).
- tools/build_v2_workflow*.js: novo Data Table 'Buscar Log de Envios',
  troca do HTTP Slack com webhook placeholder por node Slack nativo
  (credencial real lNqwBBrtLfkRqw2X, reaproveitada do projeto irmao
  Coordenador GLPI), branches de sucesso/falha gravando o log de envio
  so apos confirmacao real do Slack.
- test/sendGuard.test.js, test/workflowStructure.test.js (novos):
  cobrem a matriz de guarda de seguranca e travam regressao do bug de
  timeout (executeOnce=true nos 8 nodes de leitura em lote) e do bug
  de sendGuard.js nao concatenado no Code node gerado.
- Corrigido bug real encontrado nesta sessao: sendGuard.js nao estava
  na lista de modulos concatenados pelo gerador, deixando canSend/
  computeMessageHash/buildSendKey undefined em runtime.
- Deployado e validado ao vivo no DEV (workflow 3x5kb58TeBCvirm6):
  n8n_validate_workflow -> valid:true, 0 erros, executeOnce preservado
  nos 9 nodes de leitura em lote.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Automacao GLPI
2026-08-25 09:22:42 -03:00
co-authored by Claude Sonnet 5
parent bdfa675d89
commit 64ddfb9b7b
10 changed files with 815 additions and 84 deletions
+16
View File
@@ -46,6 +46,10 @@ function runCodeNode(nodeName, inputItems, extraGlobals) {
first: () => inputItems[0],
all: () => inputItems,
},
// $execution.mode: 'trigger' simula o Schedule Trigger (producao real);
// o smoke test usa isso por padrao porque e o caminho mais exercitado
// pelo relatorio (execucao manual e coberta por sendGuard.test.js).
$execution: { mode: 'trigger' },
console,
Date,
JSON,
@@ -87,6 +91,9 @@ const configItem = [
MAX_REPORT_INSIGHTS: 5,
DEV_MODE: true,
SHADOW_MODE: true,
SEND_ENABLED: true,
FORCE_SEND: false,
SLACK_DESTINATION: 'C0000TESTE',
EXTENDED_METRICS_ENABLED: false,
ANOMALY_MULTIPLIER: 2.0,
ANOMALY_MIN_DELTA: 3,
@@ -155,6 +162,7 @@ registry.set('MySQL - Baseline Diario Cliente', [
].map((r) => ({ json: r })));
registry.set('Data Table - Buscar Memoria de Insights', []);
registry.set('Data Table - Buscar Historico Anterior', []);
registry.set('Data Table - Buscar Log de Envios', []);
console.log('\n--- 2) Code - Preparar Contexto IA ---');
const out2 = runCodeNode('Code - Preparar Contexto IA', [{ json: {} }]);
@@ -193,6 +201,7 @@ const out4 = runCodeNode('Code - Motor V2: Relatorio Completo', [{ json: out3[0]
const relatorio = out4[0].json;
console.log('status_operacional:', relatorio.status_operacional);
console.log('insights_aceitos:', relatorio.insights_aceitos.length);
console.log('envio:', JSON.stringify(relatorio.envio, null, 2));
console.log('observabilidade:', JSON.stringify(relatorio.observabilidade, null, 2));
console.log('\n=== mensagem_v1 (fallback / legado) ===\n' + relatorio.mensagem_v1);
console.log('\n=== mensagem_v2 (V2 curta) ===\n' + relatorio.mensagem_v2);
@@ -201,4 +210,11 @@ console.log('\n--- 5) Code - Preparar Historico ---');
const out5 = runCodeNode('Code - Preparar Historico', [{ json: relatorio }]);
console.log(JSON.stringify(out5[0].json, null, 2));
console.log('\n--- 6) Code - Preparar Log de Envio (Sucesso/Falha) ---');
registry.set('Code - Motor V2: Relatorio Completo', [{ json: relatorio }]);
const out6a = runCodeNode('Code - Preparar Log de Envio (Sucesso)', [{ json: {} }]);
console.log('log sucesso:', JSON.stringify(out6a[0].json));
const out6b = runCodeNode('Code - Preparar Log de Envio (Falha)', [{ json: { error: { message: 'timeout simulado' } } }]);
console.log('log falha:', JSON.stringify(out6b[0].json));
console.log('\nSMOKE TEST OK — todos os Code nodes gerados executaram sem excecao.');