{
  "name": "Bug分流自动化工作流",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "bug-triage",
        "responseMode": "onReceived",
        "options": {}
      },
      "name": "Webhook收Bug报告",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "position": [0, 0],
      "webhookId": "bug-triage-automation"
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const raw = $input.first().json;\nconst body = raw.body || raw;\n// 归一多源字段：表单/邮件/IM bot\nconst title = raw.title || raw.subject || raw.summary || '未命名Bug报告';\nconst description = raw.description || raw.content || raw.text || (raw.body && raw.body.description) || '';\nconst environment = raw.environment || raw.env || raw.browser || raw.app_version || '';\nconst reproSteps = raw.repro_steps || raw.steps || raw.reproduction || '';\nconst reporter = raw.reporter || raw.user || raw.username || 'anonymous';\nconst reporterContact = raw.reporter_contact || raw.email || raw.user_id || '';\nconst source = raw.source || 'webhook';\n// 去重键：标题+环境 hash\nlet h = 0;\nconst dedupKey = title + '|' + environment;\nfor (let i = 0; i < dedupKey.length; i++) h = ((h << 5) - h + dedupKey.charCodeAt(i)) | 0;\nconst hash = 'bug_' + Math.abs(h).toString(36);\nreturn { json: { ...body, title, description, environment, reproSteps, reporter, reporterContact, source, hash } };"
      },
      "name": "提取字段",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [220, 0]
    },
    {
      "parameters": {
        "url": "https://api.moonshot.cn/v1/chat/completions",
        "method": "POST",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            { "name": "Authorization", "value": "Bearer YOUR_LLM_API_KEY" },
            { "name": "Content-Type", "value": "application/json" }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\"model\":\"moonshot-v1-8k\",\"messages\":[{\"role\":\"system\",\"content\":\"你是Bug分流工程师。读bug报告输出JSON：severity(P0崩溃/数据丢失/安全漏洞/大面积不可用|P1核心功能受阻|P2次要功能受损|P3外观体验问题)、module(frontend/backend/infra/unknown四选一,从描述推断)、reproducible(yes有明确复现步骤|no无法复现|unknown信息不足)、confidence(0-1)、summary(30字内)、missing_info(缺失关键信息数组,如复现步骤为空则加入repro_steps,环境为空加入environment,空数组表示齐全)。不编造报告中没有的事实,仅基于原文判断。\"},{\"role\":\"user\",\"content\":\"={{JSON.stringify({title:$json.title,description:$json.description,environment:$json.environment,steps:$json.reproSteps})}}\"}]}",
        "options": {}
      },
      "name": "LLM分类",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 1,
      "position": [440, 0]
    },
    {
      "parameters": {
        "conditions": {
          "combinator": "or",
          "boolean": [
            { "value1": "={{JSON.parse($json.choices[0].message.content).severity}}", "value2": "P0" },
            { "value1": "={{JSON.parse($json.choices[0].message.content).severity}}", "value2": "P1" }
          ]
        }
      },
      "name": "IF紧急",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [660, 0]
    },
    {
      "parameters": {
        "url": "YOUR_ONCALL_WEBHOOK_URL",
        "method": "POST",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\"msgtype\":\"text\",\"text\":{\"content\":\"[P0/P1 Bug] {{JSON.parse($json.choices[0].message.content).summary}}\\n严重级别: {{JSON.parse($json.choices[0].message.content).severity}}\\n模块: {{JSON.parse($json.choices[0].message.content).module}}\\n可复现: {{JSON.parse($json.choices[0].message.content).reproducible}}\\n报告人: {{$node[\\\"提取字段\\\"].json.reporter}}\\n来源: {{$node[\\\"提取字段\\\"].json.source}}\"}}",
        "options": {}
      },
      "name": "通知值班",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 1,
      "position": [880, -160]
    },
    {
      "parameters": {
        "url": "=https://api.github.com/repos/YOUR_ORG/YOUR_REPO/issues",
        "method": "POST",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            { "name": "Authorization", "value": "Bearer YOUR_GITHUB_TOKEN" },
            { "name": "Accept", "value": "application/vnd.github+json" }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\"title\":\"[{{JSON.parse($json.choices[0].message.content).severity}}] {{$node[\\\"提取字段\\\"].json.title}}\",\"labels\":[\"bug\",\"auto-triaged\",\"{{JSON.parse($json.choices[0].message.content).module}}\",\"priority:{{JSON.parse($json.choices[0].message.content).severity}}\"],\"body\":\"## Bug 报告\\n\\n**严重级别**: {{JSON.parse($json.choices[0].message.content).severity}}\\n**模块**: {{JSON.parse($json.choices[0].message.content).module}}\\n**可复现**: {{JSON.parse($json.choices[0].message.content).reproducible}}\\n**报告人**: {{$node[\\\"提取字段\\\"].json.reporter}}\\n**来源**: {{$node[\\\"提取字段\\\"].json.source}}\\n\\n**描述**:\\n{{$node[\\\"提取字段\\\"].json.description}}\\n\\n**环境**:\\n{{$node[\\\"提取字段\\\"].json.environment}}\\n\\n**复现步骤**:\\n{{$node[\\\"提取字段\\\"].json.reproSteps}}\\n\\n**缺失信息**: {{JSON.parse($json.choices[0].message.content).missing_info.join(', ') || '无'}}\"}",
        "options": {}
      },
      "name": "建高优Issue",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 1,
      "position": [1100, -160]
    },
    {
      "parameters": {
        "dataType": "string",
        "value1": "={{JSON.parse($json.choices[0].message.content).module}}",
        "rules": {
          "rules": [
            { "value2": "frontend" },
            { "value2": "backend" }
          ]
        },
        "fallbackOutput": 2
      },
      "name": "按模块路由",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 1,
      "position": [880, 160]
    },
    {
      "parameters": {
        "url": "YOUR_FRONTEND_QUEUE_WEBHOOK",
        "method": "POST",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\"text\":\"[Bug分流] {{$node[\\\"提取字段\\\"].json.title}}\\n模块: frontend\\n严重级别: {{JSON.parse($json.choices[0].message.content).severity}}\\n可复现: {{JSON.parse($json.choices[0].message.content).reproducible}}\\n报告人: {{$node[\\\"提取字段\\\"].json.reporter}}\"}",
        "options": {}
      },
      "name": "通知前端负责人",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 1,
      "position": [1100, 60]
    },
    {
      "parameters": {
        "url": "YOUR_BACKEND_QUEUE_WEBHOOK",
        "method": "POST",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\"text\":\"[Bug分流] {{$node[\\\"提取字段\\\"].json.title}}\\n模块: backend\\n严重级别: {{JSON.parse($json.choices[0].message.content).severity}}\\n可复现: {{JSON.parse($json.choices[0].message.content).reproducible}}\\n报告人: {{$node[\\\"提取字段\\\"].json.reporter}}\"}",
        "options": {}
      },
      "name": "通知后端负责人",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 1,
      "position": [1100, 260]
    },
    {
      "parameters": {
        "url": "YOUR_REPLY_ENDPOINT",
        "method": "POST",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\"to\":\"{{$node[\\\"提取字段\\\"].json.reporterContact}}\",\"subject\":\"Re: {{$node[\\\"提取字段\\\"].json.title}}\",\"body\":\"你提交的Bug报告已收到。\\n编号: {{$node[\\\"提取字段\\\"].json.hash}}\\n严重级别: {{JSON.parse($json.choices[0].message.content).severity}}\\n模块: {{JSON.parse($json.choices[0].message.content).module}}\\n预计处理: {{({P0:'立即响应',P1:'当天处理',P2:'本周排期',P3:'下个迭代评估'})[JSON.parse($json.choices[0].message.content).severity] || '评估中'}}\\n如需补充信息我们会再联系你。\"}",
        "options": {}
      },
      "name": "自动回复提交者",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 1,
      "position": [1320, 0]
    },
    {
      "parameters": {
        "url": "YOUR_STATUS_WRITEBACK_URL",
        "method": "PATCH",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\"hash\":\"{{$node[\\\"提取字段\\\"].json.hash}}\",\"status\":\"triaged\",\"severity\":\"{{JSON.parse($json.choices[0].message.content).severity}}\",\"module\":\"{{JSON.parse($json.choices[0].message.content).module}}\",\"reproducible\":\"{{JSON.parse($json.choices[0].message.content).reproducible}}\",\"triaged_at\":\"{{$now.toISO()}}\"}",
        "options": {}
      },
      "name": "状态回写",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 1,
      "position": [1540, 0]
    }
  ],
  "connections": {
    "Webhook收Bug报告": { "main": [ [{ "node": "提取字段", "type": "main", "index": 0 }] ] },
    "提取字段": { "main": [ [{ "node": "LLM分类", "type": "main", "index": 0 }] ] },
    "LLM分类": { "main": [ [{ "node": "IF紧急", "type": "main", "index": 0 }] ] },
    "IF紧急": { "main": [ [{ "node": "通知值班", "type": "main", "index": 0 }], [{ "node": "按模块路由", "type": "main", "index": 0 }] ] },
    "通知值班": { "main": [ [{ "node": "建高优Issue", "type": "main", "index": 0 }] ] },
    "建高优Issue": { "main": [ [{ "node": "自动回复提交者", "type": "main", "index": 0 }] ] },
    "按模块路由": { "main": [ [{ "node": "通知前端负责人", "type": "main", "index": 0 }], [{ "node": "通知后端负责人", "type": "main", "index": 0 }], [{ "node": "自动回复提交者", "type": "main", "index": 0 }] ] },
    "通知前端负责人": { "main": [ [{ "node": "自动回复提交者", "type": "main", "index": 0 }] ] },
    "通知后端负责人": { "main": [ [{ "node": "自动回复提交者", "type": "main", "index": 0 }] ] },
    "自动回复提交者": { "main": [ [{ "node": "状态回写", "type": "main", "index": 0 }] ] }
  }
}
