{
  "id": "<REDACTED_WORKFLOW_ID>",
  "meta": {
    "instanceId": "<REDACTED_N8N_INSTANCE_ID>",
    "templateCredsSetupCompleted": true
  },
  "name": "Lead Routing Engine with SLA Auto-Reassignment",
  "tags": [],
  "nodes": [
    {
      "id": "081127cd-9a65-420f-bcc9-ec00edd129c0",
      "name": "1) Form Trigger (New Lead)",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        1008,
        656
      ],
      "webhookId": "<REDACTED_WEBHOOK_ID_FORM_TRIGGER>",
      "parameters": {
        "options": {
          "buttonLabel": "Submit"
        },
        "formTitle": "Lead Intake (Generic Form Trigger)",
        "formFields": {
          "values": [
            {
              "fieldName": "Name",
              "fieldLabel": "Name",
              "requiredField": true
            },
            {
              "fieldName": "Phone",
              "fieldLabel": "Phone",
              "placeholder": "0812xxx / +62812xxx / 62812xxx",
              "requiredField": true
            }
          ]
        }
      },
      "typeVersion": 2.4
    },
    {
      "id": "3379ea2e-316c-407e-adee-75094f1904cd",
      "name": "2) Prep Lead",
      "type": "n8n-nodes-base.code",
      "position": [
        1232,
        656
      ],
      "parameters": {
        "jsCode": "// =============================================\n// 2) Prep Lead (Normalize + Lead ID + Funnel Stage)\n// =============================================\n// Funnel stages:\n// - NEW, CONTACTED, QUALIFIED, CLOSED_LOST\n//\n// This node:\n// - generates a safe lead_id\n// - normalizes phone into 62xxxx\n// - sets initial stage = NEW\n\nfunction normalizePhone(input) {\n  let p = String(input || '').trim();\n  p = p.replace(/\\s+/g, '');\n  p = p.replace(/[^0-9+]/g, '');\n\n  if (p.startsWith('+62')) p = '62' + p.slice(3);\n  if (p.startsWith('0')) p = '62' + p.slice(1);\n  if (p.startsWith('62')) return p;\n  if (/^\\d+$/.test(p)) return '62' + p;\n  return p;\n}\n\nfunction makeLeadId() {\n  const ts = Date.now().toString(36);\n  const rnd = Math.random().toString(36).slice(2, 8);\n  return `L-${ts}-${rnd}`.toUpperCase();\n}\n\nconst now = new Date().toISOString();\n\nreturn [{\n  json: {\n    lead_id: makeLeadId(),\n    name: String($json.Name || '').trim(),\n    phone: normalizePhone($json.Phone),\n\n    // Funnel stage\n    stage: 'NEW',\n\n    // Routing state\n    assigned_sales: '',\n    sales_slack_id: '',\n    route_count: 0,\n\n    // Timestamps\n    created_at: now,\n    initial_assigned_at: '',\n    assigned_at: '',\n    last_routed_at: ''\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "43e46f8a-bdf3-4617-a342-fbb756f3d986",
      "name": "3) Get Sales List (active=ON)",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1456,
        656
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 0,
          "cachedResultUrl": "<REDACTED_GOOGLE_SHEET_URL>",
          "cachedResultName": "sales_sheet"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "<REDACTED_GOOGLE_SHEET_DOCUMENT_ID>",
          "cachedResultUrl": "<REDACTED_GOOGLE_SHEET_URL>",
          "cachedResultName": "DEMO_SHEET"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "<REDACTED_GSHEETS_CRED_ID>",
          "name": "Google Sheets account (<REDACTED>)"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "4b206a78-d668-4750-b005-99baa882807f",
      "name": "4) Build Sales List",
      "type": "n8n-nodes-base.code",
      "position": [
        1680,
        656
      ],
      "parameters": {
        "jsCode": "// =============================================\n// 4) Build Sales List (1 object)\n// =============================================\n// Output: sales_list[] is used for initial assignment and re-routing.\n\nconst salesList = items\n  .map(i => i.json)\n  .filter(r => {\n    const a = String(r.active || '').toUpperCase();\n    return a === 'ON' || a === 'TRUE' || r.active === true;\n  })\n  .map(r => ({\n    name: String(r.name || '').trim(),\n    email: String(r.email || '').trim(),\n    slack_id: String(r.slack_id || '').trim(),\n    active: true\n  }))\n  .filter(r => r.name && r.slack_id);\n\nif (!salesList.length) {\n  throw new Error('No active sales found. Check sales sheet: name, slack_id, active=ON');\n}\n\nreturn [{ json: { sales_list: salesList, sales_count: salesList.length } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "aacd08b3-e26b-4545-b0b1-478c69785d0d",
      "name": "5) Get routing_state (last_index)",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1904,
        656
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "last_index",
              "lookupColumn": "key"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 0,
          "cachedResultUrl": "<REDACTED_GOOGLE_SHEET_URL>",
          "cachedResultName": "routing_state_sheet"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "<REDACTED_GOOGLE_SHEET_DOCUMENT_ID>",
          "cachedResultUrl": "<REDACTED_GOOGLE_SHEET_URL>",
          "cachedResultName": "DEMO_SHEET"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "<REDACTED_GSHEETS_CRED_ID>",
          "name": "Google Sheets account (<REDACTED>)"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "63feae74-e4fa-45fa-85a8-d70cf8264add",
      "name": "6) Initial Assign (Round Robin)",
      "type": "n8n-nodes-base.code",
      "position": [
        2128,
        656
      ],
      "parameters": {
        "jsCode": "// 6) Initial Assign (Round Robin)\n// Read the lead directly from node 2 (to avoid being overwritten by Google Sheets nodes)\n\nconst lead = $items('2) Prep Lead')[0].json;              // ✅ original lead\nconst sales = $items('4) Build Sales List')[0].json.sales_list;\n\n// routing_state is typically from node 5 (key/value)\nconst rs = $items('5) Get routing_state (last_index)')[0]?.json || {};\nconst lastIndex = Number(rs.value ?? -1);\n\nconst nextIndex = (lastIndex + 1) % sales.length;\nconst assigned = sales[nextIndex];\n\nconst now = new Date().toISOString();\n\nreturn [{\n  json: {\n    ...lead,\n\n    assigned_sales: assigned.name,\n    sales_slack_id: assigned.slack_id,\n\n    assigned_sales_index: nextIndex,\n    routing_key: 'last_index',\n\n    route_count: Number(lead.route_count || 0) + 1,\n\n    initial_assigned_at: lead.initial_assigned_at || now,\n    assigned_at: now,\n    last_routed_at: now,\n  }\n}];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "84bd91ec-f4c6-4abb-bc2f-83ec9afffb97",
      "name": "7) Update routing_state",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2352,
        560
      ],
      "parameters": {
        "columns": {
          "value": {
            "key": "={{ $json.routing_key }}",
            "value": "={{ $json.assigned_sales_index }}"
          },
          "schema": [
            {
              "id": "key",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "key",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "value",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "value",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "number",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "key"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 0,
          "cachedResultUrl": "<REDACTED_GOOGLE_SHEET_URL>",
          "cachedResultName": "routing_state_sheet"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "<REDACTED_GOOGLE_SHEET_DOCUMENT_ID>",
          "cachedResultUrl": "<REDACTED_GOOGLE_SHEET_URL>",
          "cachedResultName": "DEMO_SHEET"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "<REDACTED_GSHEETS_CRED_ID>",
          "name": "Google Sheets account (<REDACTED>)"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "e79612be-ccc5-4a59-8da9-fdea4036ae6b",
      "name": "8) Upsert Lead (leads sheet)",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2352,
        752
      ],
      "parameters": {
        "columns": {
          "value": {
            "name": "={{ $json.name }}",
            "phone": "={{ $json.phone }}",
            "stage": "={{ $json.stage }}",
            "lead_id": "={{ $json.lead_id }}",
            "created_at": "={{ $json.created_at }}",
            "assigned_at": "={{ $json.assigned_at }}",
            "route_count": "={{ $json.route_count }}",
            "assigned_sales": "={{ $json.assigned_sales }}",
            "last_routed_at": "={{ $json.last_routed_at }}",
            "sales_slack_id": "={{ $json.sales_slack_id }}",
            "initial_assigned_at": "={{ $json.initial_assigned_at }}"
          },
          "schema": [
            {
              "id": "lead_id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "lead_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "phone",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "stage",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "stage",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "assigned_sales",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "assigned_sales",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "sales_slack_id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "sales_slack_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "initial_assigned_at",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "initial_assigned_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "assigned_at",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "assigned_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "last_routed_at",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "last_routed_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "route_count",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "route_count",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "created_at",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "created_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "lead_id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 0,
          "cachedResultUrl": "<REDACTED_GOOGLE_SHEET_URL>",
          "cachedResultName": "lead_sheet"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "<REDACTED_GOOGLE_SHEET_DOCUMENT_ID>",
          "cachedResultUrl": "<REDACTED_GOOGLE_SHEET_URL>",
          "cachedResultName": "DEMO_SHEET"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "<REDACTED_GSHEETS_CRED_ID>",
          "name": "Google Sheets account (<REDACTED>)"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "75bd650d-7e5f-46d6-b422-cff871904be9",
      "name": "SLA Trigger (every 1 hour)",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        1008,
        1184
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours"
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "df9abcc5-683b-4345-9a47-39b0ddeafae2",
      "name": "SLA) Get Sales List",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1232,
        1184
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 0,
          "cachedResultUrl": "<REDACTED_GOOGLE_SHEET_URL>",
          "cachedResultName": "sales_sheet"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "<REDACTED_GOOGLE_SHEET_DOCUMENT_ID>",
          "cachedResultUrl": "<REDACTED_GOOGLE_SHEET_URL>",
          "cachedResultName": "DEMO_SHEET"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "<REDACTED_GSHEETS_CRED_ID>",
          "name": "Google Sheets account (<REDACTED>)"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "1a849c9c-cac8-4d79-808a-747addc1650d",
      "name": "SLA) Build Sales List",
      "type": "n8n-nodes-base.code",
      "position": [
        1456,
        1184
      ],
      "parameters": {
        "jsCode": "// Reuse the same builder logic for the SLA path\nconst salesList = items\n  .map(i => i.json)\n  .filter(r => {\n    const a = String(r.active || '').toUpperCase();\n    return a === 'ON' || a === 'TRUE' || r.active === true;\n  })\n  .map(r => ({\n    name: String(r.name || '').trim(),\n    email: String(r.email || '').trim(),\n    slack_id: String(r.slack_id || '').trim(),\n    active: true\n  }))\n  .filter(r => r.name && r.slack_id);\n\nif (!salesList.length) throw new Error('No active sales found');\n\nreturn [{ json: { sales_list: salesList, sales_count: salesList.length } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "5a9d1951-f3fe-457a-baf2-64d3016a9f6b",
      "name": "SLA) Get Leads (stage=NEW)",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1680,
        1184
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "NEW",
              "lookupColumn": "stage"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 0,
          "cachedResultUrl": "<REDACTED_GOOGLE_SHEET_URL>",
          "cachedResultName": "lead_sheet"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "<REDACTED_GOOGLE_SHEET_DOCUMENT_ID>",
          "cachedResultUrl": "<REDACTED_GOOGLE_SHEET_URL>",
          "cachedResultName": "DEMO_SHEET"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "<REDACTED_GSHEETS_CRED_ID>",
          "name": "Google Sheets account (<REDACTED>)"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "848e4f52-21dc-4a4d-b57e-04449767c114",
      "name": "SLA) If last route >= 1 hour",
      "type": "n8n-nodes-base.if",
      "position": [
        1904,
        1184
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "d684dde0-8f7d-4ecf-a07b-c0557a9b1323",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ (Date.now() - new Date($json.last_routed_at || $json.initial_assigned_at || $json.assigned_at || $json.created_at).getTime()) >= 60 * 60 * 1000 }}"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "ef2e8f85-a46f-44af-86a3-60230e7f8d7b",
      "name": "SLA) Re-route to next sales",
      "type": "n8n-nodes-base.code",
      "position": [
        2128,
        1184
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// SLA) Hourly Re-route (per item) - n8n 2.1.4 compatible\n\nconst lead = $json;\nconst sales = $items('SLA) Build Sales List')[0].json.sales_list;\n\nif (!Array.isArray(sales) || sales.length === 0) {\n  throw new Error(\"Sales list is empty. Check output of node 'SLA) Build Sales List'.\");\n}\n\nconst currentSlack = String(lead.sales_slack_id || '').trim();\nconst currentIndex = sales.findIndex(s => String(s.slack_id) === currentSlack);\nconst safeIndex = currentIndex === -1 ? 0 : currentIndex;\n\nconst nextIndex = (safeIndex + 1) % sales.length;\nconst nextSales = sales[nextIndex];\n\nconst now = new Date().toISOString();\n\n// IMPORTANT: For 'Run Once for Each Item', return MUST be an object, not an array\nreturn {\n  json: {\n    ...lead,\n    assigned_sales: nextSales.name,\n    sales_slack_id: nextSales.slack_id,\n    route_count: Number(lead.route_count || 0) + 1,\n    assigned_at: now,\n    last_routed_at: now,\n  }\n};\n"
      },
      "typeVersion": 2
    },
    {
      "id": "0c2f96ca-edd6-4b09-9e56-a29e3d85b005",
      "name": "SLA) Update lead (after reroute)",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2576,
        1280
      ],
      "parameters": {
        "columns": {
          "value": {
            "lead_id": "={{ $json.lead_id }}",
            "assigned_at": "={{ $json.assigned_at }}",
            "route_count": "={{ $json.route_count }}",
            "assigned_sales": "={{ $json.assigned_sales }}",
            "last_routed_at": "={{ $json.last_routed_at }}",
            "sales_slack_id": "={{ $json.sales_slack_id }}"
          },
          "schema": [
            {
              "id": "lead_id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "lead_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "phone",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "stage",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "stage",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "assigned_sales",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "assigned_sales",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "sales_slack_id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "sales_slack_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "initial_assigned_at",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "initial_assigned_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "assigned_at",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "assigned_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "last_routed_at",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "last_routed_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "route_count",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "route_count",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "created_at",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "created_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "number",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "lead_id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 0,
          "cachedResultUrl": "<REDACTED_GOOGLE_SHEET_URL>",
          "cachedResultName": "lead_sheet"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "<REDACTED_GOOGLE_SHEET_DOCUMENT_ID>",
          "cachedResultUrl": "<REDACTED_GOOGLE_SHEET_URL>",
          "cachedResultName": "DEMO_SHEET"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "<REDACTED_GSHEETS_CRED_ID>",
          "name": "Google Sheets account (<REDACTED>)"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "f2b2d1f5-5c79-4c15-bccb-68576372352b",
      "name": "STAGE) Webhook (/demo-stage-update)",
      "type": "n8n-nodes-base.webhook",
      "position": [
        1024,
        1696
      ],
      "webhookId": "<REDACTED_WEBHOOK_ID_STAGE>",
      "parameters": {
        "path": "demo-stage-update",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "lastNode"
      },
      "typeVersion": 2
    },
    {
      "id": "bcdaf046-1550-4a7c-9203-fb3d0efd445e",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        912,
        512
      ],
      "parameters": {
        "width": 1904,
        "height": 432,
        "content": "## Intake & Initial Assignment (Round Robin)"
      },
      "typeVersion": 1
    },
    {
      "id": "47ba8bf6-9a88-4740-b055-444a71837399",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        912,
        992
      ],
      "parameters": {
        "width": 2992,
        "height": 512,
        "content": "## SLA Monitor & Hourly Re-route"
      },
      "typeVersion": 1
    },
    {
      "id": "2fae9d8f-876c-4402-a2ca-5fac8150ad29",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        912,
        1552
      ],
      "parameters": {
        "width": 1488,
        "height": 432,
        "content": "##  \"Contacted\" Stage Update API (Stop Routing)"
      },
      "typeVersion": 1
    },
    {
      "id": "1d86227e-35f4-4433-9be2-657ed6c8bc0f",
      "name": "STAGE) Update lead stage to CONTACTED",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2144,
        1600
      ],
      "parameters": {
        "columns": {
          "value": {
            "stage": "={{ $json.stage }}",
            "lead_id": "={{ $json.lead_id }}",
            "contacted_at": "={{ $json.contacted_at }}"
          },
          "schema": [
            {
              "id": "lead_id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "lead_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "phone",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "stage",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "stage",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "assigned_sales",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "assigned_sales",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "sales_slack_id",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "sales_slack_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "initial_assigned_at",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "initial_assigned_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "assigned_at",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "assigned_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "last_routed_at",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "last_routed_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "route_count",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "route_count",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "created_at",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "created_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "contacted_at",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "contacted_at",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "number",
              "display": true,
              "removed": true,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "lead_id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 0,
          "cachedResultUrl": "<REDACTED_GOOGLE_SHEET_URL>",
          "cachedResultName": "lead_sheet"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "<REDACTED_GOOGLE_SHEET_DOCUMENT_ID>",
          "cachedResultUrl": "<REDACTED_GOOGLE_SHEET_URL>",
          "cachedResultName": "DEMO_SHEET"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "<REDACTED_GSHEETS_CRED_ID>",
          "name": "Google Sheets account (<REDACTED>)"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "ae3aa50c-f879-4687-a17e-28d8ef01fa0c",
      "name": "SLA) Slack Notify (reroute) & Button",
      "type": "n8n-nodes-base.slack",
      "position": [
        2800,
        1280
      ],
      "webhookId": "<REDACTED_SLACK_NODE_WEBHOOK_ID>",
      "parameters": {
        "text": "=",
        "select": "channel",
        "blocksUi": "={\n  \"blocks\": [\n    {\n      \"type\": \"section\",\n      \"text\": {\n        \"type\": \"mrkdwn\",\n        \"text\": \"🔁 *Lead Re-routed (SLA)*\\n\\n*Lead ID:* {{ $items(\\\"SLA) Re-route to next sales\\\")[$itemIndex].json.lead_id }}\\n*Now Assigned to:* <@{{ $items(\\\"SLA) Re-route to next sales\\\")[$itemIndex].json.sales_slack_id }}>\\n*Name:* {{ $items(\\\"SLA) Re-route to next sales\\\")[$itemIndex].json.name }}\\n*Phone:* {{ $items(\\\"SLA) Re-route to next sales\\\")[$itemIndex].json.phone }}\\n*Route count:* {{ $items(\\\"SLA) Re-route to next sales\\\")[$itemIndex].json.route_count }}\"\n      }\n    },\n    {\n      \"type\": \"actions\",\n      \"elements\": [\n        {\n          \"type\": \"button\",\n          \"style\": \"primary\",\n          \"text\": {\n            \"type\": \"plain_text\",\n            \"text\": \"Mark as CONTACTED\"\n          },\n          \"value\": \"{{ $items(\\\"SLA) Re-route to next sales\\\")[$itemIndex].json.lead_id }}\",\n          \"action_id\": \"mark_contacted\"\n        }\n      ]\n    }\n  ]\n}",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "<REDACTED_SLACK_CHANNEL_ID_1>"
        },
        "messageType": "block",
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "id": "<REDACTED_SLACK_CRED_ID>",
          "name": "Slack account (<REDACTED>)"
        }
      },
      "typeVersion": 2.4
    },
    {
      "id": "50fce6b6-5460-4441-9322-6bf5ef4073cf",
      "name": "9) Slack Notify (New Lead) & Button",
      "type": "n8n-nodes-base.slack",
      "position": [
        2576,
        752
      ],
      "webhookId": "<REDACTED_SLACK_NODE_WEBHOOK_ID>",
      "parameters": {
        "text": "=",
        "select": "channel",
        "blocksUi": "={\n  \"blocks\": [\n    {\n      \"type\": \"section\",\n      \"text\": {\n        \"type\": \"mrkdwn\",\n        \"text\": \":scream: *ALERT!!! NEW LEAD ASSIGNED*\\n\\n*Lead ID:* {{ $json.lead_id }}\\n*Assigned to:* <@{{ $json.sales_slack_id }}>\\n*Name:* {{ $json.name }}\\n*Phone:* {{ $json.phone }}\\n\\n:hourglass_flowing_sand: *Please claim within 1 hour*\"\n      }\n    },\n    {\n      \"type\": \"actions\",\n      \"elements\": [\n        {\n          \"type\": \"button\",\n          \"style\": \"primary\",\n          \"text\": {\n            \"type\": \"plain_text\",\n            \"text\": \"Mark as CONTACTED\"\n          },\n          \"value\": \"{{ $json.lead_id }}\",\n          \"action_id\": \"mark_contacted\"\n        }\n      ]\n    }\n  ]\n}",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "<REDACTED_SLACK_CHANNEL_ID_1>"
        },
        "messageType": "block",
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "id": "<REDACTED_SLACK_CRED_ID>",
          "name": "Slack account (<REDACTED>)"
        }
      },
      "typeVersion": 2.4
    },
    {
      "id": "8b9bed18-38c6-462a-b5df-99a84718d4b7",
      "name": "STAGE) Lookup lead by lead_id",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1472,
        1696
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "={{ $json.lead_id }}",
              "lookupColumn": "lead_id"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 0,
          "cachedResultUrl": "<REDACTED_GOOGLE_SHEET_URL>",
          "cachedResultName": "lead_sheet"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "<REDACTED_GOOGLE_SHEET_DOCUMENT_ID>",
          "cachedResultUrl": "<REDACTED_GOOGLE_SHEET_URL>",
          "cachedResultName": "DEMO_SHEET"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "<REDACTED_GSHEETS_CRED_ID>",
          "name": "Google Sheets account (<REDACTED>)"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "ffc50ca6-b358-40f9-a9f9-e3458c1e03e4",
      "name": "STAGE) Prep Payload",
      "type": "n8n-nodes-base.code",
      "position": [
        1248,
        1696
      ],
      "parameters": {
        "jsCode": "// =============================================\n// STAGE) Prep Payload (Slack Interactive - Block Actions)\n// =============================================\n// Slack interactive payload arrives as x-www-form-urlencoded:\n// $json.body.payload is a STRING containing JSON\n\nconst payloadStr = $json?.body?.payload;\n\nif (!payloadStr) {\n  throw new Error('Missing body.payload from Slack (expected x-www-form-urlencoded payload)');\n}\n\nlet slack;\ntry {\n  slack = JSON.parse(payloadStr);\n} catch (e) {\n  throw new Error('Invalid JSON in body.payload');\n}\n\n// Extract lead_id from button value\nconst lead_id = String(slack?.actions?.[0]?.value || '').trim();\n\n// The user who clicked\nconst actor_slack_id = String(slack?.user?.id || '').trim();\n\n// response_url for direct message feedback (optional but recommended)\nconst response_url = String(slack?.response_url || '').trim();\n\n// Target stage to set (this button is for CONTACTED)\nconst stage = 'CONTACTED';\n\nif (!lead_id) throw new Error('lead_id required (expected slack.actions[0].value)');\nif (!actor_slack_id) throw new Error('actor_slack_id missing (expected slack.user.id)');\n\nconst now = new Date().toISOString();\n\nreturn [{\n  json: {\n    lead_id,\n    stage,\n    contacted_at: now,\n    contacted_by: actor_slack_id,\n    actor_slack_id,\n    response_url,     // ✅ needed for \"Not allowed\" feedback\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "42020b30-cae9-4e49-852f-ccc5c601742b",
      "name": "STAGE) If authorized",
      "type": "n8n-nodes-base.if",
      "position": [
        1920,
        1696
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "1ca8acf2-bd8b-4cfd-852e-f09d3e7260c7",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.authorized }}",
              "rightValue": false
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "486062f2-bd86-4006-aeea-8ef2a6230101",
      "name": "STAGE) Slack Feedback - Not allowed",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2144,
        1792
      ],
      "parameters": {
        "url": "={{ $json.response_url }}",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"replace_original\": false,\n  \"text\": \"⚠️ *Access denied.* This lead is currently handled by another sales representative.\\n\\nAssigned to: <@{{ $json.assigned_sales_slack_id }}>\\nClicked by: <@{{ $json.actor_slack_id }}>\\nLead ID: {{ $json.lead_id }}\"\n}\n",
        "sendBody": true,
        "specifyBody": "json"
      },
      "typeVersion": 4.3
    },
    {
      "id": "08a8fef6-9693-4791-b899-308816a89666",
      "name": "STAGE) Authorize click (must be assigned sales)",
      "type": "n8n-nodes-base.code",
      "position": [
        1696,
        1696
      ],
      "parameters": {
        "jsCode": "// =============================================\n// STAGE) Authorization + Idempotency Gate\n// - Only the assigned sales can mark CONTACTED\n// - Only allowed if current stage === 'NEW'\n// =============================================\n\nconst payload = $items('STAGE) Prep Payload')[0].json;\n\n// Lookup result: item from node \"STAGE) Lookup lead by lead_id\"\nconst leadRow = items?.[0]?.json;\n\nif (!leadRow) {\n  return [{\n    json: {\n      ...payload,\n      authorized_owner: false,\n      stage_allowed: false,\n      authorized: false,\n      reason: 'LEAD_NOT_FOUND',\n      assigned_sales_slack_id: '',\n      current_stage: '',\n      lead_name: '',\n      lead_phone: '',\n    }\n  }];\n}\n\nconst assigned = String(leadRow.sales_slack_id || '').trim();\nconst actor = String(payload.actor_slack_id || payload.contacted_by || '').trim();\nconst currentStage = String(leadRow.stage || '').trim().toUpperCase();\n\n// Gate #1: owner check\nconst authorizedOwner = assigned && actor && (assigned === actor);\n\n// Gate #2: stage check (idempotent)\nconst stageAllowed = (currentStage === 'NEW');\n\n// Final allow\nconst authorized = Boolean(authorizedOwner && stageAllowed);\n\n// Reason priority\nlet reason = '';\nif (!authorizedOwner) reason = 'NOT_ASSIGNED_OWNER';\nelse if (!stageAllowed) reason = 'ALREADY_NOT_NEW';\n\nreturn [{\n  json: {\n    ...payload,\n\n    // Flags for the IF node\n    authorized_owner: authorizedOwner,\n    stage_allowed: stageAllowed,\n    authorized,\n\n    reason,\n\n    assigned_sales_slack_id: assigned,\n    current_stage: currentStage,\n\n    // Include lead data for better feedback\n    lead_name: String(leadRow.name || '').trim(),\n    lead_phone: String(leadRow.phone || '').trim(),\n  }\n}];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "f14e59b3-6f63-4e8d-8186-8874d463047f",
      "name": "🚨 SLACK ESCALATION",
      "type": "n8n-nodes-base.slack",
      "position": [
        3408,
        1088
      ],
      "webhookId": "<REDACTED_SLACK_NODE_WEBHOOK_ID>",
      "parameters": {
        "text": "=",
        "select": "channel",
        "blocksUi": "={\n  \"blocks\": [\n    {\n      \"type\": \"section\",\n      \"text\": {\n        \"type\": \"mrkdwn\",\n        \"text\": \"🚨 *LEAD ESCALATION – NO RESPONSE*\\n\\nThis lead has been *re-routed {{ $('IF route_count >= 10').item.json.route_count }} times* without being contacted.\\n\\n*Lead ID:* {{ $('IF route_count >= 10').item.json.lead_id }}\\n*Name:* {{ $('IF route_count >= 10').item.json.name }} \\n*Phone:* {{ $('IF route_count >= 10').item.json.phone }}\\n*Last Assigned Sales:* <@{{ $('IF route_count >= 10').item.json.sales_slack_id }}>\\n\\n⚠️ *Action required from manager.*\"\n      }\n    },\n    {\n      \"type\": \"context\",\n      \"elements\": [\n        {\n          \"type\": \"mrkdwn\",\n          \"text\": \"👤 Escalated to: <@{{ $('Set Manager id').item.json.manager_slack_id }}>\\n🕒 Escalated at: {{ new Date().toISOString() }}\"\n        }\n      ]\n    }\n  ]\n}",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "<REDACTED_SLACK_CHANNEL_ID_2>"
        },
        "messageType": "block",
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "id": "<REDACTED_SLACK_CRED_ID>",
          "name": "Slack account (<REDACTED>)"
        }
      },
      "typeVersion": 2.4
    },
    {
      "id": "5cbd553a-7bad-4bfc-8adc-98ce6485806c",
      "name": "Set Manager id",
      "type": "n8n-nodes-base.set",
      "position": [
        2576,
        1088
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "{\n  \"manager_slack_id\": \"<REDACTED_MANAGER_SLACK_USER_ID>\"\n}\n",
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "328f94e0-f496-46d4-ae9b-8396788c94d8",
      "name": "IF route_count >= 10",
      "type": "n8n-nodes-base.if",
      "position": [
        2352,
        1184
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "d05144bb-b1f2-48da-ae0d-2cfc067d0c15",
              "operator": {
                "type": "number",
                "operation": "gte"
              },
              "leftValue": "={{ $json.route_count }}",
              "rightValue": 10
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "78fdb48e-54b1-47fa-8e75-f65820872006",
      "name": "ESC) Get escalation flag",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2800,
        1088
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "={{ 'escalated_' + $json.lead_id }}",
              "lookupColumn": "key"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 0,
          "cachedResultUrl": "<REDACTED_GOOGLE_SHEET_URL>",
          "cachedResultName": "routing_state_sheet"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "<REDACTED_GOOGLE_SHEET_DOCUMENT_ID>",
          "cachedResultUrl": "<REDACTED_GOOGLE_SHEET_URL>",
          "cachedResultName": "DEMO_SHEET"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "<REDACTED_GSHEETS_CRED_ID>",
          "name": "Google Sheets account (<REDACTED>)"
        }
      },
      "typeVersion": 4.7,
      "alwaysOutputData": true
    },
    {
      "id": "7a5107c4-1ebd-403a-b6d8-a1d0d793d664",
      "name": "ESC) Set escalation flag",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        3648,
        1088
      ],
      "parameters": {
        "columns": {
          "value": {
            "key": "={{ 'escalated_' + $items('SLA) Re-route to next sales')[$itemIndex].json.lead_id }}",
            "value": "={{ new Date().toISOString() }}"
          },
          "schema": [
            {
              "id": "key",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "key",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "value",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "value",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "key"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "appendOrUpdate",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 0,
          "cachedResultUrl": "<REDACTED_GOOGLE_SHEET_URL>",
          "cachedResultName": "routing_state_sheet"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "<REDACTED_GOOGLE_SHEET_DOCUMENT_ID>",
          "cachedResultUrl": "<REDACTED_GOOGLE_SHEET_URL>",
          "cachedResultName": "DEMO_SHEET"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "<REDACTED_GSHEETS_CRED_ID>",
          "name": "Google Sheets account (<REDACTED>)"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "12854bb3-1ab6-42a2-ba90-4bb1ee83ddca",
      "name": "ESC) Normalize flag result",
      "type": "n8n-nodes-base.code",
      "position": [
        2992,
        1088
      ],
      "parameters": {
        "jsCode": "// Read the lead from the previous node in the escalation path (must have lead_id)\nconst lead = $json;\n\n// Lookup results from ESC) Get escalation flag\nconst rows = $items(\"ESC) Get escalation flag\").map(i => i.json);\n\n// Consider it found only if there is a non-empty key/value\nconst found = rows.some(r => r && String(r.key || \"\").trim() !== \"\");\n\nreturn [{\n  json: {\n    ...lead,\n    esc_key: `escalated_${lead.lead_id}`,\n    already_escalated: found,\n    esc_row: found ? rows.find(r => String(r.key || \"\").trim() !== \"\") : null\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "cfd92876-0c6f-4e3a-b4dd-26a6981427e9",
      "name": "ESC) If not escalated yet",
      "type": "n8n-nodes-base.if",
      "position": [
        3200,
        1088
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "5c1b6c7a-acdf-4ea7-bcf4-047bd3a201a7",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.already_escalated === false }}",
              "rightValue": ""
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.3
    },
    {
      "id": "d2c74230-2458-4143-b7ba-e8a73dc3f9b1",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        112,
        512
      ],
      "parameters": {
        "width": 752,
        "height": 736,
        "content": "## SLA-Based Lead Routing & Auto Reassignment Workflow\n\nThis workflow implements an SLA-based lead routing system designed to ensure fast response times and prevent lead neglect through automated reassignment and escalation.\n\nWhen a new lead is submitted, the workflow immediately assigns it to a sales representative using a round-robin distribution. This ensures fair workload allocation across the sales team and avoids manual lead picking.\n\nA 1-hour SLA threshold is applied after each assignment. If the lead remains in the “NEW” stage and has not been contacted within this timeframe, the system automatically re-routes the lead to the next available sales representative in a circular order.\n\nThe SLA duration can be adjusted easily by modifying the Schedule Trigger configuration.\n\nWhile this implementation uses Google Sheets as a lightweight operational datastore and Slack as the interaction layer, the same logic can be adapted to other databases or CRM platforms (such as Salesforce, HubSpot, or PostgreSQL).\n\nA scheduled process periodically scans the lead database and identifies leads that meet the following conditions:\n\na) Lead stage is NEW\nb) No contact activity has occurred within the SLA window\n\nQualified leads are automatically re-assigned, and Slack notifications are sent to the newly assigned sales representative with an interactive “Mark as CONTACTED” action.\n\nTo maintain operational safety:\n\na) Only the currently assigned sales representative is allowed to update the lead status\nb) Stage updates are idempotent, preventing duplicate or accidental re-processing\nc) Repeated SLA breaches trigger a one-time escalation to a manager, ensuring visibility without notification spam\n\nThis workflow helps improve response speed, enforces consistent follow-up behavior, and introduces operational discipline without requiring a full CRM system."
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "pinData": {},
  "settings": {
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "<REDACTED_WORKFLOW_VERSION_ID>",
  "connections": {
    "2) Prep Lead": {
      "main": [
        [
          {
            "node": "3) Get Sales List (active=ON)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Manager id": {
      "main": [
        [
          {
            "node": "ESC) Get escalation flag",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4) Build Sales List": {
      "main": [
        [
          {
            "node": "5) Get routing_state (last_index)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SLA) Get Sales List": {
      "main": [
        [
          {
            "node": "SLA) Build Sales List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "STAGE) Prep Payload": {
      "main": [
        [
          {
            "node": "STAGE) Lookup lead by lead_id",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF route_count >= 10": {
      "main": [
        [
          {
            "node": "Set Manager id",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "SLA) Update lead (after reroute)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "STAGE) If authorized": {
      "main": [
        [
          {
            "node": "STAGE) Update lead stage to CONTACTED",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "STAGE) Slack Feedback - Not allowed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SLA) Build Sales List": {
      "main": [
        [
          {
            "node": "SLA) Get Leads (stage=NEW)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🚨 SLACK ESCALATION": {
      "main": [
        [
          {
            "node": "ESC) Set escalation flag",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "7) Update routing_state": {
      "main": [
        []
      ]
    },
    "ESC) Get escalation flag": {
      "main": [
        [
          {
            "node": "ESC) Normalize flag result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ESC) If not escalated yet": {
      "main": [
        [
          {
            "node": "🚨 SLACK ESCALATION",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "1) Form Trigger (New Lead)": {
      "main": [
        [
          {
            "node": "2) Prep Lead",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ESC) Normalize flag result": {
      "main": [
        [
          {
            "node": "ESC) If not escalated yet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SLA Trigger (every 1 hour)": {
      "main": [
        [
          {
            "node": "SLA) Get Sales List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SLA) Get Leads (stage=NEW)": {
      "main": [
        [
          {
            "node": "SLA) If last route >= 1 hour",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SLA) Re-route to next sales": {
      "main": [
        [
          {
            "node": "IF route_count >= 10",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8) Upsert Lead (leads sheet)": {
      "main": [
        [
          {
            "node": "9) Slack Notify (New Lead) & Button",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SLA) If last route >= 1 hour": {
      "main": [
        [
          {
            "node": "SLA) Re-route to next sales",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "3) Get Sales List (active=ON)": {
      "main": [
        [
          {
            "node": "4) Build Sales List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "STAGE) Lookup lead by lead_id": {
      "main": [
        [
          {
            "node": "STAGE) Authorize click (must be assigned sales)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "6) Initial Assign (Round Robin)": {
      "main": [
        [
          {
            "node": "7) Update routing_state",
            "type": "main",
            "index": 0
          },
          {
            "node": "8) Upsert Lead (leads sheet)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SLA) Update lead (after reroute)": {
      "main": [
        [
          {
            "node": "SLA) Slack Notify (reroute) & Button",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "5) Get routing_state (last_index)": {
      "main": [
        [
          {
            "node": "6) Initial Assign (Round Robin)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "STAGE) Webhook (/demo-stage-update)": {
      "main": [
        [
          {
            "node": "STAGE) Prep Payload",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SLA) Slack Notify (reroute) & Button": {
      "main": [
        []
      ]
    },
    "STAGE) Update lead stage to CONTACTED": {
      "main": [
        []
      ]
    },
    "STAGE) Authorize click (must be assigned sales)": {
      "main": [
        [
          {
            "node": "STAGE) If authorized",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}