{
  "name": "LGM 04 — Review Request (SIMULATED)",
  "nodes": [
    {
      "parameters": {},
      "id": "f04-start",
      "name": "Start",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        240,
        320
      ]
    },
    {
      "parameters": {
        "jsCode": "// Fictional job-complete webhook payload. Every eligible customer gets the\n// SAME public review link; low ratings route to a private service alert\n// IN ADDITION (never as a replacement).\nconst fixture = {\n  event_id: 'JOB-' + Math.floor(Math.random() * 90000 + 10000),\n  event_type: 'job_completed',\n  customer_name: 'Hannah Wu',\n  customer_phone: '+61400000444',\n  customer_email: 'hannah@example.invalid',\n  job_type: 'exterior repaint',\n  technician: 'Sam',\n  public_review_url: 'https://example.invalid/r/abc',\n  business: 'Coastline Painting',\n  marketing_consent: true,\n  // Hint selector for the branch demo.\n  branch_hint: 'neutral-send',\n  rating: 5\n};\nreturn [{ json: fixture }];"
      },
      "id": "f04-fixture",
      "name": "Build Fixture",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        460,
        320
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "c1",
              "leftValue": "={{ $json.marketing_consent }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            },
            {
              "id": "c2",
              "leftValue": "={{ $json.rating }}",
              "rightValue": 4,
              "operator": {
                "type": "number",
                "operation": "lt"
              }
            }
          ]
        }
      },
      "id": "f04-low",
      "name": "Low Rating?",
      "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": "reminder",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "outputKey": "reminder",
              "renameOutput": true
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra"
        }
      },
      "id": "f04-switch",
      "name": "Pick Channel",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.2,
      "position": [
        900,
        480
      ]
    },
    {
      "parameters": {
        "jsCode": "// Private service-recovery alert. Public review link is NOT replaced.\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: 'Job', value: $json.event_id },\n    { label: 'Stage', value: 'Completed → Low rating flagged' },\n    { label: 'Rating', value: `${$json.rating}/5` }\n  ]},\n  { type: 'heading', label: '2. Public review request (SIMULATED Chatwoot / SMS)' },\n  { type: 'message', channel: 'sms', label: 'SMS',\n    body: `Hi ${$json.customer_name}, thanks for choosing ${$json.business} for your ${$json.job_type}. If you have a moment, a Google review helps other locals find us → ${$json.public_review_url}` },\n  { type: 'heading', label: '3. Private service-recovery alert (SIMULATED internal)' },\n  { type: 'message', channel: 'internal', label: 'Slack/Teams',\n    body: `Customer ${$json.customer_name} rated the ${$json.job_type} ${$json.rating}/5. Public review link is still active; opening service-recovery queue.` },\n  { type: 'heading', label: '4. Recovery task (SIMULATED Todoist)' },\n  { type: 'task', label: 'Todoist',\n    title: 'Service-recovery call within 24 hours',\n    owner: 'Operations', dueIn: 'Within 24h',\n    notes: `Ref: ${$json.event_id}` }\n];\nreturn [{ json: { ...$json, branch: 'private-alert', simulatedOutputs } }];"
      },
      "id": "f04-alert",
      "name": "Build Alert Output",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        900,
        200
      ]
    },
    {
      "parameters": {
        "jsCode": "// Neutral send — single neutral review request. Same link for everyone.\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: 'Job', value: $json.event_id },\n    { label: 'Stage', value: 'Completed → Review request sent' }\n  ]},\n  { type: 'heading', label: '2. SMS review request (SIMULATED Chatwoot)' },\n  { type: 'message', channel: 'sms', label: 'SMS',\n    body: `Hi ${$json.customer_name}, thanks for choosing ${$json.business} for your ${$json.job_type}. If you have a moment, a Google review helps other locals find us → ${$json.public_review_url} — ${$json.business}` },\n  { type: 'note', label: 'Compliance',\n    text: 'Every eligible customer receives the SAME link, regardless of sentiment. STOP keyword suppressed in Listmonk.' }\n];\nreturn [{ json: { ...$json, branch: 'neutral-send', simulatedOutputs } }];"
      },
      "id": "f04-neutral",
      "name": "Build Neutral Output",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1140,
        420
      ]
    },
    {
      "parameters": {
        "jsCode": "// Follow-up reminder 7 days later if no review has been posted.\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: 'Job', value: $json.event_id },\n    { label: 'Stage', value: 'Completed → Review reminder sent' }\n  ]},\n  { type: 'heading', label: '2. Reminder SMS (SIMULATED Chatwoot)' },\n  { type: 'message', channel: 'sms', label: 'SMS',\n    body: `Hi ${$json.customer_name}, just a reminder about the Google review for your ${$json.job_type}. Tap when you've got a sec: ${$json.public_review_url} — ${$json.business}` },\n  { type: 'note', label: 'Compliance',\n    text: 'Max 2 sends per job. STOP suppresses further reminders.' }\n];\nreturn [{ json: { ...$json, branch: 'reminder', simulatedOutputs } }];"
      },
      "id": "f04-remind",
      "name": "Build Reminder",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1140,
        560
      ]
    },
    {
      "parameters": {},
      "id": "f04-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": "Low Rating?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Low Rating?": {
      "main": [
        [
          {
            "node": "Build Alert Output",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Pick Channel",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Pick Channel": {
      "main": [
        [
          {
            "node": "Build Neutral Output",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Build Reminder",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Alert Output": {
      "main": [
        [
          {
            "node": "Sink",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Neutral Output": {
      "main": [
        [
          {
            "node": "Sink",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Reminder": {
      "main": [
        [
          {
            "node": "Sink",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "callerPolicy": "workflowsFromSameOwner"
  },
  "versionId": "lgm-04-review-request",
  "id": "lgm-04-review-request",
  "meta": {
    "templateCredsSetupCompleted": false,
    "description": "SIMULATED review-request automation. Same neutral link for everyone; low ratings add (never replace) a private alert."
  },
  "tags": [
    {
      "name": "lgm-04-review-request"
    }
  ]
}
