{
  "name": "LDS - Driver Document Expiry Watch",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 8 * * *"
            }
          ]
        }
      },
      "id": "trigger-daily",
      "name": "Daily 8am",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        -460,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "// DEMO DATA - swap this node for 'Google Sheets: Get Rows' on a real client.\n// Expected columns: driver, doc_type, expiry_date, email, phone\nconst drivers = $json.drivers || [\n  { driver: 'R. Sandhu',  doc_type: 'Medical Card',       expiry_date: '2026-10-11', email: 'driver1@example.com', phone: '+14035550101' },\n  { driver: 'M. Okafor',  doc_type: 'CDL',                expiry_date: '2026-11-03', email: 'driver2@example.com', phone: '+14035550102' },\n  { driver: 'J. Tremblay',doc_type: 'Insurance Cert',     expiry_date: '2026-12-15', email: 'driver3@example.com', phone: '+14035550103' },\n  { driver: 'A. Haddad',  doc_type: 'Drug Test Record',   expiry_date: '2027-01-20', email: 'driver4@example.com', phone: '+14035550104' }\n];\nconst today = new Date();\ntoday.setHours(0,0,0,0);\nreturn drivers.map(d => {\n  const exp = new Date(d.expiry_date + 'T00:00:00');\n  const days = Math.round((exp - today) / 86400000);\n  let tier = null;\n  if (days < 0) tier = 'LAPSED';\n  else if (days <= 1) tier = '1_DAY';\n  else if (days <= 7) tier = '7_DAY';\n  else if (days <= 14) tier = '14_DAY';\n  else if (days <= 30) tier = '30_DAY';\n  else if (days <= 60) tier = '60_DAY';\n  return { ...d, days_until_expiry: days, tier: tier, action: tier ? 'notify' : 'skip' };\n});"
      },
      "id": "calc-expiry",
      "name": "Calc days to expiry",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -240,
        300
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "cond-action",
              "leftValue": "={{ $json.action }}",
              "rightValue": "notify",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "filter-notify",
      "name": "Due for reminder?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        -20,
        300
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "a1",
              "name": "subject",
              "value": "=ACTION REQUIRED: {{ $json.doc_type }} for {{ $json.driver }} expires soon",
              "type": "string"
            },
            {
              "id": "a2",
              "name": "body",
              "value": "=Hi {{ $json.driver }},\n\nYour {{ $json.doc_type }} expires in {{ $json.days_until_expiry }} day(s) on {{ $json.expiry_date }}.\n\nPlease send us an updated copy today so we can keep your file audit-ready.\n\nReply to this email with a photo or scan and we'll update your file.\n\nThank you,\nFleet Compliance Team",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "build-reminder",
      "name": "Build reminder",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        200,
        200
      ]
    },
    {
      "parameters": {
        "sendTo": "={{ $json.email }}",
        "subject": "={{ $json.subject }}",
        "message": "={{ $json.body }}",
        "options": {}
      },
      "id": "send-email",
      "name": "Send driver reminder",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        420,
        200
      ],
      "notes": "Swap for SMTP/Twilio/GoHighLevel depending on client stack"
    },
    {
      "parameters": {
        "aggregate": "aggregateAllItemData",
        "options": {}
      },
      "id": "collect-alerts",
      "name": "Collect all due",
      "type": "n8n-nodes-base.aggregate",
      "typeVersion": 1,
      "position": [
        200,
        420
      ]
    },
    {
      "parameters": {
        "sendTo": "={{ $env.COMPLIANCE_MANAGER_EMAIL || 'compliance@example.com' }}",
        "subject": "=Fleet summary: {{ $json.data.length }} document(s) need attention",
        "message": "={{ $json.data.map(d => `- ${d.driver}: ${d.doc_type} \u2014 ${d.days_until_expiry} day(s) [${d.tier}]`).join('\\n') }}",
        "options": {}
      },
      "id": "send-manager",
      "name": "Escalate summary to manager",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        420,
        420
      ]
    },
    {
      "parameters": {
        "content": "",
        "height": 280,
        "width": 480,
        "color": 4
      },
      "id": "note-demo",
      "name": "DEMO NOTES",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -560,
        40
      ],
      "notes": "DOCUMENT EXPIRY WATCH (Tier 1)\n\nDEMO MODE: the Code node holds sample drivers.\nSwap it for 'Google Sheets: Get Rows' (or Airtable/Postgres) on a real client.\n\nTiers: 60 / 30 / 14 / 7 / 1 day, plus LAPSED for overdue.\nDriver gets a reminder; compliance manager gets an aggregate escalation.\n\nNothing here is trucking-specific plumbing \u2014 it works for any document-expiry regime."
    },
    {
      "parameters": {},
      "id": "noop",
      "name": "No reminders today",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        200,
        600
      ]
    }
  ],
  "connections": {
    "Daily 8am": {
      "main": [
        [
          {
            "node": "Calc days to expiry",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calc days to expiry": {
      "main": [
        [
          {
            "node": "Due for reminder?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Due for reminder?": {
      "main": [
        [
          {
            "node": "Build reminder",
            "type": "main",
            "index": 0
          },
          {
            "node": "Collect all due",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "No reminders today",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build reminder": {
      "main": [
        [
          {
            "node": "Send driver reminder",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Collect all due": {
      "main": [
        [
          {
            "node": "Escalate summary to manager",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "tags": []
}