{
 "name": "[노드 한 장] Guardrails · 가상 연락처가 있는 문의 분기",
 "nodes": [
  {
   "id": "m",
   "name": "Run manually",
   "type": "n8n-nodes-base.manualTrigger",
   "typeVersion": 1,
   "position": [
    0,
    0
   ],
   "parameters": {}
  },
  {
   "id": "s",
   "name": "Four fictional inquiries",
   "type": "n8n-nodes-base.code",
   "typeVersion": 2,
   "position": [
    220,
    0
   ],
   "parameters": {
    "jsCode": "// 직접 작성한 안전한 가상 문의. 실제 사람/연락처 아님.\nreturn [{\"caseId\":\"A\",\"text\":\"샘플 문의: 머그컵 재입고 일정이 궁금해요.\",\"publicLabel\":\"재입고 일정 문의\",\"expected\":\"Pass\"},{\"caseId\":\"B\",\"text\":\"샘플 문의: 답장은 sample@example.com 으로 부탁해요.\",\"publicLabel\":\"sample@example.com 포함\",\"expected\":\"Fail\"},{\"caseId\":\"C\",\"text\":\"샘플 문의: 가상 연락처 010-0000-0000 이 들어 있어요.\",\"publicLabel\":\"010-****-**** 포함\",\"expected\":\"Fail\"},{\"caseId\":\"D\",\"text\":\"샘플 문의: 노트의 환불 정책을 알려주세요.\",\"publicLabel\":\"환불 정책 문의\",\"expected\":\"Pass\"}].map(x=>({json:{sample:true,...x}}));"
   }
  },
  {
   "id": "g",
   "name": "Guardrails",
   "type": "@n8n/n8n-nodes-langchain.guardrails",
   "typeVersion": 2,
   "position": [
    470,
    0
   ],
   "parameters": {
    "operation": "classify",
    "text": "={{ $json.text }}",
    "guardrails": {
     "customRegex": {
      "regex": [
       {
        "name": "sample_email_format",
        "value": "/\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}\\b/gi"
       },
       {
        "name": "sample_010_phone_format",
        "value": "/\\b010-\\d{4}-\\d{4}\\b/g"
       }
      ]
     }
    }
   }
  },
  {
   "id": "p",
   "name": "Public Pass results",
   "type": "n8n-nodes-base.code",
   "typeVersion": 2,
   "position": [
    750,
    -140
   ],
   "parameters": {
    "jsCode": "// Guardrails emits guardrailsInput/checks, not the original fields. Match unique actual input text to sample case, then publish only safe label.\nconst src=$('Four fictional inquiries').all().map(x=>x.json);return $input.all().map((it,i)=>{const matches=src.filter(s=>s.text===it.json.guardrailsInput);if(matches.length!==1)throw Error('Unique sample mapping required');const s=matches[0];return {json:{sample:true,caseId:s.caseId,publicLabel:s.publicLabel,branch:'Pass',expected:s.expected,matchesExpected:s.expected==='Pass',checkTriggered:it.json.checks.some(c=>c.triggered)},pairedItem:{item:i}};});"
   }
  },
  {
   "id": "f",
   "name": "Public Fail results",
   "type": "n8n-nodes-base.code",
   "typeVersion": 2,
   "position": [
    750,
    140
   ],
   "parameters": {
    "jsCode": "// Guardrails emits guardrailsInput/checks, not the original fields. Match unique actual input text to sample case, then publish only safe label.\nconst src=$('Four fictional inquiries').all().map(x=>x.json);return $input.all().map((it,i)=>{const matches=src.filter(s=>s.text===it.json.guardrailsInput);if(matches.length!==1)throw Error('Unique sample mapping required');const s=matches[0];return {json:{sample:true,caseId:s.caseId,publicLabel:s.publicLabel,branch:'Fail',expected:s.expected,matchesExpected:s.expected==='Fail',checkTriggered:it.json.checks.some(c=>c.triggered)},pairedItem:{item:i}};});"
   }
  }
 ],
 "connections": {
  "Run manually": {
   "main": [
    [
     {
      "node": "Four fictional inquiries",
      "type": "main",
      "index": 0
     }
    ]
   ]
  },
  "Four fictional inquiries": {
   "main": [
    [
     {
      "node": "Guardrails",
      "type": "main",
      "index": 0
     }
    ]
   ]
  },
  "Guardrails": {
   "main": [
    [
     {
      "node": "Public Pass results",
      "type": "main",
      "index": 0
     }
    ],
    [
     {
      "node": "Public Fail results",
      "type": "main",
      "index": 0
     }
    ]
   ]
  }
 },
 "settings": {
  "executionOrder": "v1",
  "timezone": "Asia/Seoul"
 },
 "meta": {
  "templateCredsSetupCompleted": false,
  "source": "datapopcorn.ai/workflow/nodes"
 }
}