{
  "name": "Auto Fix Scheduler",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 10
            }
          ]
        }
      },
      "id": "schedule",
      "name": "Every 10 min",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        240,
        304
      ]
    },
    {
      "parameters": {
        "resource": "issue",
        "operation": "getAll",
        "limit": 5,
        "options": {
          "jql": "project = __JIRA_PROJECT_KEY__ AND labels = \"ai:auto-fix\" AND status = BACKLOG ORDER BY created ASC"
        }
      },
      "id": "fetch-tickets",
      "name": "Fetch Tickets",
      "type": "n8n-nodes-base.jira",
      "typeVersion": 1,
      "position": [
        432,
        304
      ],
      "credentials": {
        "jiraSoftwareCloudApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "leftValue": "={{ $json.key }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "has-tickets",
      "name": "Has Tickets?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        608,
        304
      ]
    },
    {
      "parameters": {
        "jsCode": "const issue = $input.item.json;\nconst status = issue.fields?.status?.name || '';\nconst needsToDoTransition = status === 'Backlog';\nconst today = new Date().toISOString().split('T')[0];\nconst nextWeek = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0];\nreturn { json: { ...issue, needsToDoTransition, startDate: today, dueDate: nextWeek } };"
      },
      "id": "check-status",
      "name": "Check Status",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        784,
        304
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "leftValue": "={{ $json.needsToDoTransition }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "is-backlog",
      "name": "Is Backlog?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        960,
        304
      ]
    },
    {
      "parameters": {
        "resource": "issue",
        "operation": "update",
        "issueKey": "={{ $json.key }}",
        "updateFields": {
          "customFieldsUi": {
            "customFieldsValues": [
              {
                "fieldId": {
                  "value": "__JIRA_START_DATE_FIELD__",
                  "mode": "id"
                },
                "fieldValue": "={{ $json.startDate }}"
              },
              {
                "fieldId": {
                  "value": "duedate",
                  "mode": "id"
                },
                "fieldValue": "={{ $json.dueDate }}"
              }
            ]
          }
        }
      },
      "id": "set-dates",
      "name": "Set Dates",
      "type": "n8n-nodes-base.jira",
      "typeVersion": 1,
      "position": [
        1152,
        112
      ],
      "credentials": {
        "jiraSoftwareCloudApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "issue",
        "operation": "update",
        "issueKey": "={{ $('Check Status').item.json.key }}",
        "updateFields": {
          "customFieldsUi": {
            "customFieldsValues": [
              {
                "fieldId": {
                  "value": "__JIRA_START_DATE_FIELD__",
                  "mode": "id"
                },
                "fieldValue": "={{ $('Check Status').item.json.startDate }}"
              },
              {
                "fieldId": {
                  "value": "duedate",
                  "mode": "id"
                },
                "fieldValue": "={{ $('Check Status').item.json.dueDate }}"
              }
            ]
          },
          "statusId": "51"
        }
      },
      "id": "transition-to-todo",
      "name": "To Do",
      "type": "n8n-nodes-base.jira",
      "typeVersion": 1,
      "position": [
        1328,
        112
      ],
      "credentials": {
        "jiraSoftwareCloudApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "resource": "issue",
        "operation": "update",
        "issueKey": "={{ $('Check Status').item.json.key }}",
        "updateFields": {
          "statusId": "21"
        }
      },
      "id": "transition-in-progress",
      "name": "In Progress",
      "type": "n8n-nodes-base.jira",
      "typeVersion": 1,
      "position": [
        1504,
        320
      ],
      "credentials": {
        "jiraSoftwareCloudApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const issue = $('Check Status').item.json;\nconst prompt = `Auto-fix JIRA ticket\\n\\n**JIRA Key**: ${issue.key}\\n**Summary**: ${issue.fields?.summary || 'N/A'}`;\nreturn { json: { jira_key: issue.key, jira_summary: issue.fields?.summary, prompt } };"
      },
      "id": "build-prompt",
      "name": "Build Prompt",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1696,
        320
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "={{ $env.N8N_API_URL }}/v1/projects/system/chat",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ user_message: $json.prompt, agent: 'Auto Fixer', source: 'scheduler', requester: 'auto-fix-scheduler', metadata: { jira_key: $json.jira_key, workflow_execution_id: $executionId } }) }}",
        "options": {
          "timeout": 600000
        }
      },
      "id": "auto-fix",
      "name": "Auto Fix",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1872,
        320
      ],
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "jsCode": "const prev = $('Build Prompt').item.json;\nconst r = $input.item.json;\nlet res = { fixed: false, branch_name: '', commit_sha: '', summary: '', mr_title: '', mr_description: '', error: '' };\nif (r.status !== 'completed') res.error = r.error?.message || 'API error';\nelse if (r.structured_output) res = { ...res, ...r.structured_output };\nelse res.error = 'No structured output';\n\nconst reviewer_ids = '__AUTO_FIX_REVIEWER_IDS__'.split(',').filter(Boolean).map(Number);\n\nreturn { json: { ...prev, ...res, execution_id: r.id, reviewer_ids } };"
      },
      "id": "parse-result",
      "name": "Parse Result",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2048,
        320
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "leftValue": "={{ $json.fixed }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "is-fixed",
      "name": "Fixed?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        2224,
        320
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://__GITLAB_HOST__/api/v4/projects/__GITLAB_PROJECT_ENCODED__/merge_requests",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "httpHeaderAuth",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ source_branch: $json.branch_name, target_branch: 'main', title: $json.mr_title || `fix: [${$json.jira_key}] ${$json.jira_summary}`, description: $json.mr_description || `## Summary\\n[${$json.jira_key}] ${$json.summary}\\n\\n## Testing\\n- [x] compileKotlin\\n- [x] ktlintCheck\\n\\n---\\n_Auto-generated by AI Agent_`, remove_source_branch: true, reviewer_ids: $json.reviewer_ids }) }}",
        "options": {
          "timeout": 30000
        }
      },
      "id": "create-mr",
      "name": "Create MR",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        2400,
        192
      ],
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "jsCode": "const prev = $('Parse Result').item.json;\nconst mr = $input.item.json;\nconst mr_url = mr.web_url || null;\nconst mr_iid = mr.iid || null;\nreturn { json: { ...prev, mr_url, mr_iid } };"
      },
      "id": "parse-mr",
      "name": "Parse MR",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2592,
        192
      ]
    },
    {
      "parameters": {
        "resource": "issue",
        "operation": "update",
        "issueKey": "={{ $json.jira_key }}",
        "updateFields": {
          "statusId": "31"
        }
      },
      "id": "transition-resolved",
      "name": "Resolved",
      "type": "n8n-nodes-base.jira",
      "typeVersion": 1,
      "position": [
        2784,
        192
      ],
      "credentials": {
        "jiraSoftwareCloudApi": {
          "name": "<your credential>"
        }
      },
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "resource": "issue",
        "operation": "update",
        "issueKey": "={{ $('Parse MR').item.json.jira_key }}",
        "updateFields": {
          "labels": [
            "ai:auto-fixed"
          ]
        }
      },
      "id": "update-label-success",
      "name": "Label Success",
      "type": "n8n-nodes-base.jira",
      "typeVersion": 1,
      "position": [
        2976,
        192
      ],
      "credentials": {
        "jiraSoftwareCloudApi": {
          "name": "<your credential>"
        }
      },
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "resource": "issueComment",
        "operation": "add",
        "issueKey": "={{ $('Parse MR').item.json.jira_key }}",
        "comment": "=\ud83e\udd16 *Auto-fix completed*\n\n\u2022 Branch: {{$('Parse MR').item.json.branch_name}}\n\u2022 MR: {{$('Parse MR').item.json.mr_url || 'N/A'}}\n\u2022 Commit: {{$('Parse MR').item.json.commit_sha || 'N/A'}}\n\n{{$('Parse MR').item.json.summary}}"
      },
      "id": "jira-comment-success",
      "name": "Comment Success",
      "type": "n8n-nodes-base.jira",
      "typeVersion": 1,
      "position": [
        3168,
        192
      ],
      "credentials": {
        "jiraSoftwareCloudApi": {
          "name": "<your credential>"
        }
      },
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "resource": "issue",
        "operation": "update",
        "issueKey": "={{ $json.jira_key }}",
        "updateFields": {
          "labels": [
            "ai:auto-fix-failed"
          ]
        }
      },
      "id": "update-label-fail",
      "name": "Label Fail",
      "type": "n8n-nodes-base.jira",
      "typeVersion": 1,
      "position": [
        2400,
        416
      ],
      "credentials": {
        "jiraSoftwareCloudApi": {
          "name": "<your credential>"
        }
      },
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "resource": "issueComment",
        "operation": "add",
        "issueKey": "={{ $('Parse Result').item.json.jira_key }}",
        "comment": "=\ud83e\udd16 *Auto-fix failed*\n\n{{ $('Parse Result').item.json.error || $('Parse Result').item.json.summary || 'Unknown error' }}"
      },
      "id": "jira-comment-fail",
      "name": "Comment Fail",
      "type": "n8n-nodes-base.jira",
      "typeVersion": 1,
      "position": [
        2592,
        416
      ],
      "credentials": {
        "jiraSoftwareCloudApi": {
          "name": "<your credential>"
        }
      },
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "resource": "issue",
        "operation": "update",
        "issueKey": "={{ $('Parse Result').item.json.jira_key }}",
        "updateFields": {
          "statusId": "61"
        }
      },
      "id": "transition-back",
      "name": "Back to Backlog",
      "type": "n8n-nodes-base.jira",
      "typeVersion": 1,
      "position": [
        2784,
        416
      ],
      "credentials": {
        "jiraSoftwareCloudApi": {
          "name": "<your credential>"
        }
      },
      "onError": "continueRegularOutput"
    }
  ],
  "connections": {
    "Every 10 min": {
      "main": [
        [
          {
            "node": "Fetch Tickets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Tickets": {
      "main": [
        [
          {
            "node": "Has Tickets?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has Tickets?": {
      "main": [
        [
          {
            "node": "Check Status",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Check Status": {
      "main": [
        [
          {
            "node": "Is Backlog?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Backlog?": {
      "main": [
        [
          {
            "node": "Set Dates",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "In Progress",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Dates": {
      "main": [
        [
          {
            "node": "To Do",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "To Do": {
      "main": [
        [
          {
            "node": "In Progress",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "In Progress": {
      "main": [
        [
          {
            "node": "Build Prompt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Prompt": {
      "main": [
        [
          {
            "node": "Auto Fix",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Auto Fix": {
      "main": [
        [
          {
            "node": "Parse Result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Result": {
      "main": [
        [
          {
            "node": "Fixed?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fixed?": {
      "main": [
        [
          {
            "node": "Create MR",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Label Fail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create MR": {
      "main": [
        [
          {
            "node": "Parse MR",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse MR": {
      "main": [
        [
          {
            "node": "Resolved",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Resolved": {
      "main": [
        [
          {
            "node": "Label Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Label Success": {
      "main": [
        [
          {
            "node": "Comment Success",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Label Fail": {
      "main": [
        [
          {
            "node": "Comment Fail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Comment Fail": {
      "main": [
        [
          {
            "node": "Back to Backlog",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "callerPolicy": "workflowsFromSameOwner",
    "availableInMCP": false
  }
}