{
  "name": "LGM 03 — Quote Follow-Up (SIMULATED)",
  "nodes": [
    {
      "parameters": {},
      "id": "f03-start",
      "name": "Start",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        240,
        320
      ]
    },
    {
      "parameters": {
        "jsCode": "// Fictional quote that was sent N days ago. Re-run to exercise each branch\n// by changing branch_hint and days_since_sent.\nconst fixture = {\n  quote_id: 'Q-' + Math.floor(Math.random() * 9000 + 1000),\n  customer_name: 'Priya Anand',\n  customer_email: 'priya@example.invalid',\n  customer_phone: '+61400000333',\n  job_description: 'Replace shower screen + regrout',\n  quote_amount_aud: 780,\n  days_since_sent: 4,\n  branch_hint: 'soft-checkin',\n  business: 'Outback Glass'\n};\nreturn [{ json: fixture }];"
      },
      "id": "f03-fixture",
      "name": "Build Fixture",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        460,
        320
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "leftValue": "={{ $json.days_since_sent }}",
              "rightValue": 14,
              "operator": {
                "type": "number",
                "operation": "gte"
              }
            }
          ]
        }
      },
      "id": "f03-stale",
      "name": "Stale Check",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        680,
        320
      ]
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "loose"
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.branch_hint }}",
                    "rightValue": "visit-reminder",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "outputKey": "visit-reminder",
              "renameOutput": true
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "loose"
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.branch_hint }}",
                    "rightValue": "approve",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "outputKey": "approve",
              "renameOutput": true
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra"
        }
      },
      "id": "f03-switch",
      "name": "Choose Branch",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.2,
      "position": [
        900,
        480
      ]
    },
    {
      "parameters": {
        "jsCode": "// Stale quote (>14 days) — close out and offer re-engagement at 90 days.\nconst items = $input.all();\nconst $json = items[0].json;\nconst simulatedOutputs = [\n  { type: 'heading', label: '1. CRM tag (SIMULATED Twenty)' },\n  { type: 'crm', label: 'Twenty CRM', rows: [\n    { label: 'Quote', value: $json.quote_id },\n    { label: 'Stage', value: 'Closed — no reply' },\n    { label: 'Days since sent', value: String($json.days_since_sent) }\n  ]},\n  { type: 'heading', label: '2. Customer email (SIMULATED Listmonk)' },\n  { type: 'message', channel: 'email', label: 'Listmonk', subject: 'Closing out your quote',\n    body: `Hi ${$json.customer_name}, we'll close out the ${$json.job_description} quote for now. If anything changes, just reply — your quote will be waiting. — ${$json.business}` },\n  { type: 'note', label: 'Re-engagement policy',\n    text: 'Tagged quote-closed. Re-engagement at 90 days with consent.' }\n];\nreturn [{ json: { ...$json, branch: 'closed', simulatedOutputs } }];"
      },
      "id": "f03-close",
      "name": "Build Close Output",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        900,
        200
      ]
    },
    {
      "parameters": {
        "jsCode": "// Soft check-in email — for quotes 0–13 days old with no reply.\nconst items = $input.all();\nconst $json = items[0].json;\nconst simulatedOutputs = [\n  { type: 'heading', label: '1. CRM touch (SIMULATED Twenty)' },\n  { type: 'crm', label: 'Twenty CRM', rows: [\n    { label: 'Quote', value: $json.quote_id },\n    { label: 'Stage', value: 'Open → Soft check-in' },\n    { label: 'Days since sent', value: String($json.days_since_sent) }\n  ]},\n  { type: 'heading', label: '2. Customer email (SIMULATED Listmonk)' },\n  { type: 'message', channel: 'email', label: 'Listmonk', subject: 'Did you have any questions about your quote?',\n    body: `Hi ${$json.customer_name}, just checking in on the ${$json.job_description} quote ($${$json.quote_amount_aud}). If anything's unclear, hit reply — happy to walk through it. No need to commit today. — ${$json.business}` }\n];\nreturn [{ json: { ...$json, branch: 'soft-checkin', simulatedOutputs } }];"
      },
      "id": "f03-soft",
      "name": "Build Soft Check-In",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1140,
        420
      ]
    },
    {
      "parameters": {
        "jsCode": "// Visit reminder SMS — quote accepted but visit slot unconfirmed.\nconst items = $input.all();\nconst $json = items[0].json;\nconst simulatedOutputs = [\n  { type: 'heading', label: '1. CRM touch (SIMULATED Twenty)' },\n  { type: 'crm', label: 'Twenty CRM', rows: [\n    { label: 'Quote', value: $json.quote_id },\n    { label: 'Stage', value: 'Accepted → Visit slot hold' }\n  ]},\n  { type: 'heading', label: '2. Customer SMS (SIMULATED Chatwoot)' },\n  { type: 'message', channel: 'sms', label: 'SMS',\n    body: `Hi ${$json.customer_name}, friendly reminder — we can hold the visit slot for the ${$json.job_description} for another week. Reply HOLD or RESCHEDULE. — ${$json.business}` }\n];\nreturn [{ json: { ...$json, branch: 'visit-reminder', simulatedOutputs } }];"
      },
      "id": "f03-visit",
      "name": "Build Visit Reminder",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1140,
        560
      ]
    },
    {
      "parameters": {
        "jsCode": "// Approval path — quote accepted, schedule a visit.\nconst items = $input.all();\nconst $json = items[0].json;\nconst simulatedOutputs = [\n  { type: 'heading', label: '1. CRM transition (SIMULATED Twenty)' },\n  { type: 'crm', label: 'Twenty CRM', rows: [\n    { label: 'Quote', value: $json.quote_id },\n    { label: 'Stage', value: 'Approved → Operations' }\n  ]},\n  { type: 'heading', label: '2. Confirmation email (SIMULATED Listmonk)' },\n  { type: 'message', channel: 'email', label: 'Listmonk', subject: \"Great — let's lock it in\",\n    body: `Hi ${$json.customer_name}, thanks for the go-ahead. We'll be in touch within 1 business day to confirm a visit window. Booking reference ${$json.quote_id}. — ${$json.business}` },\n  { type: 'heading', label: '3. Internal task (SIMULATED Todoist)' },\n  { type: 'task', label: 'Todoist', title: 'Schedule visit and confirm window',\n    owner: 'Operations', dueIn: 'Within 1 business day', notes: `Ref: ${$json.quote_id}` }\n];\nreturn [{ json: { ...$json, branch: 'approve', simulatedOutputs } }];"
      },
      "id": "f03-approve",
      "name": "Build Approve Output",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1140,
        700
      ]
    },
    {
      "parameters": {},
      "id": "f03-sink",
      "name": "Sink",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        1380,
        480
      ]
    }
  ],
  "connections": {
    "Start": {
      "main": [
        [
          {
            "node": "Build Fixture",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Fixture": {
      "main": [
        [
          {
            "node": "Stale Check",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Stale Check": {
      "main": [
        [
          {
            "node": "Build Close Output",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Choose Branch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Choose Branch": {
      "main": [
        [
          {
            "node": "Build Soft Check-In",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Build Visit Reminder",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Build Approve Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Close Output": {
      "main": [
        [
          {
            "node": "Sink",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Soft Check-In": {
      "main": [
        [
          {
            "node": "Sink",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Visit Reminder": {
      "main": [
        [
          {
            "node": "Sink",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Approve Output": {
      "main": [
        [
          {
            "node": "Sink",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "callerPolicy": "workflowsFromSameOwner"
  },
  "versionId": "lgm-03-quote-followup",
  "id": "lgm-03-quote-followup",
  "meta": {
    "templateCredsSetupCompleted": false,
    "description": "SIMULATED quote follow-up. Branches by days_since_sent and branch_hint. Replaces Jobber-style automation."
  },
  "tags": [
    {
      "name": "lgm-03-quote-followup"
    }
  ]
}
