AutomationFlowsWeb Scraping › Jira Allure Auto Qa

Jira Allure Auto Qa

Jira-Allure-Auto-Qa. Uses httpRequest, jira. Scheduled trigger; 68 nodes.

Cron / scheduled trigger★★★★★ complexity68 nodesHTTP RequestJira
Web Scraping Trigger: Cron / scheduled Nodes: 68 Complexity: ★★★★★ Added:

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "nodes": [
    {
      "parameters": {
        "jsCode": "const data = $input.first().json;\n\nconst systemPrompt = `\u0422\u044b QA-\u0438\u043d\u0436\u0435\u043d\u0435\u0440 \u043a\u043e\u043c\u0430\u043d\u0434\u044b your-company.example.com \u2014 \u043c\u0430\u0440\u043a\u0435\u0442\u043f\u043b\u0435\u0439\u0441 \u0431\u0430\u043d\u043a\u043e\u0432\u0441\u043a\u0438\u0445 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432.\n\n\u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0439 \u0442\u0435\u0441\u0442-\u043a\u0435\u0439\u0441\u044b \u0441\u0442\u0440\u043e\u0433\u043e \u043f\u043e \u041d\u0410\u0428\u0418\u041c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430\u043c (\u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0438\u0437 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u0422\u041a).\n\n---\n\n## \u0421\u0422\u0410\u041d\u0414\u0410\u0420\u0422 \u041d\u0410\u0417\u0412\u0410\u041d\u0418\u042f\n\n### \u0424\u043e\u0440\u043c\u0430\u0442 \u0434\u043b\u044f API:\n\\`/endpoint - [\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u044f]\\`\n\n### \u041f\u0440\u0438\u043c\u0435\u0440\u044b \u0438\u0437 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0430:\n\u2705 \"/applicationProcessDeposit - \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0437\u0430\u0432\u0438\u0441\u0448\u0438\u0445 \u0437\u0430\u044f\u0432\u043e\u043a \u043d\u0430 \u0434\u0435\u043f\u043e\u0437\u0438\u0442\"\n\u2705 \"/confirmCourierMeeting - \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0432\u0441\u0442\u0440\u0435\u0447\u0438 \u043f\u0440\u0438 \u043d\u0435\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c userId\"\n\u2705 \"/earlyTermination - \u0412\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0432 \u0442\u0435\u043b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\"\n\u2705 \"/getDeliverySlots - \u0417\u0430\u043f\u0440\u043e\u0441 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e \u0441\u043b\u043e\u0442\u0430\u043c \u043f\u0440\u0438 \u043d\u0435\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c leadId\"\n\u2705 \"/depositAccount - \u0417\u0430\u043f\u0440\u043e\u0441 \u0440\u0435\u043a\u0432\u0438\u0437\u0438\u0442\u043e\u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043f\u043e leadId \u0441 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c \u0434\u043e\u0433\u043e\u0432\u043e\u0440\u043e\u043c\"\n\n### \u0424\u043e\u0440\u043c\u0430\u0442 \u0434\u043b\u044f \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432/Consumer:\n\\`[\u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442/\u041f\u0440\u043e\u0446\u0435\u0441\u0441] - [\u0421\u0446\u0435\u043d\u0430\u0440\u0438\u0439]\\`\n\n\u2705 \"CONSUMER bankApiGate/application/process/deposit - \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0437\u0430\u0432\u0438\u0441\u0448\u0438\u0445 \u0437\u0430\u044f\u0432\u043e\u043a\"\n\u2705 \"EOD-\u043f\u0440\u043e\u0446\u0435\u0434\u0443\u0440\u0430 - \u0423\u0441\u043f\u0435\u0448\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0441\u0447\u0451\u0442 \u043e\u0441\u0442\u0430\u0442\u043a\u043e\u0432 \u0437\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0434\u0435\u043d\u044c\"\n\n### \u0414\u043b\u044f \u043d\u0435\u0433\u0430\u0442\u0438\u0432\u043d\u044b\u0445:\n\\`/endpoint - [\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435] \u043f\u0440\u0438 [\u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u0435]\\`\n\n\u2705 \"/confirmCourierMeeting - \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0432\u0441\u0442\u0440\u0435\u0447\u0438 \u043f\u0440\u0438 \u043d\u0435\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c userId\"\n\u2705 \"/getClientIdByAuthProvider - \u041f\u043e\u0438\u0441\u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043f\u043e userId \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0445 \u0434\u043b\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439\"\n\n---\n\n## \u0421\u0422\u0410\u041d\u0414\u0410\u0420\u0422 \u041e\u041f\u0418\u0421\u0410\u041d\u0418\u042f\n\n### \u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430:\n1. \u041e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0435 \u0447\u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f (1-2 \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u0438\u044f)\n2. \u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e Confluence (\u041e\u0411\u042f\u0417\u0410\u0422\u0415\u041b\u042c\u041d\u041e \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c)\n\n### \u041f\u0440\u0438\u043c\u0435\u0440\u044b \u0438\u0437 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0430:\n\u2705 \"\u0422\u0435\u0441\u0442-\u043a\u0435\u0439\u0441 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u044c \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043b\u043e\u0433\u043e\u0442\u0438\u043f\u0430 \u0411\u0430\u043d\u043a\u0430 \u0432 \u0438\u0441\u0442\u043e\u0440\u0438\u0438 \u043f\u043e\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u044f \u0434\u0435\u043d\u0435\u0436\u043d\u044b\u0445 \u0441\u0440\u0435\u0434\u0441\u0442\u0432.\"\n\n\u2705 \"\u0422\u0435\u0441\u0442-\u043a\u0435\u0439\u0441 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0439 userId \u0432 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u0445 \u0442\u0435\u043b\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445.\n\n[\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f /confirmCourierMeeting](https://your-confluence.example.com/pages/viewpage.action?pageId=18944396)\"\n\n\u2705 \"\u0422\u0435\u0441\u0442-\u043a\u0435\u0439\u0441 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044e \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043d\u0430 \u043f\u0440\u0435\u0434\u043c\u0435\u0442 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432: userId, leadId, bik.\n\n[\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f /earlyTermination](https://your-confluence.example.com/pages/viewpage.action?pageId=18943904)\"\n\n### \u0428\u0430\u0431\u043b\u043e\u043d:\n\"\u0422\u0435\u0441\u0442-\u043a\u0435\u0439\u0441 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c [\u0447\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f].\n\n[\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f [\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435]](CONFLUENCE_URL)\"\n\n---\n\n## \u0421\u0422\u0410\u041d\u0414\u0410\u0420\u0422 \u041f\u0420\u0415\u0414\u0423\u0421\u041b\u041e\u0412\u0418\u042f\n\n### \u0427\u0442\u043e \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c:\n1. \u0421\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0435 \u043a\u0435\u0439\u0441\u044b \u2014 \"[\u0442\u0435\u043a\u0441\u0442](https://your-services.example.comst-cases/XXXXX)\"\n2. \u0414\u0430\u043d\u043d\u044b\u0435 \u0432 \u0411\u0414 \u2014 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b, \u043f\u043e\u043b\u044f, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\n3. \u0421\u0442\u0430\u0442\u0443\u0441\u044b \u2014 \u043a\u043b\u0438\u0435\u043d\u0442\u0430, \u0437\u0430\u044f\u0432\u043a\u0438, \u0434\u043e\u0433\u043e\u0432\u043e\u0440\u0430\n4. \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u2014 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u0435 \u0442\u043e\u0433\u043b\u044b, \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f\n5. \u041d\u0443\u043c\u0435\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u2014 \u043a\u0430\u0436\u0434\u043e\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0441 \u0446\u0438\u0444\u0440\u043e\u0439\n\n### \u041f\u0440\u0438\u043c\u0435\u0440\u044b \u0438\u0437 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0430:\n\n\u2705 \"1. \u0412\u043a\u043b\u044e\u0447\u0435\u043d \u0442\u043e\u0433\u0433\u043b [IDENTITY_PARTNER_CODE_ALWAYS_FD_ENABLED](https://your-services.example.comsole/index);\n2. \u0421\u043e\u0437\u0434\u0430\u043d\u0430 \u0434\u0435\u043f\u043e\u0437\u0438\u0442\u043d\u0430\u044f \u0437\u0430\u044f\u0432\u043a\u0430 \u0432 \u043b\u044e\u0431\u043e\u0439 \u0431\u0430\u043d\u043a;\n3. \u0414\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 midb.core_client_data \u0437\u0430\u0434\u0430\u0442\u044c \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043f\u043e\u043b\u044f user_id.\"\n\n\u2705 \"1. \u0412\u044b\u043f\u043e\u043b\u043d\u0435\u043d \u043a\u0435\u0439\u0441 \u0430\u043a\u0442\u0438\u0432\u0430\u0446\u0438\u0438 \u0434\u043e\u0433\u043e\u0432\u043e\u0440\u0430, \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0430 \u0437\u0430\u044f\u0432\u043a\u0430 \u0432 \u0441\u0442\u0430\u0442\u0443\u0441\u0435 OFFER_SELECTED.\n2. \u0417\u0430\u044f\u0432\u043a\u0430 \u043d\u0435 \u0441\u0442\u0430\u0440\u0448\u0435 45 \u0434\u043d\u0435\u0439 \u0438 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u044f\u0432\u043a\u043e\u0439 \u043d\u0430 \u043f\u0440\u043e\u043b\u043e\u043d\u0433\u0430\u0446\u0438\u044e.\n3. \u041a\u043b\u0438\u0435\u043d\u0442 \u0438\u043c\u0435\u0435\u0442 \u0441\u0442\u0430\u0442\u0443\u0441: recordStatus=ACTIVE, identificationsStatus=FULL_IDENT.\"\n\n\u2705 \u0414\u043b\u044f \u043d\u0435\u0433\u0430\u0442\u0438\u0432\u043d\u044b\u0445: null \u2014 \u0435\u0441\u043b\u0438 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438.\n\n---\n\n## \u0421\u0422\u0410\u041d\u0414\u0410\u0420\u0422 \u0428\u0410\u0413\u041e\u0412\n\n### \u0424\u043e\u0440\u043c\u0430\u0442 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0448\u0430\u0433\u0430:\n\"[\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435] \u2192 [\u041e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442]\"\n\n### \u041f\u0440\u0438\u043c\u0435\u0440\u044b:\n\"\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c POST /depositAccount \u0441 leadId \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0434\u043e\u0433\u043e\u0432\u043e\u0440\u0430 \u2192 \u041a\u043e\u0434 \u043e\u0442\u0432\u0435\u0442\u0430 200, \u0432 \u043e\u0442\u0432\u0435\u0442\u0435 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0440\u0435\u043a\u0432\u0438\u0437\u0438\u0442\u044b\"\n\"\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c POST /confirmCourierMeeting \u0441 \u043d\u0435\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c userId \u2192 \u041a\u043e\u0434 \u043e\u0448\u0438\u0431\u043a\u0438 400, \u0442\u0435\u043a\u0441\u0442 \u043e\u0448\u0438\u0431\u043a\u0438 USER_NOT_FOUND\"\n\"\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u044c \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 portfolio_fee_EOD \u0434\u043b\u044f \u0414\u043e\u0433\u043e\u0432\u043e\u0440\u0430 \u0410 \u2192 \u0417\u0430\u043f\u0438\u0441\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0430, balance=800\"\n\n---\n\n## \u041f\u0420\u0410\u0412\u0418\u041b\u0410 \u0413\u0415\u041d\u0415\u0420\u0410\u0426\u0418\u0418\n\n### \u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e: 8-12 \u0442\u0435\u0441\u0442-\u043a\u0435\u0439\u0441\u043e\u0432\n\n### \u0422\u0438\u043f\u044b (\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e):\n1. **Happy path** (2-3 \u043a\u0435\u0439\u0441\u0430) \u2014 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u044b\u0435 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0438\n2. **Negative** (3-4 \u043a\u0435\u0439\u0441\u0430) \u2014 \u043d\u0435\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 ID, \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u0441\u0442\u0430\u0442\u0443\u0441\u044b, \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432\n3. **Validation** (2-3 \u043a\u0435\u0439\u0441\u0430) \u2014 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u043b\u0435\u0439, \u0444\u043e\u0440\u043c\u0430\u0442\u043e\u0432, \u0433\u0440\u0430\u043d\u0438\u0447\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439\n4. **Edge cases** (1-2 \u043a\u0435\u0439\u0441\u0430) \u2014 \u0433\u0440\u0430\u043d\u0438\u0447\u043d\u044b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u0434\u0443\u0431\u043b\u0438, \u0433\u043e\u043d\u043a\u0438\n\n### \u0412\u0441\u0435\u0433\u0434\u0430:\n- \u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 Confluence \u0432 description \u041a\u0410\u0416\u0414\u041e\u0413\u041e \u0442\u0435\u0441\u0442-\u043a\u0435\u0439\u0441\u0430 (\u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f)\n- \u041a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438\u0437 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 (\u043d\u0435 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0435)\n- \u041a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0438\u043c\u0435\u043d\u0430 \u0442\u0430\u0431\u043b\u0438\u0446 \u0411\u0414, \u0441\u0442\u0430\u0442\u0443\u0441\u044b, \u043a\u043e\u0434\u044b \u043e\u0448\u0438\u0431\u043e\u043a \u0438\u0437 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438\n- Steps: \u043c\u0438\u043d\u0438\u043c\u0443\u043c 3, \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u043e 5-7, \u0447\u0435\u0440\u0435\u0437 \"\u2192\"\n\n---\n\n## PRODUCTION \u041f\u0420\u0418\u041c\u0415\u0420\u042b\n\n### \u041f\u0440\u0438\u043c\u0435\u0440 1: API Happy Path\n{\n  \"name\": \"/depositAccount - \u0417\u0430\u043f\u0440\u043e\u0441 \u0440\u0435\u043a\u0432\u0438\u0437\u0438\u0442\u043e\u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043f\u043e leadId \u0441 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c \u0434\u043e\u0433\u043e\u0432\u043e\u0440\u043e\u043c\",\n  \"description\": \"\u0422\u0435\u0441\u0442-\u043a\u0435\u0439\u0441 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u044b \u043c\u0435\u0442\u043e\u0434\u0430 \u043f\u0440\u0438 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u0440\u0435\u043a\u0432\u0438\u0437\u0438\u0442\u043e\u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0430.\\n\\n[\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f /depositAccount](https://your-confluence.example.com/pages/viewpage.action?pageId=18944483)\",\n  \"preconditions\": \"\u0421\u043e\u0437\u0434\u0430\u043d\u0430 \u0434\u0435\u043f\u043e\u0437\u0438\u0442\u043d\u0430\u044f \u0437\u0430\u044f\u0432\u043a\u0430 \u0438 \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043d \u0434\u043e\u0433\u043e\u0432\u043e\u0440, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u0431\u0430\u043d\u043a\u0430 \u0421\u0438\u043d\u0430\u0440\u0430.\",\n  \"steps\": [\n    \"\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c POST /depositAccount \u0441 leadId \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0434\u043e\u0433\u043e\u0432\u043e\u0440\u0430 \u2192 \u041a\u043e\u0434 \u043e\u0442\u0432\u0435\u0442\u0430 200\",\n    \"\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043f\u043e\u043b\u0435\u0439 accountNumber, bik, bankName \u0432 \u0442\u0435\u043b\u0435 \u043e\u0442\u0432\u0435\u0442\u0430 \u2192 \u0412\u0441\u0435 \u043f\u043e\u043b\u044f \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0438 \u043d\u0435 \u043f\u0443\u0441\u0442\u044b\u0435\",\n    \"\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u044c \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 midb.deposit_account \u2192 \u0417\u0430\u043f\u0438\u0441\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043e\u0442\u0432\u0435\u0442\u0443 API\"\n  ],\n  \"expectedResult\": \"\u041c\u0435\u0442\u043e\u0434 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0435 \u0440\u0435\u043a\u0432\u0438\u0437\u0438\u0442\u044b \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0441 \u043a\u043e\u0434\u043e\u043c 200\"\n}\n\n### \u041f\u0440\u0438\u043c\u0435\u0440 2: Negative\n{\n  \"name\": \"/confirmCourierMeeting - \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0432\u0441\u0442\u0440\u0435\u0447\u0438 \u043f\u0440\u0438 \u043d\u0435\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c userId\",\n  \"description\": \"\u0422\u0435\u0441\u0442-\u043a\u0435\u0439\u0441 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0439 userId \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432 \u0431\u0430\u0437\u0435 \u0434\u0430\u043d\u043d\u044b\u0445.\\n\\n[\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f /confirmCourierMeeting](https://your-confluence.example.com/pages/viewpage.action?pageId=18944396)\",\n  \"preconditions\": null,\n  \"steps\": [\n    \"\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c POST /confirmCourierMeeting \u0441 userId=999999999 (\u043d\u0435\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439) \u2192 \u041a\u043e\u0434 \u043e\u0442\u0432\u0435\u0442\u0430 400 \u0438\u043b\u0438 404\",\n    \"\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0442\u0435\u043b\u043e \u043e\u0442\u0432\u0435\u0442\u0430 \u2192 \u0421\u043e\u0434\u0435\u0440\u0436\u0438\u0442 errorCode=USER_NOT_FOUND \u0438\u043b\u0438 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0439 \u043a\u043e\u0434 \u0438\u0437 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438\",\n    \"\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0447\u0442\u043e \u0437\u0430\u043f\u0438\u0441\u044c \u043e \u0432\u0441\u0442\u0440\u0435\u0447\u0435 \u041d\u0415 \u0441\u043e\u0437\u0434\u0430\u043d\u0430 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 midb.courier_meeting \u2192 \u0417\u0430\u043f\u0438\u0441\u0438 \u043d\u0435\u0442\"\n  ],\n  \"expectedResult\": \"\u041c\u0435\u0442\u043e\u0434 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0443 \u0441 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c, \u0432\u0441\u0442\u0440\u0435\u0447\u0430 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f\"\n}\n\n### \u041f\u0440\u0438\u043c\u0435\u0440 3: Validation\n{\n  \"name\": \"/earlyTermination - \u0412\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0432 \u0442\u0435\u043b\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\",\n  \"description\": \"\u0422\u0435\u0441\u0442-\u043a\u0435\u0439\u0441 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044e \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430: \u043f\u043e\u043b\u044f userId, leadId, bik \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b.\\n\\n[\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f /earlyTermination](https://your-confluence.example.com/pages/viewpage.action?pageId=18943904)\",\n  \"preconditions\": null,\n  \"steps\": [\n    \"\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c POST /earlyTermination \u0431\u0435\u0437 \u043f\u043e\u043b\u044f userId \u2192 \u041a\u043e\u0434 \u043e\u0442\u0432\u0435\u0442\u0430 400, \u043e\u0448\u0438\u0431\u043a\u0430 VALIDATION_ERROR\",\n    \"\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c POST /earlyTermination \u0431\u0435\u0437 \u043f\u043e\u043b\u044f leadId \u2192 \u041a\u043e\u0434 \u043e\u0442\u0432\u0435\u0442\u0430 400, \u043e\u0448\u0438\u0431\u043a\u0430 VALIDATION_ERROR\",\n    \"\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c POST /earlyTermination \u0431\u0435\u0437 bik \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 accountNumber \u2192 \u041a\u043e\u0434 \u043e\u0442\u0432\u0435\u0442\u0430 400\",\n    \"\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c POST /earlyTermination \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u043f\u043e\u043b\u044f\u043c\u0438 \u2192 \u041a\u043e\u0434 \u043e\u0442\u0432\u0435\u0442\u0430 200\"\n  ],\n  \"expectedResult\": \"\u041f\u0440\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u043c\u0435\u0442\u043e\u0434 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 400. \u041f\u0440\u0438 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u2014 200\"\n}\n\n---\n\n\u0412\u042b\u0425\u041e\u0414\u041d\u041e\u0419 \u0424\u041e\u0420\u041c\u0410\u0422 \u2014 \u0422\u041e\u041b\u042c\u041a\u041e \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0439 JSON \u0431\u0435\u0437 markdown:\n{\n  \"testCases\": [\n    {\n      \"name\": \"...\",\n      \"description\": \"...\",\n      \"preconditions\": \"...\" | null,\n      \"steps\": [\"action \u2192 expected\", \"...\"],\n      \"expectedResult\": \"...\"\n    }\n  ]\n}\n\n\u0412\u0410\u0416\u041d\u041e:\n- \u0420\u041e\u0412\u041d\u041e \u044d\u0442\u043e\u0442 \u0444\u043e\u0440\u043c\u0430\u0442, \u0431\u0435\u0437 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u043b\u0435\u0439\n- description \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \\\\n \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u043e\u0432 \u0441\u0442\u0440\u043e\u043a\n- preconditions \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c null\n- steps \u2014 \u043c\u0430\u0441\u0441\u0438\u0432 \u0441\u0442\u0440\u043e\u043a, \u043a\u0430\u0436\u0434\u044b\u0439 \u0448\u0430\u0433 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \"\u2192\" \u0434\u043b\u044f \u043e\u0442\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\n- \u041d\u0415 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0439 markdown-\u043e\u0431\u0451\u0440\u0442\u043a\u0438 \\`\\`\\`json\n- \u0412\u0421\u0415\u0413\u0414\u0410 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0439 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 Confluence \u0432 description \u0435\u0441\u043b\u0438 \u043e\u043d\u0430 \u0435\u0441\u0442\u044c \u0432 \u0437\u0430\u043f\u0440\u043e\u0441\u0435`;\n\nconst userPrompt = `\u0420\u041e\u0414\u0418\u0422\u0415\u041b\u042c\u0421\u041a\u0410\u042f \u0417\u0410\u0414\u0410\u0427\u0410: ${data.parentKey} - ${data.parentSummary}\n\n\u041e\u041f\u0418\u0421\u0410\u041d\u0418\u0415 \u0417\u0410\u0414\u0410\u0427\u0418:\n${data.parentDescription || '(\u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442)'}\n\n${data.confluenceUrl ? `\u0414\u041e\u041a\u0423\u041c\u0415\u041d\u0422\u0410\u0426\u0418\u042f (Confluence):\n${data.allConfluenceUrls || data.confluenceUrl}\n` : ''}${data.confluenceContent ? `\\n\ud83d\udcc4 \u0421\u041e\u0414\u0415\u0420\u0416\u0418\u041c\u041e\u0415 \u0414\u041e\u041a\u0423\u041c\u0415\u041d\u0422\u0410\u0426\u0418\u0418:\\n${data.confluenceContent}\\n\\n---\\n\\n\u26a0\ufe0f \u041e\u0411\u042f\u0417\u0410\u0422\u0415\u041b\u042c\u041d\u041e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439 \u044d\u0442\u0443 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e! \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0439 \u0441\u0441\u044b\u043b\u043a\u0443 ${data.confluenceUrl} \u0432 description \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0422\u041a.\\n\u0418\u0437\u0432\u043b\u0435\u043a\u0430\u0439 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 endpoints, \u043a\u043e\u0434\u044b \u043e\u0448\u0438\u0431\u043e\u043a, \u0441\u0442\u0430\u0442\u0443\u0441\u044b, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0435\u0439 \u0438\u0437 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0432\u044b\u0448\u0435.\\n` : `\\n\u26a0\ufe0f \u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f Confluence \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430 \u2014 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0439 \u0422\u041a \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438.\\n`}\n\u041f\u041e\u0414\u0417\u0410\u0414\u0410\u0427\u0410 QA: ${data.subtaskKey} - ${data.subtaskSummary}\n\n\u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0439 8-12 \u0442\u0435\u0441\u0442-\u043a\u0435\u0439\u0441\u043e\u0432:\n- 2-3 happy path\n- 3-4 negative (\u043d\u0435\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 ID, \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432, \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u0441\u0442\u0430\u0442\u0443\u0441\u044b)\n- 2-3 validation (\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u043b\u0435\u0439, \u0444\u043e\u0440\u043c\u0430\u0442\u044b, \u0433\u0440\u0430\u043d\u0438\u0446\u044b)\n- 1-2 edge cases\n\n\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439 \u041d\u0410\u0428\u0418 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u044b \u0438\u0437 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0432\u044b\u0448\u0435!`;\n\nconst claudeBody = JSON.stringify({\n  model: \"anthropic/claude-sonnet-4-6\",\n  max_tokens: 16000,\n  messages: [\n    { role: \"system\", content: systemPrompt },\n    { role: \"user\", content: userPrompt }\n  ]\n});\n\nreturn [{\n  json: {\n    ...data,\n    systemPrompt,\n    userPrompt,\n    claudeBody,\n  }\n}];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "id": "78e61c7a-a791-4319-87fd-3f87452491c1",
      "name": "Build Prompt V2",
      "position": [
        -6672,
        640
      ]
    },
    {
      "parameters": {
        "jsCode": "const input = $input.first().json;\nconst loopData = $('Build Prompt V2').first().json;\n\ntry {\n  let responseText = '';\n  if (input.content?.[0]?.text) {\n    responseText = input.content[0].text;\n  } else if (input.choices?.[0]?.message?.content) {\n    responseText = input.choices[0].message.content;\n  } else {\n    throw new Error('Unknown Claude response format: ' + JSON.stringify(Object.keys(input)));\n  }\n\n  if (input.stop_reason === 'max_tokens') {\n    throw new Error(\n      `Claude hit max_tokens (${input.usage?.output_tokens} tokens). ` +\n      `Response truncated. Increase max_tokens in \"Build Prompt V2\".`\n    );\n  }\n\n  responseText = responseText\n    .replace(/^```(?:json)?\\s*/i, '')\n    .replace(/```\\s*$/i, '')\n    .trim();\n\n  const jsonMatch = responseText.match(/\\{[\\s\\S]*\\}/);\n  if (!jsonMatch) {\n    throw new Error('No JSON object found in response. Preview: ' + responseText.substring(0, 200));\n  }\n\n  const parsed = JSON.parse(jsonMatch[0]);\n\n  if (!Array.isArray(parsed.testCases)) {\n    throw new Error('Invalid structure: \"testCases\" must be an array');\n  }\n\n  if (parsed.testCases.length === 0) {\n    throw new Error('Claude returned empty testCases array');\n  }\n\n  return [{\n    json: {\n      testCases: parsed.testCases,\n      metadata: parsed.metadata || {\n        parentKey: loopData.parentKey,\n        subtaskKey: loopData.subtaskKey\n      },\n      parentKey: loopData.parentKey,\n      subtaskKey: loopData.subtaskKey,\n      existingLabels: loopData.existingLabels,\n      confluenceUrl: loopData.confluenceUrl || '',\n      parseSuccess: true\n    }\n  }];\n\n} catch (error) {\n  const errorMsg = error instanceof Error ? error.message : String(error);\n  console.log(`ERR Parse error for ${loopData.subtaskKey}: ${errorMsg}`);\n  return [{\n    json: {\n      parseSuccess: false,\n      error: errorMsg,\n      subtaskKey: loopData.subtaskKey,\n      existingLabels: loopData.existingLabels,\n      confluenceUrl: loopData.confluenceUrl || ''\n    }\n  }];\n}"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "id": "4ca50440-962c-4923-8231-da1111a3be23",
      "name": "Parse Test Cases V3",
      "position": [
        -6352,
        640
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 1
          },
          "conditions": [
            {
              "id": "parse-success",
              "leftValue": "={{ $json.parseSuccess }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "cb18cbed-bfec-4545-b8e6-84dd01919adf",
      "name": "Parse OK?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        -6192,
        640
      ]
    },
    {
      "parameters": {
        "operation": "toText",
        "sourceProperty": "csv",
        "options": {
          "fileName": "={{ $json.subtaskKey }}_testcases.csv"
        }
      },
      "type": "n8n-nodes-base.convertToFile",
      "typeVersion": 1.1,
      "id": "2d7d0e02-7487-45b7-9959-c44b50fdc370",
      "name": "Convert CSV to File",
      "position": [
        -5728,
        1232
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://your-allure.example.com/api/importrequest?projectId=61&type=test_case_csv",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Api-Token YOUR_ALLURE_API_TOKEN"
            }
          ]
        },
        "sendBody": true,
        "contentType": "multipart-form-data",
        "bodyParameters": {
          "parameters": [
            {
              "parameterType": "formBinaryData",
              "name": "file",
              "inputDataFieldName": "data"
            }
          ]
        },
        "options": {}
      },
      "id": "ce46c7c5-30e0-4325-bf8d-efdf8488a9d5",
      "name": "Upload CSV to Allure",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -5552,
        1232
      ],
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 5000,
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://your-allure.example.com/api/testcase/import/csv/{{ $json.importId }}/submit",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Api-Token YOUR_ALLURE_API_TOKEN"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={{ $json.submitBody }}",
        "options": {}
      },
      "id": "17dccd14-b1ea-40db-b996-1fd60d8e5684",
      "name": "Submit CSV Import",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -5008,
        1232
      ],
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 5000,
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "jsCode": "return [{\n  json: {\n    status: 'no_tasks',\n    message: '\u041d\u0435\u0442 QA-\u043f\u043e\u0434\u0437\u0430\u0434\u0430\u0447 \u0432 \u0441\u0442\u0430\u0442\u0443\u0441\u0435 In Progress \u0431\u0435\u0437 \u043c\u0435\u0442\u043a\u0438 tc-generated',\n    timestamp: new Date().toISOString()\n  }\n}];"
      },
      "id": "ff3241f9-b749-453a-b18a-6afdcd466c49",
      "name": "No Tasks Response",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -8832,
        1712
      ]
    },
    {
      "parameters": {
        "url": "=https://your-confluence.example.com/rest/api/content/{{ $json.confluenceLinks[0].pageId }}",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "expand",
              "value": "body.storage"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -8784,
        928
      ],
      "id": "62e588f9-9ea1-44d8-a967-8e1620f1df32",
      "name": "Get Confluence Content",
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const loopItem = $('Loop Issues1').item.json;\nconst extractData = $('Extract Confluence Links1').first().json;\n\nlet confluenceContent = '';\n\ntry {\n  const directInput = $input.first().json;\n  if (directInput?.content?.[0]?.text) {\n    confluenceContent = directInput.content[0].text;\n    console.log('Using direct input (Mock or Call Claude Summary)');\n  }\n} catch (e) {}\n\nif (!confluenceContent) {\n  try {\n    const summaryResp = $('Call Claude Summary')?.first()?.json;\n    if (summaryResp?.content?.[0]?.text) {\n      confluenceContent = summaryResp.content[0].text;\n      console.log('Using Call Claude Summary');\n    }\n  } catch (e) {}\n}\n\nif (!confluenceContent) {\n  try {\n    const processed = $('Summarize Confluence (Code)')?.first()?.json;\n    if (processed?.cleanText) {\n      confluenceContent = processed.cleanText.substring(0, 10000);\n      if (processed.sectionHints) {\n        confluenceContent += '\\n\\n--- \u041a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b ---\\n' + processed.sectionHints;\n      }\n      if (processed.otherPagesNote) {\n        confluenceContent += processed.otherPagesNote;\n      }\n      console.log('Using cleanText from Summarize Confluence');\n    } else if (processed?.prioritySections) {\n      confluenceContent = processed.prioritySections;\n      console.log('Using prioritySections fallback');\n    }\n  } catch (e) {}\n}\n\nif (!confluenceContent) {\n  try {\n    const confData = $('Get Confluence Content')?.first()?.json;\n    if (confData?.body?.storage?.value) {\n      confluenceContent = confData.body.storage.value\n        .replace(/<[^>]+>/g, ' ')\n        .replace(/\\s+/g, ' ')\n        .trim()\n        .substring(0, 8000);\n      console.log('Using raw content (fallback)');\n    }\n  } catch (e) {}\n}\n\nconst confluenceLinks = extractData.confluenceLinks || [];\nconst confluenceUrl = confluenceLinks.length > 0 && confluenceLinks[0].pageId\n  ? `https://your-confluence.example.com/pages/viewpage.action?pageId=${confluenceLinks[0].pageId}`\n  : '';\nconst allConfluenceUrls = extractData.allConfluenceUrls || confluenceUrl;\n\nreturn [{\n  json: {\n    subtaskKey: loopItem.subtaskKey,\n    subtaskSummary: loopItem.subtaskSummary,\n    parentKey: loopItem.parentKey,\n    parentSummary: extractData.fields?.summary || '',\n    parentDescription: extractData.fields?.description || '\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442',\n    confluenceContent: confluenceContent,\n    confluenceUrl: confluenceUrl,\n    allConfluenceUrls: allConfluenceUrls,\n    existingLabels: loopItem.existingLabels\n  }\n}];"
      },
      "id": "9df1cad4-cb0f-49c1-b6ce-13e8d43434dd",
      "name": "Prepare Context",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -7568,
        832
      ]
    },
    {
      "parameters": {
        "jsCode": "const confData = $input.first().json;\nconst extractData = $('Extract Confluence Links1').first().json;\nconst rawHtml = confData?.body?.storage?.value || '';\n\nconst text = rawHtml\n  .replace(/<(script|style)[^>]*>[\\s\\S]*?<\\/\\1>/gi, '')\n  .replace(/<[^>]+>/g, ' ')\n  .replace(/&nbsp;/g, ' ')\n  .replace(/&amp;/g, '&')\n  .replace(/&lt;/g, '<')\n  .replace(/&gt;/g, '>')\n  .replace(/&quot;/g, '\"')\n  .replace(/&#\\d+;/g, '')\n  .replace(/\\s+/g, ' ')\n  .trim();\n\nconst SECTIONS = [\n  { name: 'API', regex: /(?:POST|GET|PUT|DELETE|PATCH)\\s+\\/[^\\s]+/gi, limit: 20 },\n  { name: '\u041e\u0448\u0438\u0431\u043a\u0438', regex: /(?:\u043e\u0448\u0438\u0431\u043a|error|ERR\\.\\d+)[^.]*\\./gi, limit: 15 },\n  { name: '\u0412\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438', regex: /(?:\u0432\u0430\u043b\u0438\u0434\u0430\u0446|\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d|\u043c\u0438\u043d\u0438\u043c\u0430\u043b|\u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b|\u0444\u043e\u0440\u043c\u0430\u0442)[^.]*\\./gi, limit: 10 },\n  { name: '\u041f\u0440\u0430\u0432\u0438\u043b\u0430', regex: /(?:\u0435\u0441\u043b\u0438|\u043a\u043e\u0433\u0434\u0430|\u043f\u0440\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u0438|\u0434\u043e\u043b\u0436\u0435\u043d|\u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d)[^.]*\\./gi, limit: 15 }\n];\n\nconst sectionHints = SECTIONS\n  .map(({ name, regex, limit }) => {\n    const matches = [...text.matchAll(regex)].slice(0, limit);\n    return matches.length > 0 ? `${name}: ${matches.map(m => m[0]).join(' | ')}` : '';\n  })\n  .filter(Boolean)\n  .join('\\n\\n');\n\nconst allLinks = extractData.confluenceLinks || [];\nconst allConfluenceUrls = extractData.allConfluenceUrls || '';\nconst otherPagesNote = allLinks.length > 1\n  ? `\\n\\n\u26a0\ufe0f \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 (\u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u043d\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439 URL \u0432 description):\\n${allLinks.slice(1).map(l => '- ' + l.url).join('\\n')}`\n  : '';\n\nconst needsSummary = text.length > 12000 ? 'true' : 'false';\n\nconsole.log(`Doc: ${text.length} chars, pages: ${allLinks.length}, needsSummary: ${needsSummary}`);\n\nreturn [{\n  json: {\n    ...confData,\n    cleanText: text,\n    sectionHints,\n    prioritySections: sectionHints,\n    needsSummary,\n    textLength: text.length,\n    allConfluenceUrls,\n    otherPagesNote,\n    confluenceCount: allLinks.length,\n    hasApiEndpoints: (text.match(/(?:POST|GET|PUT|DELETE|PATCH)\\s+\\//gi) || []).length\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -8608,
        928
      ],
      "id": "c5dc6682-1488-4558-83cb-fc9f70929817",
      "name": "Summarize Confluence (Code)"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 3
          },
          "conditions": [
            {
              "id": "ddec0c57-9d51-4040-ab3a-da8e0b18308f",
              "leftValue": "={{ $json.needsSummary }}",
              "rightValue": "true",
              "operator": {
                "type": "string",
                "operation": "equals",
                "name": "filter.operator.equals"
              }
            }
          ],
          "combinator": "and"
        },
        "looseTypeValidation": true,
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        -8432,
        928
      ],
      "id": "bea35b9c-75d5-488b-bb62-2b111988da34",
      "name": "If Need Summary?"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://your-litellm.example.com/v1/chat/completions",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_LITELLM_API_KEY"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={{ $json.claudeBody }}",
        "options": {
          "timeout": 60000
        }
      },
      "id": "b0e39327-6d75-4857-892b-80700555b937",
      "name": "Call Claude Summary",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -7792,
        976
      ],
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 5000,
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "jsCode": "const data = $input.first().json;\nconst text = data.cleanText || '';\nconst hints = data.sectionHints || data.prioritySections || '';\nconst otherPagesNote = data.otherPagesNote || '';\n\nif (!text) {\n  console.log('No cleanText \u2014 skipping summary');\n  return [{ json: { skipSummary: true, directContent: '' } }];\n}\n\nif (text.length <= 12000) {\n  console.log(`Text ${text.length} chars \u2014 passing full text directly`);\n  const directContent = text + (hints ? `\\n\\n---\\n\u041a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b:\\n${hints}` : '') + otherPagesNote;\n  return [{ json: { skipSummary: true, directContent } }];\n}\n\nconsole.log(`Text ${text.length} chars \u2014 compressing via Claude`);\n\nconst summaryPrompt = `\u0422\u044b Senior QA Engineer. \u0421\u043e\u0436\u043c\u0438 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0442\u0435\u0441\u0442-\u043a\u0435\u0439\u0441\u043e\u0432.\n\n\u0414\u041e\u041a\u0423\u041c\u0415\u041d\u0422 (${text.length} \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432):\n${text.substring(0, 50000)}\n\n${hints ? `\u0423\u0416\u0415 \u0412\u042b\u0414\u0415\u041b\u0415\u041d\u041d\u042b\u0415 \u041a\u041b\u042e\u0427\u0415\u0412\u042b\u0415 \u041c\u041e\u041c\u0415\u041d\u0422\u042b:\\n${hints}\\n\\n` : ''}\n\u0421\u041e\u0425\u0420\u0410\u041d\u0418 \u041e\u0411\u042f\u0417\u0410\u0422\u0415\u041b\u042c\u041d\u041e:\n1. \u0412\u0441\u0435 API endpoints (\u043c\u0435\u0442\u043e\u0434, URL, \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u0444\u043e\u0440\u043c\u0430\u0442\u044b \u043e\u0442\u0432\u0435\u0442\u043e\u0432)\n2. \u0412\u0441\u0435 \u043a\u043e\u0434\u044b \u043e\u0448\u0438\u0431\u043e\u043a \u0441 \u0442\u0435\u043a\u0441\u0442\u0430\u043c\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 (ERR.XXXX, BUSINESS_ERROR \u0438 \u0442.\u0434.)\n3. \u0412\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u0435\u0439: \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0444\u043e\u0440\u043c\u0430\u0442\u044b (YYYY-MM-DD etc), \u043c\u0438\u043d/\u043c\u0430\u043a\u0441 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\n4. \u0411\u0438\u0437\u043d\u0435\u0441-\u043f\u0440\u0430\u0432\u0438\u043b\u0430: \u0441\u0442\u0430\u0442\u0443\u0441\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b, \u0443\u0441\u043b\u043e\u0432\u0438\u044f, \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u044b\n5. Retry-\u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 \u0438 \u0442\u0430\u0439\u043c\u0430\u0443\u0442\u044b\n6. \u041c\u0430\u043f\u043f\u0438\u043d\u0433\u0438 \u0441\u0442\u0430\u0442\u0443\u0441\u043e\u0432 \u0438 \u043f\u043e\u043b\u0435\u0439\n7. \u041d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0442\u0430\u0431\u043b\u0438\u0446 \u0411\u0414 \u0438 \u043f\u043e\u043b\u0435\u0439\n8. \u041d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043e\u0447\u0435\u0440\u0435\u0434\u0435\u0439 \u0438 \u0442\u043e\u043f\u0438\u043a\u043e\u0432\n\n\u0423\u0411\u0415\u0420\u0418: \u0432\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u044f, \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439, \u043e\u0440\u0433\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u043f\u043e\u0432\u0442\u043e\u0440\u0435\u043d\u0438\u044f.\n\n\u0412\u0435\u0440\u043d\u0438 \u0422\u041e\u041b\u042c\u041a\u041e \u0441\u0436\u0430\u0442\u0443\u044e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u0432\u0438\u0434\u0435 (\u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c 6000 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432).${otherPagesNote}`;\n\nreturn [{\n  json: {\n    skipSummary: false,\n    claudeBody: JSON.stringify({\n      model: \"anthropic/claude-sonnet-4-6\",\n      max_tokens: 5000,\n      messages: [{ role: \"user\", content: summaryPrompt }]\n    }),\n    originalData: data\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -8208,
        720
      ],
      "id": "bfb917a0-2680-4dd6-aea8-d91e17db5212",
      "name": "Build Summary Prompt"
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 8
            }
          ]
        }
      },
      "id": "78e5574a-ae07-49d2-8907-c1e635e6e10c",
      "name": "Schedule Trigger1",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        -9520,
        1344
      ]
    },
    {
      "parameters": {
        "jsCode": "const items = $input.all();\n\nif (items.length === 0) {\n  return [{ json: { status: 'no_tasks' } }];\n}\n\nreturn items.map(({ json: issue }) => ({\n  json: {\n    subtaskKey: issue.key,\n    subtaskSummary: issue.fields?.summary || '',\n    parentKey: issue.fields?.parent?.key || '',\n    existingLabels: issue.fields?.labels || []\n  }\n}));"
      },
      "id": "586ec41c-9522-4097-9ab3-f24970a5c568",
      "name": "Split Issues1",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -9184,
        1344
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 1
          },
          "conditions": [
            {
              "id": "check-no-tasks",
              "leftValue": "={{ $json.status }}",
              "rightValue": "no_tasks",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "fc86d203-e664-4c77-8dcd-ed7f75337225",
      "name": "Has Tasks?1",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        -9024,
        1344
      ]
    },
    {
      "parameters": {
        "jiraVersion": "serverPat",
        "operation": "get",
        "issueKey": "={{ $('Loop Issues1').item.json.parentKey }}",
        "additionalFields": {}
      },
      "id": "f050e89c-b369-46bd-8646-30c4bc942c69",
      "name": "Get Parent Issue2",
      "type": "n8n-nodes-base.jira",
      "typeVersion": 1,
      "position": [
        -9440,
        1072
      ],
      "retryOnFail": true,
      "maxTries": 2,
      "waitBetweenTries": 3000,
      "credentials": {
        "jiraSoftwareServerPatApi": {
          "name": "<your credential>"
        }
      },
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "jsCode": "const parent = $input.first().json;\nconst description = parent.fields?.description || '';\n\nconst pageIdRegex = /your-confluence\\.example\\.com\\/(?:.*?pageId=(\\d+)|.*?\\/(?:pages|content)\\/(\\d+))/gi;\nconst links = [];\nconst seenIds = new Set();\n\nlet match;\nwhile ((match = pageIdRegex.exec(description)) !== null) {\n  const pageId = match[1] || match[2];\n  if (pageId && !seenIds.has(pageId)) {\n    seenIds.add(pageId);\n    links.push({\n      pageId,\n      url: `https://your-confluence.example.com/pages/viewpage.action?pageId=${pageId}`\n    });\n  }\n}\n\nconst displayLinks = [];\nconst displayRe = /https?:\\/\\/your-confluence\\.example\\.com\\/display\\/[^\\s\\|\\]\\[\\\"\\']+/gi;\nlet dm;\nwhile ((dm = displayRe.exec(description)) !== null) {\n  const url = dm[0].replace(/[.,;:!?)]+$/, '');\n  displayLinks.push(url);\n}\n\nconst allConfluenceUrls = [\n  ...links.map(l => l.url),\n  ...displayLinks\n].join('\\n');\n\nreturn [{\n  json: {\n    ...parent,\n    confluenceLinks: links,\n    confluenceDisplayLinks: displayLinks,\n    allConfluenceUrls,\n    hasConfluence: links.length > 0,\n    confluenceCount: links.length\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -9280,
        1072
      ],
      "id": "da676097-504a-423a-950c-b4ac0c52a414",
      "name": "Extract Confluence Links1"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "has-confluence",
              "leftValue": "={{ $json.hasConfluence }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        -9120,
        1072
      ],
      "id": "f1ed2f57-c74c-43df-9d27-3a099f90a331",
      "name": "Has Confluence?1"
    },
    {
      "parameters": {
        "jsCode": "const ctx = $input.first().json;\n\nconst labels = Array.isArray(ctx.existingLabels)\n\t? ctx.existingLabels.filter(Boolean)\n\t: [];\n\nif (!ctx || (!ctx.subtaskKey && !ctx.parentKey)) {\n\treturn [{ json: { ...ctx, action: 'skip', reason: 'no_context' } }];\n}\n\nconst tasks = [];\n\nconst needTC = labels.includes('need-tc');\nconst hasTCGenerated = labels.includes('tc-generated');\n\nif (needTC && !hasTCGenerated) {\n\ttasks.push({ ...ctx, action: 'tc' });\n}\n\nconst needChecklist = labels.includes('need-checklist');\nconst hasChecklistGenerated = labels.includes('checklist-generated');\n\nif (needChecklist && !hasChecklistGenerated) {\n\ttasks.push({ ...ctx, action: 'checklist' });\n}\n\nif (tasks.length === 0) {\n\treturn [{ json: { ...ctx, action: 'skip' } }];\n}\n\nreturn tasks.map(t => ({ json: t }));"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -7056,
        720
      ],
      "id": "f04ea5e6-2854-422b-8127-b80faf29863b",
      "name": "Check What To Generate"
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.action }}",
                    "rightValue": "tc",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "id": "7d872622-6a54-49fd-9453-0fd6a98f61c5"
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "TC"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "id": "15fbec28-5b66-4e65-8d03-7ef90b301883",
                    "leftValue": "={{ $json.action }}",
                    "rightValue": "checklist",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Checklist"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 3
                },
                "conditions": [
                  {
                    "id": "21ec4b7f-56f9-45b0-8a30-fa53b79d2eb7",
                    "leftValue": "={{ $json.action }}",
                    "rightValue": "skip",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Skip"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.4,
      "position": [
        -6912,
        704
      ],
      "id": "8f18e954-b281-45e5-a824-a7af318d6761",
      "name": "Route by Action"
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://your-litellm.example.com/v1/chat/completions",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_LITELLM_API_KEY"
            }
          ]
        },
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={{ $json.claudeBody }}",
        "options": {
          "timeout": 120000
        }
      },
      "id": "dbc68078-52ad-440d-a0b4-dbdf73b5f437",
      "name": "Call Claude1",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -6512,
        640
      ],
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 5000,
      "onError": "continueRegularOutput"
    },
    {
      "parameters": {
        "jsCode": "const ctx = $input.first().json;\n\nconst systemPrompt = `\u0422\u044b \u043e\u043f\u044b\u0442\u043d\u044b\u0439 QA-\u0438\u043d\u0436\u0435\u043d\u0435\u0440 \u0434\u043b\u044f \u0444\u0438\u043d\u0442\u0435\u0445 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u0430 \u2014 \u043c\u0430\u0440\u043a\u0435\u0442\u043f\u043b\u0435\u0439\u0441 \u0431\u0430\u043d\u043a\u043e\u0432\u0441\u043a\u0438\u0445 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u0432 (\u043a\u0440\u0435\u0434\u0438\u0442\u044b, \u0434\u0435\u043f\u043e\u0437\u0438\u0442\u044b, \u0438\u043f\u043e\u0442\u0435\u043a\u0430, \u0441\u0442\u0440\u0430\u0445\u043e\u0432\u0430\u043d\u0438\u0435).\n\n\u0421\u043e\u0441\u0442\u0430\u0432\u044c \u041a\u041e\u041d\u041a\u0420\u0415\u0422\u041d\u042b\u0419 QA-\u0447\u0435\u043a\u043b\u0438\u0441\u0442 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0437\u0430\u0434\u0430\u0447\u0438 \u0418 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438.\n\n## \u0418\u0421\u0422\u041e\u0427\u041d\u0418\u041a\u0418 \u0418\u041d\u0424\u041e\u0420\u041c\u0410\u0426\u0418\u0418:\n1. **\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438** \u2014 \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c\n2. **\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u0438\u0437 Confluence** \u2014 \u0434\u0435\u0442\u0430\u043b\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, API \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442\u044b, \u0431\u0438\u0437\u043d\u0435\u0441-\u043f\u0440\u0430\u0432\u0438\u043b\u0430\n\n## \u041f\u0420\u0410\u0412

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Jira-Allure-Auto-Qa. Uses httpRequest, jira. Scheduled trigger; 68 nodes.

Source: https://github.com/KonstantinVCH/n8n-auto-qa-bot/blob/96c5e27a1d24e9af78f7600216edeeae9fa0c257/workflow/jira-allure-auto-qa.json — original creator credit. Request a take-down →

More Web Scraping workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Web Scraping

Auto Fix Scheduler. Uses jira, httpRequest. Scheduled trigger; 20 nodes.

Jira, HTTP Request
Web Scraping

Birthday Automation - Production (Fixed). Uses stopAndError, httpRequest, emailSend, bannerbear. Scheduled trigger; 86 nodes.

Stop And Error, HTTP Request, Email Send +1
Web Scraping

This template runs two scheduled workflows to govern Microsoft Entra ID (Azure AD) guest accounts by detecting stale users via Microsoft Graph, staging deletions in SharePoint with a 72-hour window, n

Microsoft SharePoint, Microsoft Teams, Microsoft Entra +1
Web Scraping

Spotify-Sync-Surrealdb-V1. Uses httpRequest, n8n-nodes-surrealdb, spotify. Scheduled trigger; 62 nodes.

HTTP Request, N8N Nodes Surrealdb, Spotify
Web Scraping

As n8n instances scale, teams often lose track of sub-workflows—who uses them, where they are referenced, and whether they can be safely updated. This leads to inefficiencies like unnecessary copies o

HTTP Request, n8n, N8N Trigger +1