Files
SLACK_COORD_RELATORIO/n8n/workflow.template.json
T
GustavoandClaude Sonnet 5 3c87ab55e1 fix(v2): fix cache is_fallback bug, wire observability + data quality, drop debug webhook, fix GLPI URL
- Real bug found by code review while implementing this cycle: "Code -
  Reusar Classificacao em Cache" always hardcoded is_fallback: false when
  reconstructing a classification from memory, even when the cached
  classification was itself AI_FALLBACK. On a cache hit for a previously
  fallback-classified ticket, this would have let it skip
  applyFallbackPolicy's exclusion entirely (the policy checks
  aiClassification.is_fallback first). Fixed to derive is_fallback from
  the cached ai_classification value.
- select-top10.node.js now carries `resolucao` (ia | cache | fallback_cap)
  through to the scored item, previously dropped -- needed to tell cache
  hits apart from real AI calls in observability.
- Code - Comparar Legacy x V2 now computes the full observability summary
  (candidate_count, cache_hits/misses, ai_requested/success/errors,
  ai_fallback_count and by-reason breakdown, classification_counts,
  insufficient_context_count, actionable_real_count,
  critical_override_count, top10_count, blocked_count,
  coordination_count) and the data-quality review (buildDataQualityReview
  over INSUFFICIENT_CONTEXT tickets), both stored in the shadow_runs
  `summary` JSON column -- no new Data Table needed.
- Removed the debug webhook entirely (Debug - Ver Painel, Data Table -
  Buscar Shadow Runs Recentes debug branch, Code - Montar Painel Debug,
  Debug - Responder) and the now-unused debug-panel.node.js driver.
  Workflow went from 37 to 33 nodes. Debugging goes through n8n execution
  data, the Data Tables, and the shadow diff instead, as requested.
