{
  "name": "LDS - Driver Onboarding Chase (DEMO)",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "lds-applicant",
        "responseMode": "onReceived",
        "options": {}
      },
      "id": "w3-hook",
      "name": "Applicant submitted",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -540,
        160
      ],
      "notes": "Point the careers form (or Indeed/ZipRecruiter webhook) at this URL."
    },
    {
      "parameters": {
        "jsCode": "\n// Applicant intake. Demo mode when the webhook body is empty.\nconst SAMPLE = { full_name: 'R. Sandhu', phone: '+14035550188', email: 'driver1@example.com',\n                 cdl_number: 'A1234-56789', submitted_at: '2026-10-05T09:10:00-06:00' };\nconst raw = ($json && $json.body && Object.keys($json.body).length) ? $json.body : SAMPLE;\n\nconst REQUIRED = ['application_form', 'cdl_copy', 'medical_card', 'drug_test_record',\n                  'mvr_report', 'insurance_ack'];\nconst received = raw.documents_received || ['application_form', 'cdl_copy'];\nconst missing  = REQUIRED.filter(d => !received.includes(d));\n\nreturn [{\n  full_name: raw.full_name || 'Unknown applicant',\n  phone: String(raw.phone || '').replace(/[^0-9+]/g, ''),\n  email: raw.email || '',\n  cdl_number: raw.cdl_number || '',\n  submitted_at: raw.submitted_at || new Date().toISOString(),\n  documents_required: REQUIRED,\n  documents_received: received,\n  documents_missing: missing,\n  file_complete: missing.length === 0,\n  ack_body: `Thanks ${raw.full_name || ''} - we have your application. We still need: ` +\n            `${missing.join(', ') || 'nothing, your file is complete'}. ` +\n            `Reply with photos and we'll take it from there.`,\n}];\n"
      },
      "id": "w3-parse",
      "name": "Parse applicant + checklist",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -310,
        160
      ]
    },
    {
      "parameters": {
        "sendTo": "={{ $json.email }}",
        "subject": "=Your application - what we still need",
        "message": "={{ $json.ack_body }}",
        "options": {}
      },
      "id": "w3-ack",
      "name": "Instant acknowledgement",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        -80,
        40
      ],
      "notes": "Swap for SMS - drivers respond to text, not email."
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://REPLACE-WITH-CRM-OR-SHEETS-ENDPOINT",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify($json) }}",
        "options": {}
      },
      "id": "w3-crm",
      "name": "Create applicant record",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -80,
        280
      ]
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 9 * * *"
            }
          ]
        }
      },
      "id": "w3-cron",
      "name": "Daily 9am",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        -540,
        520
      ]
    },
    {
      "parameters": {
        "jsCode": "\n// Daily chaser. Demo mode: sample applicants; on a live client this reads a sheet/CRM.\nconst SAMPLE = [\n  { full_name: 'R. Sandhu', phone: '+14035550188', submitted_at: '2026-10-01T09:00:00-06:00', documents_missing: ['medical_card', 'mvr_report'], chases_sent: 1 },\n  { full_name: 'M. Okafor', phone: '+14035550102', submitted_at: '2026-10-04T09:00:00-06:00', documents_missing: ['drug_test_record'], chases_sent: 0 },\n  { full_name: 'J. Tremblay', phone: '+14035550103', submitted_at: '2026-09-26T09:00:00-06:00', documents_missing: ['insurance_ack'], chases_sent: 3 },\n  { full_name: 'A. Haddad', phone: '+14035550104', submitted_at: '2026-10-03T09:00:00-06:00', documents_missing: [], chases_sent: 0 },\n];\nconst applicants = ($json && $json.applicants) ? $json.applicants : SAMPLE;\nconst now = Date.now();\n\nreturn applicants.map(a => {\n  const days = Math.floor((now - new Date(a.submitted_at).getTime()) / 86400000);\n  let action = 'none';\n  if (a.documents_missing.length === 0) action = 'none';\n  else if (a.chases_sent >= 3 || days >= 7) action = 'escalate';\n  else action = 'chase';\n  return {\n    ...a,\n    days_waiting: days,\n    missing_count: a.documents_missing.length,\n    action: action,\n    chase_body: `Hi ${a.full_name}, we still need ${a.documents_missing.join(', ')} to finish ` +\n                `your file and get you seated. A photo by text is fine.`,\n    escalation_body: `${a.full_name} (${a.phone}) has been waiting ${days} day(s) for: ` +\n                     `${a.documents_missing.join(', ')} after ${a.chases_sent} chase(s). Needs a human call.`,\n  };\n});\n"
      },
      "id": "w3-chase",
      "name": "Load incomplete + choose action",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -310,
        520
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "c1",
              "leftValue": "={{ $json.action }}",
              "rightValue": "none",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "w3-if",
      "name": "Still chasing?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        -80,
        520
      ]
    },
    {
      "parameters": {
        "sendTo": "={{ $json.phone }}@CARRIER-GATEWAY (swap for SMS)",
        "subject": "=Documents still outstanding",
        "message": "={{ $json.chase_body }}",
        "options": {}
      },
      "id": "w3-chase-send",
      "name": "Chase the driver",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        170,
        400
      ]
    },
    {
      "parameters": {
        "sendTo": "={{ $env.COMPLIANCE_MANAGER_EMAIL || 'compliance@example.com' }}",
        "subject": "=Needs a human call: {{ $json.full_name }}",
        "message": "={{ $json.escalation_body }}",
        "options": {}
      },
      "id": "w3-escalate",
      "name": "Escalate to manager",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        170,
        560
      ]
    },
    {
      "parameters": {},
      "id": "w3-none",
      "name": "File complete, no action",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        170,
        700
      ]
    }
  ],
  "connections": {
    "Applicant submitted": {
      "main": [
        [
          {
            "node": "Parse applicant + checklist",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse applicant + checklist": {
      "main": [
        [
          {
            "node": "Instant acknowledgement",
            "type": "main",
            "index": 0
          },
          {
            "node": "Create applicant record",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Daily 9am": {
      "main": [
        [
          {
            "node": "Load incomplete + choose action",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Load incomplete + choose action": {
      "main": [
        [
          {
            "node": "Still chasing?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Still chasing?": {
      "main": [
        [
          {
            "node": "Chase the driver",
            "type": "main",
            "index": 0
          },
          {
            "node": "Escalate to manager",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "File complete, no action",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "tags": []
}