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 →
{
"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(/ /g, ' ')\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/"/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.
httpHeaderAuthjiraSoftwareServerPatApi
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 →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Auto Fix Scheduler. Uses jira, httpRequest. Scheduled trigger; 20 nodes.
Birthday Automation - Production (Fixed). Uses stopAndError, httpRequest, emailSend, bannerbear. Scheduled trigger; 86 nodes.
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
Spotify-Sync-Surrealdb-V1. Uses httpRequest, n8n-nodes-surrealdb, spotify. Scheduled trigger; 62 nodes.
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