{
  "name": "Project2 - WordPress inquiry with manual review",
  "nodes": [
    {
      "parameters": {
        "authentication": "headerAuth",
        "httpMethod": "POST",
        "path": "project2-inquiry-v1",
        "responseMode": "responseNode",
        "options": {}
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [-840, 0],
      "id": "89ad7e4f-2fd5-42cb-a01a-45df46cf7779",
      "name": "WordPress Inquiry Webhook",
      "webhookId": "dc57bc51-4e06-4ff3-a988-2e59ae31ac6a",
      "notes": "INACTIVE CANDIDATE. Configure a Header Auth credential before any activation."
    },
    {
      "parameters": {
        "jsCode": "const body = $json.body ?? $json;\nconst text = (value) => String(value ?? '').normalize('NFKC').trim();\nconst consented = (value) => value === true || ['true','1','yes','on','同意する'].includes(text(value).toLowerCase());\nconst emailPattern = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\nconst name = text(body.name);\nconst email = text(body.email).toLowerCase();\nconst company = text(body.company);\nconst message = text(body.message);\nconst source = text(body.source) || 'wordpress';\nlet errorCode = '';\nif (text(body.website)) errorCode = 'SPAM_SIGNAL';\nelse if (!consented(body.consent)) errorCode = 'CONSENT_REQUIRED';\nelse if (!name || name.length > 100) errorCode = 'INVALID_NAME';\nelse if (email.length > 254 || !emailPattern.test(email)) errorCode = 'INVALID_EMAIL';\nelse if (company.length > 150) errorCode = 'INVALID_COMPANY';\nelse if (!message || message.length > 2000) errorCode = 'INVALID_MESSAGE';\nconst ticketId = `inq_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;\nconst priorityHint = ['至急','緊急','本日','今日中','見積','契約'].some((term) => message.includes(term)) ? 'high' : 'normal';\nreturn [{ json: {\n  valid: !errorCode,\n  error_code: errorCode,\n  public_response: errorCode\n    ? { accepted: false, code: errorCode, message: '入力内容を確認して、もう一度送信してください。' }\n    : { accepted: true, ticket_id: ticketId, message: 'お問い合わせを受け付けました。確認後に担当者が対応します。' },\n  review_record: errorCode ? null : { ticket_id: ticketId, review_state: 'pending', priority_hint: priorityHint, source, contact: { name, email, company }, message, consent_recorded: true }\n} }];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [-600, 0],
      "id": "4d6b65df-6f30-4863-9758-475ab399a7e6",
      "name": "Validate and Normalize"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "f14fbefd-b50a-4608-91af-f3c224ef628b",
              "leftValue": "={{ $json.valid }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [-360, 0],
      "id": "b9b51b62-271e-48cd-bb86-e7d4b3bdd2a6",
      "name": "Valid?"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ $json.public_response }}",
        "options": {
          "responseCode": 202
        }
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.4,
      "position": [-100, -120],
      "id": "8f16455e-bbe5-419a-88c6-bad7133df8ec",
      "name": "Respond Accepted"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ $json.public_response }}",
        "options": {
          "responseCode": 400
        }
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.4,
      "position": [-100, 160],
      "id": "683ea8a5-bab8-4856-aa1c-695a1f51cb04",
      "name": "Respond Rejected"
    },
    {
      "parameters": {
        "resume": "form",
        "formTitle": "問い合わせレビュー",
        "formDescription": "CRMへ渡す前に、内容と同意を確認してください。このリンクは本番では認証された担当者だけに公開します。",
        "formFields": {
          "values": [
            {
              "fieldLabel": "Decision",
              "fieldType": "dropdown",
              "fieldOptions": {
                "values": [
                  {"option": "approve"},
                  {"option": "reject"}
                ]
              },
              "requiredField": true
            },
            {
              "fieldLabel": "Review note",
              "fieldType": "textarea"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [160, -120],
      "id": "19991184-c766-4de0-9486-829a39ee04b6",
      "name": "Manual Review",
      "webhookId": "3d10b599-96fd-4ef9-8797-eb1650b54f23",
      "notes": "RUNTIME UNMEASURED. Protect the generated review URL with authenticated reviewer-only access before production."
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "26e40e31-559c-48ed-970d-7ce2cce52c56",
              "leftValue": "={{ $json['Decision'] }}",
              "rightValue": "approve",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [400, -120],
      "id": "38b3c652-5974-4af5-82dd-0e2105788bfa",
      "name": "Approved?"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "c812f36d-898b-42f2-9e8d-f93a2ecf19fd",
              "name": "properties.email",
              "value": "={{ $('Validate and Normalize').item.json.review_record.contact.email }}",
              "type": "string"
            },
            {
              "id": "52cb3a54-93e4-4dbc-a0db-5ab36cc241f0",
              "name": "properties.firstname",
              "value": "={{ $('Validate and Normalize').item.json.review_record.contact.name }}",
              "type": "string"
            },
            {
              "id": "4ad83231-d9a6-41cb-8fc9-67f6393930f6",
              "name": "properties.company",
              "value": "={{ $('Validate and Normalize').item.json.review_record.contact.company }}",
              "type": "string"
            },
            {
              "id": "17202457-b609-4cc0-9617-47ed697b1e92",
              "name": "source_ticket_id",
              "value": "={{ $('Validate and Normalize').item.json.review_record.ticket_id }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [660, -220],
      "id": "6d565779-6510-4037-9831-bab0ba42e579",
      "name": "Build Minimal CRM Payload",
      "notes": "Raw inquiry message is intentionally excluded from the default contact payload."
    },
    {
      "parameters": {},
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [920, -220],
      "id": "abdeaa7d-da9c-493b-9eab-35710c8854ae",
      "name": "HubSpot Connection Required",
      "notes": "STOP. Replace only after owner creates least-privilege HubSpot credentials and approves a live connection test."
    },
    {
      "parameters": {},
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [660, 20],
      "id": "55f27ac5-312c-437e-a021-7c3f3d58df67",
      "name": "Rejected by Reviewer"
    }
  ],
  "connections": {
    "WordPress Inquiry Webhook": {
      "main": [[{"node": "Validate and Normalize", "type": "main", "index": 0}]]
    },
    "Validate and Normalize": {
      "main": [[{"node": "Valid?", "type": "main", "index": 0}]]
    },
    "Valid?": {
      "main": [
        [{"node": "Respond Accepted", "type": "main", "index": 0}],
        [{"node": "Respond Rejected", "type": "main", "index": 0}]
      ]
    },
    "Respond Accepted": {
      "main": [[{"node": "Manual Review", "type": "main", "index": 0}]]
    },
    "Manual Review": {
      "main": [[{"node": "Approved?", "type": "main", "index": 0}]]
    },
    "Approved?": {
      "main": [
        [{"node": "Build Minimal CRM Payload", "type": "main", "index": 0}],
        [{"node": "Rejected by Reviewer", "type": "main", "index": 0}]
      ]
    },
    "Build Minimal CRM Payload": {
      "main": [[{"node": "HubSpot Connection Required", "type": "main", "index": 0}]]
    }
  },
  "pinData": {},
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "saveDataSuccessExecution": "none",
    "saveDataErrorExecution": "all",
    "saveManualExecutions": true
  },
  "versionId": "ed1c6786-a966-487f-842e-2d7a3203140c",
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "tags": []
}
