{
  "id": "b0ccb7be-5256-49a5-a3c6-5fa27971dd66",
  "name": "AIOps - Auto PR Generator",
  "versionId": "52005d78-7609-46a8-95f6-5dae27a8d589",
  "active": true,
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "alert",
        "options": {}
      },
      "id": "webhook",
      "name": "Webhook Alert",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [
        100,
        300
      ]
    },
    {
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{ $json.body.status }}",
              "operation": "equal",
              "value2": "firing"
            }
          ]
        }
      },
      "id": "filter-status",
      "name": "Es Firing?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        300,
        300
      ]
    },
    {
      "parameters": {
        "values": {
          "string": [
            {
              "name": "github_token",
              "value": "={{ $env.GITHUB_TOKEN }}"
            },
            {
              "name": "owner",
              "value": "={{ $env.GITHUB_OWNER }}"
            },
            {
              "name": "repo",
              "value": "={{ $env.GITHUB_REPO }}"
            },
            {
              "name": "path",
              "value": "={{ $env.GITHUB_FILE_PATH }}"
            },
            {
              "name": "branch_name",
              "value": "=fix/incident-{{ $now.format('x') }}"
            }
          ]
        }
      },
      "id": "config",
      "name": "CONFIGURACION",
      "type": "n8n-nodes-base.set",
      "typeVersion": 2,
      "position": [
        500,
        300
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://slack.com/api/chat.postMessage",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer {{ $env.SLACK_BOT_TOKEN }}"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "channel",
              "value": "={{ $env.SLACK_CHANNEL_ID }}"
            },
            {
              "name": "text",
              "value": "=\ud83d\udd25 *ALERTA CR\u00cdTICA DETECTADA*\n\nGrafana reporta:\n```\n{{ $('Webhook Alert').item.json.body.alerts[0].annotations.description }}\n```\n\n\ud83d\udd75\ufe0f\u200d\u2642\ufe0f _Iniciando protocolo de auto-remediaci\u00f3n..._"
            }
          ]
        },
        "options": {}
      },
      "id": "slack-alert",
      "name": "Publicar Alerta Inicial",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        700,
        300
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "=https://api.github.com/repos/{{ $('CONFIGURACION').item.json.owner }}/{{ $('CONFIGURACION').item.json.repo }}/contents/{{ $('CONFIGURACION').item.json.path }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=token {{ $('CONFIGURACION').item.json.github_token }}"
            },
            {
              "name": "Accept",
              "value": "application/vnd.github.v3+json"
            }
          ]
        },
        "options": {}
      },
      "id": "get-code",
      "name": "Leer Codigo Actual",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        900,
        300
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "=https://api.github.com/repos/{{ $('CONFIGURACION').item.json.owner }}/{{ $('CONFIGURACION').item.json.repo }}/contents/AGENTS.md",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=token {{ $('CONFIGURACION').item.json.github_token }}"
            },
            {
              "name": "Accept",
              "value": "application/vnd.github.v3+json"
            }
          ]
        },
        "options": {},
        "onError": "continueRegularOutput"
      },
      "id": "get-agents-md",
      "name": "Leer Reglas (AGENTS.md)",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        1100,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "// --- DEBUGGING Y LIMPIEZA ---\n// 1. Obtener inputs\nconst fileData = $('Leer Codigo Actual').item.json;\nconst alertData = $('Webhook Alert').item.json;\nconst rulesData = $('Leer Reglas (AGENTS.md)').item.json;\n\n// 2. Decodificar Base64 de forma segura\nconst sourceCode = Buffer.from(fileData.content, 'base64').toString('utf-8');\nconst errorMsg = alertData.body.alerts[0].annotations.description;\n\n// 3. Procesar Reglas (Si existen)\nlet contextRules = \"Sin reglas especificas. Aplica mejores practicas generales.\";\nif (rulesData && rulesData.content) {\n  contextRules = Buffer.from(rulesData.content, 'base64').toString('utf-8');\n}\n\n// 4. Construir el Prompt con CONTEXTO\nconst promptText = `Eres un experto desarrollador senior del proyecto ATLAS. Tu trabajo es arreglar el c\u00f3digo siguiendo estrictamente las reglas de arquitectura.\n\n--- REGLAS DEL PROYECTO (AGENTS.MD) ---\n${contextRules}\n\n--- CODIGO ORIGINAL ---\n${sourceCode}\n\n--- ERROR REPORTADO ---\n${errorMsg}\n\n--- INSTRUCCION ---\nAnaliza el error y el c\u00f3digo. DEBES RESPONDER SOLO UN JSON VALIDO (sin markdown ni explicacion previa). Formato estricto: { \"explanation\": \"breve explicacion citando qu\u00e9 regla se aplic\u00f3\", \"fixed_code\": \"codigo completo corregido\" }.`;\n\n// 5. Retornar\nreturn {\n  geminiPayload: {\n    contents: [\n      {\n        parts: [\n          { text: promptText }\n        ]\n      }\n    ]\n  },\n  originalSha: fileData.sha\n};"
      },
      "id": "prepare-prompt",
      "name": "Preparar Prompt Seguro",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1300,
        300
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key={{ $env.GEMINI_API_KEY }}",
        "sendBody": true,
        "contentType": "json",
        "specifyBody": "json",
        "jsonBody": "={{ $json.geminiPayload }}",
        "options": {}
      },
      "id": "gemini",
      "name": "Analizar y Corregir",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        1500,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "const raw = $input.item.json.candidates[0].content.parts[0].text;\nconst clean = raw.replace(/```json/g, '').replace(/```/g, '').trim();\nconst parsed = JSON.parse(clean);\n\n// Codificar a Base64 para GitHub\nconst contentBase64 = Buffer.from(parsed.fixed_code).toString('base64');\n\nreturn {\n  explanation: parsed.explanation,\n  fixed_code: parsed.fixed_code,\n  content_base64: contentBase64,\n  base_sha: $('Preparar Prompt Seguro').item.json.originalSha\n};"
      },
      "id": "parse-json",
      "name": "Parsear JSON Gemini",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1700,
        300
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "=https://api.github.com/repos/{{ $('CONFIGURACION').item.json.owner }}/{{ $('CONFIGURACION').item.json.repo }}/git/ref/heads/main",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=token {{ $('CONFIGURACION').item.json.github_token }}"
            }
          ]
        },
        "options": {}
      },
      "id": "get-main-sha",
      "name": "Obtener SHA Main",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        1900,
        200
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://api.github.com/repos/{{ $('CONFIGURACION').item.json.owner }}/{{ $('CONFIGURACION').item.json.repo }}/git/refs",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=token {{ $('CONFIGURACION').item.json.github_token }}"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "ref",
              "value": "=refs/heads/{{ $('CONFIGURACION').item.json.branch_name }}"
            },
            {
              "name": "sha",
              "value": "={{ $json.object.sha }}"
            }
          ]
        },
        "options": {}
      },
      "id": "create-branch",
      "name": "Crear Rama Fix",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        2100,
        300
      ]
    },
    {
      "parameters": {
        "method": "PUT",
        "url": "=https://api.github.com/repos/{{ $('CONFIGURACION').item.json.owner }}/{{ $('CONFIGURACION').item.json.repo }}/contents/{{ $('CONFIGURACION').item.json.path }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=token {{ $('CONFIGURACION').item.json.github_token }}"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "message",
              "value": "=fix: automated patch by AIOps"
            },
            {
              "name": "content",
              "value": "={{ $('Parsear JSON Gemini').item.json.content_base64 }}"
            },
            {
              "name": "branch",
              "value": "={{ $('CONFIGURACION').item.json.branch_name }}"
            },
            {
              "name": "sha",
              "value": "={{ $('Parsear JSON Gemini').item.json.base_sha }}"
            }
          ]
        },
        "options": {}
      },
      "id": "commit-file",
      "name": "Commit Fix",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        2300,
        300
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://api.github.com/repos/{{ $('CONFIGURACION').item.json.owner }}/{{ $('CONFIGURACION').item.json.repo }}/pulls",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=token {{ $('CONFIGURACION').item.json.github_token }}"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "title",
              "value": "=\ud83d\ude91 Fix: Incidente Detectado por AIOps"
            },
            {
              "name": "body",
              "value": "=### Reporte de Incidente Autom\u00e1tico\n\n**An\u00e1lisis de IA:**\n{{ $('Parsear JSON Gemini').item.json.explanation }}\n\nEste PR aplica la correcci\u00f3n sugerida autom\u00e1ticamente."
            },
            {
              "name": "head",
              "value": "={{ $('CONFIGURACION').item.json.branch_name }}"
            },
            {
              "name": "base",
              "value": "main"
            }
          ]
        },
        "options": {}
      },
      "id": "create-pr",
      "name": "Crear PR",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        2500,
        300
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://slack.com/api/chat.postMessage",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer {{ $env.SLACK_BOT_TOKEN }}"
            }
          ]
        },
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "channel",
              "value": "={{ $env.SLACK_CHANNEL_ID }}"
            },
            {
              "name": "text",
              "value": "=\u2705 *PR Creado con \u00c9xito*\n\nLa IA ha analizado el error y las reglas de `AGENTS.md`.\n\n\ud83d\udd17 *Ver Pull Request:*\n{{ $json.html_url }}"
            },
            {
              "name": "thread_ts",
              "value": "={{ $('Publicar Alerta Inicial').item.json.ts }}"
            }
          ]
        },
        "options": {}
      },
      "id": "slack-reply",
      "name": "Responder en Hilo",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        2700,
        300
      ]
    }
  ],
  "connections": {
    "Webhook Alert": {
      "main": [
        [
          {
            "node": "Es Firing?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Es Firing?": {
      "main": [
        [
          {
            "node": "CONFIGURACION",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "CONFIGURACION": {
      "main": [
        [
          {
            "node": "Publicar Alerta Inicial",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Publicar Alerta Inicial": {
      "main": [
        [
          {
            "node": "Leer Codigo Actual",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Leer Codigo Actual": {
      "main": [
        [
          {
            "node": "Leer Reglas (AGENTS.md)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Leer Reglas (AGENTS.md)": {
      "main": [
        [
          {
            "node": "Preparar Prompt Seguro",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Preparar Prompt Seguro": {
      "main": [
        [
          {
            "node": "Analizar y Corregir",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Analizar y Corregir": {
      "main": [
        [
          {
            "node": "Parsear JSON Gemini",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parsear JSON Gemini": {
      "main": [
        [
          {
            "node": "Obtener SHA Main",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Obtener SHA Main": {
      "main": [
        [
          {
            "node": "Crear Rama Fix",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Crear Rama Fix": {
      "main": [
        [
          {
            "node": "Commit Fix",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Commit Fix": {
      "main": [
        [
          {
            "node": "Crear PR",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Crear PR": {
      "main": [
        [
          {
            "node": "Responder en Hilo",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}