- Fixed glpi_base_url: was still V1's own placeholder
  (https://glpi.suaempresa.com.br, never a real value, not report
  anonymization) -- confirmed the real domain (https://glpi.gtigrupo.com.br)
  from the live, active GLPI x WhatsApp workflow's own GLPI API config in
  the same n8n instance. SQL still only ever receives it through
  {GLPI_BASE_URL} substitution from the Config node, never hardcoded.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-24 19:50:48 -03:00

524 lines
19 KiB
JSON

{
"name": "[DEV] Coordenador GLPI - Chamados Abertos v2 (Shadow)",
"nodes": [
{
"id": "manual-trigger-v2",
"name": "Manual Trigger",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [-1600, 0],
"parameters": {}
},
{
"id": "schedule-trigger-v2-desligado",
"name": "Schedule Trigger - Dias uteis 08h (desligado em DEV)",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.3,
"position": [-1600, 900],
"parameters": {
"rule": {
"interval": [
{ "field": "cronExpression", "expression": "0 8 * * 1-5" }
]
}
}
},
{
"id": "config-v2",
"name": "Config - Coordenador GLPI v2",
"type": "n8n-nodes-base.set",
"typeVersion": 3.5,
"position": [-1360, 0],
"parameters": {
"assignments": {
"assignments": [
{ "id": "glpi-base-url-v2", "name": "glpi_base_url", "type": "string", "value": "https://glpi.gtigrupo.com.br" },
{ "id": "cfg-ai-enabled", "name": "AI_ENABLED", "type": "boolean", "value": true },
{ "id": "cfg-ai-provider", "name": "AI_PROVIDER", "type": "string", "value": "openai" },
{ "id": "cfg-ai-model", "name": "AI_MODEL", "type": "string", "value": "gpt-4o-mini" },
{ "id": "cfg-candidate-pool-size", "name": "CANDIDATE_POOL_SIZE", "type": "number", "value": 60 },
{ "id": "cfg-ai-max-candidates", "name": "AI_MAX_CANDIDATES", "type": "number", "value": 30 },
{ "id": "cfg-top-n", "name": "TOP_N", "type": "number", "value": 10 },
{ "id": "cfg-cooldown-days", "name": "COOLDOWN_DAYS", "type": "number", "value": 1 },
{ "id": "cfg-ai-confidence-threshold", "name": "AI_CONFIDENCE_THRESHOLD", "type": "number", "value": 0.6 },
{ "id": "cfg-ai-max-context-chars", "name": "AI_MAX_CONTEXT_CHARS", "type": "number", "value": 4000 },
{ "id": "cfg-dev-mode", "name": "DEV_MODE", "type": "boolean", "value": true },
{ "id": "cfg-shadow-mode", "name": "SHADOW_MODE", "type": "boolean", "value": true },
{ "id": "cfg-dias-sem-interacao-alerta", "name": "DIAS_SEM_INTERACAO_ALERTA", "type": "number", "value": 2 },
{ "id": "cfg-horas-sla-risco", "name": "HORAS_SLA_RISCO", "type": "number", "value": 8 }
]
},
"options": {}
}
},
{
"id": "code-montar-sql-candidatos",
"name": "Code - Montar SQL Candidatos",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [-1120, -160],
"parameters": { "jsCode": "__BUILD__:build-sql-candidatos.node.js" }
},
{
"id": "code-montar-sql-legado",
"name": "Code - Montar SQL Legado",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [-1120, 900],
"parameters": { "jsCode": "__BUILD__:build-sql-legado.node.js" }
},
{
"id": "mysql-buscar-candidatos",
"name": "MySQL - Buscar Candidatos",
"type": "n8n-nodes-base.mySql",
"typeVersion": 2.5,
"position": [-880, -160],
"parameters": { "operation": "executeQuery", "query": "={{ $json.query }}", "options": {} }
},
{
"id": "mysql-legado-top10-shadow",
"name": "MySQL - Legado Top 10 (Shadow)",
"type": "n8n-nodes-base.mySql",
"typeVersion": 2.5,
"position": [-880, 900],
"parameters": { "operation": "executeQuery", "query": "={{ $json.query }}", "options": {} }
},
{
"id": "code-normalizar-candidatos-base",
"name": "Code - Normalizar Candidatos Base",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [-640, -160],
"parameters": { "jsCode": "__BUILD__:normalize-candidates.node.js" }
},
{
"id": "code-montar-sql-contexto",
"name": "Code - Montar SQL Contexto",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [-400, -160],
"parameters": { "jsCode": "__BUILD__:build-sql-context.node.js" }
},
{
"id": "mysql-buscar-contexto",
"name": "MySQL - Buscar Contexto",
"type": "n8n-nodes-base.mySql",
"typeVersion": 2.5,
"position": [-160, -160],
"parameters": { "operation": "executeQuery", "query": "={{ $json.query }}", "options": {} }
},
{
"id": "code-mesclar-contexto-hash",
"name": "Code - Mesclar Contexto e Calcular Hash",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [80, -160],
"parameters": { "jsCode": "__BUILD__:merge-context-hash.node.js" }
},
{
"id": "datatable-buscar-memoria",
"name": "Data Table - Buscar Memoria",
"type": "n8n-nodes-base.dataTable",
"typeVersion": 1.1,
"position": [-1120, 300],
"parameters": {
"resource": "row",
"operation": "get",
"dataTableId": { "mode": "name", "value": "coordenador_glpi_memoria" },
"filters": { "conditions": [] },
"returnAll": true
}
},
{
"id": "merge-aguardar-memoria",
"name": "Merge - Aguardar Memoria",
"type": "n8n-nodes-base.merge",
"typeVersion": 3.2,
"position": [320, -160],
"parameters": { "mode": "append", "numberInputs": 2 }
},
{
"id": "code-decidir-necessidade-ia",
"name": "Code - Decidir Necessidade de IA",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [560, -160],
"parameters": { "jsCode": "__BUILD__:decide-needs-ai.node.js" }
},
{
"id": "if-precisa-ia",
"name": "IF - Precisa IA?",
"type": "n8n-nodes-base.if",
"typeVersion": 2.3,
"position": [800, -160],
"parameters": {
"conditions": {
"options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict", "version": 2 },
"conditions": [
{
"id": "cond-precisa-ia",
"leftValue": "={{ $json.precisa_ia }}",
"rightValue": true,
"operator": { "type": "boolean", "operation": "true", "singleValue": true }
}
],
"combinator": "and"
},
"options": {}
}
},
{
"id": "if-ia-ligada",
"name": "IF - IA Ligada?",
"type": "n8n-nodes-base.if",
"typeVersion": 2.3,
"position": [1040, -320],
"parameters": {
"conditions": {
"options": { "caseSensitive": true, "leftValue": "", "typeValidation": "strict", "version": 2 },
"conditions": [
{
"id": "cond-ia-ligada",
"leftValue": "={{ $json.config.aiEnabled }}",
"rightValue": true,
"operator": { "type": "boolean", "operation": "true", "singleValue": true }
}
],
"combinator": "and"
},
"options": {}
}
},
{
"id": "code-preparar-prompt-ia",
"name": "Code - Preparar Prompt IA",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [1280, -400],
"parameters": { "jsCode": "__BUILD__:prepare-ai-prompt.node.js" }
},
{
"id": "http-openai-classificar",
"name": "HTTP - OpenAI Classificar Chamado",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.4,
"position": [1520, -400],
"continueOnFail": true,
"parameters": {
"method": "POST",
"url": "https://api.openai.com/v1/chat/completions",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "openAiApi",
"sendBody": true,
"contentType": "json",
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify($json.requestBody) }}",
"options": { "timeout": 30000 }
},
"credentials": { "openAiApi": { "id": "WUGriAn5FgCiLza2", "name": "OpenAI - Coordenador GLPI" } }
},
{
"id": "code-validar-classificacao-ia",
"name": "Code - Validar Classificacao IA",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [1760, -400],
"parameters": { "jsCode": "__BUILD__:validate-ai-response.node.js" }
},
{
"id": "code-fallback-ia-desligada",
"name": "Code - Fallback IA Desligada",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [1280, -160],
"parameters": { "jsCode": "__BUILD__:ai-disabled-fallback.node.js" }
},
{
"id": "code-reusar-classificacao-cache",
"name": "Code - Reusar Classificacao em Cache",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [1040, 80],
"parameters": { "jsCode": "__BUILD__:reuse-cached-classification.node.js" }
},
{
"id": "merge-consolidar-classificacoes",
"name": "Merge - Consolidar Classificacoes",
"type": "n8n-nodes-base.merge",
"typeVersion": 3.2,
"position": [2000, -160],
"parameters": { "mode": "append", "numberInputs": 3 }
},
{
"id": "code-calcular-score",
"name": "Code - Calcular Score",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [2240, -160],
"parameters": { "jsCode": "__BUILD__:compute-score.node.js" }
},
{
"id": "code-preparar-registro-memoria-analise",
"name": "Code - Preparar Registro Memoria Analise",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [2480, 160],
"parameters": { "jsCode": "__BUILD__:prepare-memoria-analise-record.node.js" }
},
{
"id": "datatable-upsert-memoria-analise",
"name": "Data Table - Upsert Memoria Analise",
"type": "n8n-nodes-base.dataTable",
"typeVersion": 1.1,
"position": [2720, 160],
"parameters": {
"resource": "row",
"operation": "upsert",
"dataTableId": { "mode": "name", "value": "coordenador_glpi_memoria" },
"filters": {
"conditions": [
{ "keyName": "ticket_id", "condition": "eq", "keyValue": "={{ $json.ticket_id }}" }
]
},
"columns": {
"mappingMode": "defineBelow",
"matchingColumns": ["ticket_id"],
"value": {
"ticket_id": "={{ $json.ticket_id }}",
"last_analyzed_at": "={{ $json.last_analyzed_at }}",
"last_context_hash": "={{ $json.last_context_hash }}",
"last_meaningful_change_at": "={{ $json.last_meaningful_change_at }}",
"ai_classification": "={{ $json.ai_classification }}",
"ai_confidence": "={{ $json.ai_confidence }}",
"blocker_type": "={{ $json.blocker_type }}",
"waiting_for": "={{ $json.waiting_for }}",
"next_action": "={{ $json.next_action }}",
"next_review_at": "={{ $json.next_review_at }}",
"last_score": "={{ $json.last_score }}",
"last_ai_reason": "={{ $json.last_ai_reason }}",
"updated_at": "={{ $json.updated_at }}"
}
}
}
},
{
"id": "code-selecionar-top10",
"name": "Code - Selecionar Top 10",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [2480, -320],
"parameters": { "jsCode": "__BUILD__:select-top10.node.js" }
},
{
"id": "code-preparar-registro-envio",
"name": "Code - Preparar Registro de Envio",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [2720, -560],
"parameters": { "jsCode": "__BUILD__:prepare-envio-record.node.js" }
},
{
"id": "datatable-registrar-envio",
"name": "Data Table - Registrar Envio",
"type": "n8n-nodes-base.dataTable",
"typeVersion": 1.1,
"position": [2960, -560],
"parameters": {
"resource": "row",
"operation": "upsert",
"dataTableId": { "mode": "name", "value": "coordenador_glpi_memoria" },
"filters": {
"conditions": [
{ "keyName": "ticket_id", "condition": "eq", "keyValue": "={{ $json.ticket_id }}" }
]
},
"columns": {
"mappingMode": "defineBelow",
"matchingColumns": ["ticket_id"],
"value": {
"ticket_id": "={{ $json.ticket_id }}",
"last_sent_at": "={{ $json.last_sent_at }}",
"times_sent": "={{ $json.times_sent }}",
"times_sent_30d": "={{ $json.times_sent_30d }}",
"consecutive_days_sent": "={{ $json.consecutive_days_sent }}",
"updated_at": "={{ $json.updated_at }}"
}
}
}
},
{
"id": "code-montar-mensagem-curta",
"name": "Code - Montar Mensagem Curta",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [2720, -320],
"parameters": { "jsCode": "__BUILD__:build-top-message.node.js" }
},
{
"id": "code-montar-digest-coordenacao",
"name": "Code - Montar Digest Coordenacao",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [2960, -320],
"parameters": { "jsCode": "__BUILD__:build-coordination-digest.node.js" }
},
{
"id": "merge-unir-shadow",
"name": "Merge - Unir Shadow",
"type": "n8n-nodes-base.merge",
"typeVersion": 3.2,
"position": [3200, 160],
"parameters": { "mode": "append", "numberInputs": 2 }
},
{
"id": "code-comparar-legacy-v2",
"name": "Code - Comparar Legacy x V2",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [3440, 160],
"parameters": { "jsCode": "__BUILD__:compare-legacy-v2.node.js" }
},
{
"id": "datatable-registrar-shadow-run",
"name": "Data Table - Registrar Shadow Run",
"type": "n8n-nodes-base.dataTable",
"typeVersion": 1.1,
"position": [3680, 160],
"parameters": {
"resource": "row",
"operation": "insert",
"dataTableId": { "mode": "name", "value": "coordenador_glpi_shadow_runs" },
"columns": {
"mappingMode": "defineBelow",
"value": {
"run_at": "={{ $json.run_at }}",
"legacy_ids": "={{ $json.legacy_ids }}",
"v2_ids": "={{ $json.v2_ids }}",
"added": "={{ $json.added }}",
"removed": "={{ $json.removed }}",
"summary": "={{ $json.summary }}"
}
}
}
}
],
"connections": {
"Manual Trigger": {
"main": [[{ "node": "Config - Coordenador GLPI v2", "type": "main", "index": 0 }]]
},
"Schedule Trigger - Dias uteis 08h (desligado em DEV)": {
"main": [[{ "node": "Config - Coordenador GLPI v2", "type": "main", "index": 0 }]]
},
"Config - Coordenador GLPI v2": {
"main": [[
{ "node": "Code - Montar SQL Candidatos", "type": "main", "index": 0 },
{ "node": "Code - Montar SQL Legado", "type": "main", "index": 0 },
{ "node": "Data Table - Buscar Memoria", "type": "main", "index": 0 }
]]
},
"Code - Montar SQL Candidatos": {
"main": [[{ "node": "MySQL - Buscar Candidatos", "type": "main", "index": 0 }]]
},
"Code - Montar SQL Legado": {
"main": [[{ "node": "MySQL - Legado Top 10 (Shadow)", "type": "main", "index": 0 }]]
},
"MySQL - Buscar Candidatos": {
"main": [[{ "node": "Code - Normalizar Candidatos Base", "type": "main", "index": 0 }]]
},
"Code - Normalizar Candidatos Base": {
"main": [[{ "node": "Code - Montar SQL Contexto", "type": "main", "index": 0 }]]
},
"Code - Montar SQL Contexto": {
"main": [[{ "node": "MySQL - Buscar Contexto", "type": "main", "index": 0 }]]
},
"MySQL - Buscar Contexto": {
"main": [[{ "node": "Code - Mesclar Contexto e Calcular Hash", "type": "main", "index": 0 }]]
},
"Code - Mesclar Contexto e Calcular Hash": {
"main": [[{ "node": "Merge - Aguardar Memoria", "type": "main", "index": 0 }]]
},
"Data Table - Buscar Memoria": {
"main": [[{ "node": "Merge - Aguardar Memoria", "type": "main", "index": 1 }]]
},
"Merge - Aguardar Memoria": {
"main": [[{ "node": "Code - Decidir Necessidade de IA", "type": "main", "index": 0 }]]
},
"Code - Decidir Necessidade de IA": {
"main": [[{ "node": "IF - Precisa IA?", "type": "main", "index": 0 }]]
},
"IF - Precisa IA?": {
"main": [
[{ "node": "IF - IA Ligada?", "type": "main", "index": 0 }],
[{ "node": "Code - Reusar Classificacao em Cache", "type": "main", "index": 0 }]
]
},
"IF - IA Ligada?": {
"main": [
[{ "node": "Code - Preparar Prompt IA", "type": "main", "index": 0 }],
[{ "node": "Code - Fallback IA Desligada", "type": "main", "index": 0 }]
]
},
"Code - Preparar Prompt IA": {
"main": [[{ "node": "HTTP - OpenAI Classificar Chamado", "type": "main", "index": 0 }]]
},
"HTTP - OpenAI Classificar Chamado": {
"main": [[{ "node": "Code - Validar Classificacao IA", "type": "main", "index": 0 }]]
},
"Code - Validar Classificacao IA": {
"main": [[{ "node": "Merge - Consolidar Classificacoes", "type": "main", "index": 0 }]]
},
"Code - Fallback IA Desligada": {
"main": [[{ "node": "Merge - Consolidar Classificacoes", "type": "main", "index": 1 }]]
},
"Code - Reusar Classificacao em Cache": {
"main": [[{ "node": "Merge - Consolidar Classificacoes", "type": "main", "index": 2 }]]
},
"Merge - Consolidar Classificacoes": {
"main": [[{ "node": "Code - Calcular Score", "type": "main", "index": 0 }]]
},
"Code - Calcular Score": {
"main": [[
{ "node": "Code - Selecionar Top 10", "type": "main", "index": 0 },
{ "node": "Code - Preparar Registro Memoria Analise", "type": "main", "index": 0 }
]]
},
"Code - Preparar Registro Memoria Analise": {
"main": [[{ "node": "Data Table - Upsert Memoria Analise", "type": "main", "index": 0 }]]
},
"Code - Selecionar Top 10": {
"main": [[
{ "node": "Code - Montar Mensagem Curta", "type": "main", "index": 0 },
{ "node": "Code - Preparar Registro de Envio", "type": "main", "index": 0 }
]]
},
"Code - Preparar Registro de Envio": {
"main": [[{ "node": "Data Table - Registrar Envio", "type": "main", "index": 0 }]]
},
"Code - Montar Mensagem Curta": {
"main": [[{ "node": "Code - Montar Digest Coordenacao", "type": "main", "index": 0 }]]
},
"Code - Montar Digest Coordenacao": {
"main": [[{ "node": "Merge - Unir Shadow", "type": "main", "index": 0 }]]
},
"MySQL - Legado Top 10 (Shadow)": {
"main": [[{ "node": "Merge - Unir Shadow", "type": "main", "index": 1 }]]
},
"Merge - Unir Shadow": {
"main": [[{ "node": "Code - Comparar Legacy x V2", "type": "main", "index": 0 }]]
},
"Code - Comparar Legacy x V2": {
"main": [[{ "node": "Data Table - Registrar Shadow Run", "type": "main", "index": 0 }]]
}
},
"pinData": {},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "",
"meta": {
"templateCredsSetupCompleted": false
},
"tags": []
}