{
  "name": "Document Intake with AI Classification",
  "activeVersionId": null,
  "settings": {
    "executionOrder": "v1",
    "availableInMCP": false
  },
  "connections": {
    "Document Intake Webhook": {
      "main": [
        [
          {
            "node": "Validate Intake Token",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Intake Token": {
      "main": [
        [
          {
            "node": "Intake Authorized?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Intake Authorized?": {
      "main": [
        [
          {
            "node": "Normalize Document Intake",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Respond Intake Unauthorized",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Document Intake": {
      "main": [
        [
          {
            "node": "Claim Document Key",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Claim Document Key": {
      "main": [
        [
          {
            "node": "Document Claim Duplicate?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Document Claim Duplicate?": {
      "main": [
        [
          {
            "node": "Find Claimed Document Row",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Find Existing Document Row",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Find Claimed Document Row": {
      "main": [
        [
          {
            "node": "Respond Document Duplicate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Find Existing Document Row": {
      "main": [
        [
          {
            "node": "Persistent Document Duplicate?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Persistent Document Duplicate?": {
      "main": [
        [
          {
            "node": "Respond Document Duplicate",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Document Intake Dead Letter?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Document Intake Dead Letter?": {
      "main": [
        [
          {
            "node": "Insert Document Dead Letter",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "OCR Usable?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Insert Document Dead Letter": {
      "main": [
        [
          {
            "node": "Mark Document Claim Dead Letter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark Document Claim Dead Letter": {
      "main": [
        [
          {
            "node": "Respond Document Dead Letter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OCR Usable?": {
      "main": [
        [
          {
            "node": "Extract Document Fields",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Insert OCR Needs Review",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Document Fields": {
      "main": [
        [
          {
            "node": "Validate AI Extraction",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate AI Extraction": {
      "main": [
        [
          {
            "node": "AI Validated Auto File?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Validated Auto File?": {
      "main": [
        [
          {
            "node": "Insert Filed Document Record",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Insert AI Needs Review",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Insert Filed Document Record": {
      "main": [
        [
          {
            "node": "Mark Document Claim Filed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark Document Claim Filed": {
      "main": [
        [
          {
            "node": "Respond Document Filed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Insert AI Needs Review": {
      "main": [
        [
          {
            "node": "Send Controlled AI Review Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Controlled AI Review Alert": {
      "main": [
        [
          {
            "node": "Build AI Review Alert Update",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build AI Review Alert Update": {
      "main": [
        [
          {
            "node": "Update AI Review Alert Sent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update AI Review Alert Sent": {
      "main": [
        [
          {
            "node": "Mark Document Claim AI Review",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark Document Claim AI Review": {
      "main": [
        [
          {
            "node": "Respond AI Needs Review",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Insert OCR Needs Review": {
      "main": [
        [
          {
            "node": "Send Controlled OCR Review Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Controlled OCR Review Alert": {
      "main": [
        [
          {
            "node": "Build OCR Review Alert Update",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build OCR Review Alert Update": {
      "main": [
        [
          {
            "node": "Update OCR Review Alert Sent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update OCR Review Alert Sent": {
      "main": [
        [
          {
            "node": "Mark Document Claim OCR Review",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark Document Claim OCR Review": {
      "main": [
        [
          {
            "node": "Respond OCR Needs Review",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "nodes": [
    {
      "id": "5e2ad64c-6e48-45bb-9557-a5c06f386a65",
      "name": "Document Intake Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        0,
        260
      ],
      "parameters": {
        "httpMethod": "POST",
        "path": "document-intake-test",
        "responseMode": "responseNode"
      }
    },
    {
      "id": "b7a08f56-e876-4a13-8023-d0caa5286154",
      "name": "Validate Intake Token",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        260,
        260
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "const root = $input.item.json || {};\nconst headers = root.headers || {};\nconst header = (name) => headers[name] || headers[name.toLowerCase()] || headers[name.toUpperCase()] || '';\nconst rawAuth = String(header('authorization') || '');\nconst bearer = rawAuth.toLowerCase().startsWith('bearer ') ? rawAuth.slice(7).trim() : '';\nconst provided = String(header('x-doc-intake-token') || bearer || '').trim();\nconst expected = String($vars.DOC_INTAKE_WEBHOOK_TOKEN || '').trim();\nreturn { json: {\n  ...root,\n  auth_ok: Boolean(expected && provided && provided === expected),\n  auth_reason: !expected ? 'missing_server_token_var' : !provided ? 'missing_token_header' : provided === expected ? '' : 'bad_token',\n  checked_at: new Date().toISOString(),\n} };"
      }
    },
    {
      "id": "ca7a8169-1bd3-4115-8d76-3b05f12dbd9c",
      "name": "Intake Authorized?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        520,
        260
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "leftValue": "={{ $json.auth_ok }}",
              "operator": {
                "type": "boolean",
                "operation": "true"
              },
              "rightValue": true
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "013d1a1c-c9bc-4d57-bf54-dea04579eb91",
      "name": "Normalize Document Intake",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        780,
        260
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "const crypto = require('crypto');\nconst root = $input.item.json || {};\nconst body = root.body && typeof root.body === 'object' ? root.body : root;\nconst now = new Date().toISOString();\nconst collapse = (value) => String(value ?? '').replace(/\\s+/g, ' ').trim();\nconst truncate = (value, max) => collapse(value).slice(0, max);\nconst htmlEscape = (value) => String(value ?? '').replace(/[&<>\"']/g, ch => ({\n  '&': '&amp;',\n  '<': '&lt;',\n  '>': '&gt;',\n  '\"': '&quot;',\n  \"'\": '&#39;',\n}[ch]));\nconst filename = truncate(body.filename || body.file_name || 'unnamed-document', 180);\nconst mime_type = truncate(body.mime_type || body.mimeType || '', 120);\nconst attachment_id = truncate(body.attachment_id || body.attachmentId || '', 180);\nconst file_sha256_raw = String(body.file_sha256 || body.sha256 || '').toLowerCase();\nconst file_sha256_valid = /^[a-f0-9]{64}$/.test(file_sha256_raw);\nconst file_sha256 = file_sha256_valid ? file_sha256_raw : '';\nconst file_sha256_malformed = Boolean(file_sha256_raw && !file_sha256_valid);\nconst rawText = String(body.ocr_text || body.text || body.extracted_text || '');\nconst ocr_confidence = Number(body.ocr_confidence ?? body.ocrConfidence ?? 0);\nconst scan_text_ratio = Number(body.scan_text_ratio ?? body.scanTextRatio ?? 0);\nconst supportedMime = ['application/pdf', 'image/png', 'image/jpeg', 'image/tiff', 'image/heic', 'text/plain'].includes(mime_type);\nconst errors = [];\nif (!filename || filename === 'unnamed-document') errors.push('filename missing');\nif (!supportedMime) errors.push('unsupported mime_type');\nif (!attachment_id && !file_sha256) errors.push('attachment_id or file_sha256 required');\nif (file_sha256_malformed) errors.push('file_sha256 must be 64 hex characters when provided');\nif (!rawText.trim()) errors.push('ocr_text missing');\nconst textChars = rawText.replace(/\\s/g, '').length;\nconst replacementRatio = textChars ? ((rawText.match(/[\ufffd]/g) || []).length / textChars) : 1;\nconst alphaRatio = textChars ? ((rawText.match(/[\\p{L}\\p{N}]/gu) || []).length / textChars) : 0;\nconst ocr_usable = rawText.trim().length >= 80 && ocr_confidence >= 0.55 && scan_text_ratio >= 0.15 && replacementRatio < 0.08 && alphaRatio >= 0.45;\nconst document_key_seed = file_sha256 || (attachment_id ? [attachment_id, filename, mime_type].join('|') : [filename, mime_type, rawText.slice(0, 2000)].join('|'));\nconst document_key = crypto.createHash('sha256').update('doc-intake\\n' + document_key_seed).digest('hex');\nconst redactions = [\n  { re: /[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}/gi, token: '[email-redacted]' },\n  { re: /\\b[A-Za-z]{2}\\d{2}(?:[ -]?[A-Za-z0-9]){11,30}\\b/g, token: '[iban-redacted]' },\n  { re: /\\b(?:NIP[:\\s-]*)?\\d{3}[ -]?\\d{3}[ -]?\\d{2}[ -]?\\d{2}\\b/gi, token: '[tax-id-redacted]' },\n  { re: /\\b\\d{11}\\b/g, token: '[national-id-redacted]' },\n  { re: /\\b(?:\\+?\\d[\\d\\s().-]{7,}\\d)\\b/g, token: '[phone-redacted]' },\n];\nconst redactForModel = (value) => {\n  let text = String(value ?? '');\n  let changed = false;\n  for (const rule of redactions) {\n    const next = text.replace(rule.re, rule.token);\n    if (next !== text) changed = true;\n    text = next;\n  }\n  return { text, changed };\n};\nconst redactedBody = redactForModel(rawText);\nconst redactedFilename = redactForModel(filename);\nlet modelText = redactedBody.text;\nlet filenameForModel = redactedFilename.text;\nlet pii_redacted_for_model = redactedBody.changed || redactedFilename.changed;\nmodelText = modelText.replace(/\\s+/g, ' ').trim().slice(0, 6000);\nfilenameForModel = filenameForModel.replace(/\\s+/g, ' ').trim().slice(0, 180);\nconst invalid_input = errors.length > 0 || !ocr_usable;\nlet status = 'AI Pending';\nlet review_reason = '';\nlet last_error_class = '';\nlet last_error_message = '';\nif (errors.length > 0) {\n  status = supportedMime ? 'Needs Review' : 'Dead Letter';\n  review_reason = errors.join('; ');\n  last_error_class = supportedMime ? 'business' : 'permanent';\n  last_error_message = review_reason;\n} else if (!ocr_usable) {\n  status = 'Needs Review';\n  review_reason = 'ocr_unusable: low confidence, too little text, or OCR garbage';\n  last_error_class = 'business';\n  last_error_message = review_reason;\n}\nreturn { json: {\n  document_key,\n  attachment_id,\n  filename,\n  filename_html: htmlEscape(filename),\n  mime_type,\n  file_sha256,\n  status,\n  document_type: '',\n  party_name: '',\n  party_name_html: '',\n  document_date: '',\n  amount_total: null,\n  currency: 'Unknown',\n  confidence: 0,\n  validation_errors: errors.join('; '),\n  review_reason,\n  review_reason_html: htmlEscape(review_reason),\n  archive_path: '',\n  ocr_confidence: Number.isFinite(ocr_confidence) ? ocr_confidence : 0,\n  scan_text_ratio: Number.isFinite(scan_text_ratio) ? scan_text_ratio : 0,\n  model_transport_chars: modelText.length,\n  pii_redacted_for_model,\n  review_alert_sent: false,\n  review_alert_id: '',\n  ai_raw_json: '',\n  model_prompt_excerpt: modelText.slice(0, 1200),\n  ai_prompt_text: modelText,\n  filename_for_model: filenameForModel,\n  ocr_usable,\n  invalid_input,\n  raw_event_json: JSON.stringify({ source: body.source || '', attachment_id, filename, mime_type, file_sha256, ocr_confidence, scan_text_ratio, omitted_fields: ['sender_email', 'email_body', 'raw_ocr_text'] }).slice(0, 9000),\n  last_execution_id: $execution.id,\n  last_error_class,\n  last_error_message,\n  created_at: now,\n  updated_at: now,\n} };"
      }
    },
    {
      "id": "0c9f3b4b-4269-43ba-bb4b-73151148b5eb",
      "name": "Claim Document Key",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1040,
        260
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "const pruneStore = (obj, max = 5000) => {\n  const keys = Object.keys(obj);\n  for (let i = 0; i < keys.length - max; i++) delete obj[keys[i]];\n};\nconst n = $input.item.json;\nconst store = $getWorkflowStaticData('global');\nstore.document_claims = store.document_claims || {};\npruneStore(store.document_claims);\nconst claims = store.document_claims;\nconst now = Date.now();\nconst claim = claims[n.document_key];\nconst claimAge = claim?.claimed_at ? now - Date.parse(claim.claimed_at) : 0;\nconst activeClaim = claim && (claim.status !== 'in_progress' || claimAge < 15 * 60 * 1000);\nif (activeClaim) {\n  return { json: { ...n, duplicate_claim: true, duplicate_status: claim.status || 'seen', existing_record_id: claim.record_id || '' } };\n}\nclaims[n.document_key] = { status: 'in_progress', claimed_at: new Date(now).toISOString(), first_execution_id: n.last_execution_id };\nreturn { json: { ...n, duplicate_claim: false, duplicate_status: '', existing_record_id: '' } };"
      }
    },
    {
      "id": "27f34597-bb07-4403-a558-fa8b272c505a",
      "name": "Document Claim Duplicate?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        1300,
        260
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "leftValue": "={{ $json.duplicate_claim }}",
              "operator": {
                "type": "boolean",
                "operation": "true"
              },
              "rightValue": true
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "0057a990-14db-4588-8a3e-a125500e27be",
      "name": "Find Claimed Document Row",
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [
        1560,
        80
      ],
      "parameters": {
        "resource": "row",
        "operation": "get",
        "dataTableId": {
          "__rl": true,
          "mode": "id",
          "value": "REPLACE_WITH_TABLE_ID",
          "cachedResultName": "Intake_Documents"
        },
        "matchType": "allConditions",
        "filters": {
          "conditions": [
            {
              "keyName": "document_key",
              "condition": "eq",
              "keyValue": "={{ $(\"Normalize Document Intake\").item.json.document_key }}"
            }
          ]
        },
        "returnAll": false,
        "limit": 1
      },
      "alwaysOutputData": true
    },
    {
      "id": "34f095af-72c2-42bc-8016-a5e3be8fa866",
      "name": "Respond Document Duplicate",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.5,
      "position": [
        2080,
        80
      ],
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ { ok: true, status: \"duplicate\", document_key: $(\"Normalize Document Intake\").item.json.document_key, existing_record_id: $json.id || $(\"Claim Document Key\").item.json.existing_record_id || \"\", existing_status: $json.status || $(\"Claim Document Key\").item.json.duplicate_status || \"seen\" } }}",
        "options": {
          "responseCode": 200
        }
      }
    },
    {
      "id": "4e134505-da38-41fd-95d5-8e9878726724",
      "name": "Find Existing Document Row",
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [
        1560,
        320
      ],
      "parameters": {
        "resource": "row",
        "operation": "get",
        "dataTableId": {
          "__rl": true,
          "mode": "id",
          "value": "REPLACE_WITH_TABLE_ID",
          "cachedResultName": "Intake_Documents"
        },
        "matchType": "allConditions",
        "filters": {
          "conditions": [
            {
              "keyName": "document_key",
              "condition": "eq",
              "keyValue": "={{ $(\"Normalize Document Intake\").item.json.document_key }}"
            }
          ]
        },
        "returnAll": false,
        "limit": 1
      },
      "alwaysOutputData": true
    },
    {
      "id": "5b9e4d5a-9f78-4632-953b-21ce85876aa9",
      "name": "Persistent Document Duplicate?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        1820,
        320
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose"
          },
          "conditions": [
            {
              "leftValue": "={{ !!$json.id }}",
              "operator": {
                "type": "boolean",
                "operation": "true"
              },
              "rightValue": true
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "74a1ec43-4ea3-4bb4-880a-301215565f63",
      "name": "Document Intake Dead Letter?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        2080,
        320
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "leftValue": "={{ $(\"Normalize Document Intake\").item.json.status }}",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "rightValue": "Dead Letter"
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "1f7d29b1-1cda-482c-8a5e-77db246dee66",
      "name": "Insert Document Dead Letter",
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [
        2340,
        160
      ],
      "parameters": {
        "resource": "row",
        "operation": "insert",
        "dataTableId": {
          "__rl": true,
          "mode": "id",
          "value": "REPLACE_WITH_TABLE_ID",
          "cachedResultName": "Intake_Documents"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "document_key": "={{ $(\"Normalize Document Intake\").item.json.document_key }}",
            "attachment_id": "={{ $(\"Normalize Document Intake\").item.json.attachment_id }}",
            "filename": "={{ $(\"Normalize Document Intake\").item.json.filename }}",
            "mime_type": "={{ $(\"Normalize Document Intake\").item.json.mime_type }}",
            "file_sha256": "={{ $(\"Normalize Document Intake\").item.json.file_sha256 }}",
            "status": "={{ $(\"Normalize Document Intake\").item.json.status }}",
            "document_type": "={{ $(\"Normalize Document Intake\").item.json.document_type }}",
            "party_name": "={{ $(\"Normalize Document Intake\").item.json.party_name }}",
            "document_date": "={{ $(\"Normalize Document Intake\").item.json.document_date }}",
            "amount_total": "={{ $(\"Normalize Document Intake\").item.json.amount_total }}",
            "currency": "={{ $(\"Normalize Document Intake\").item.json.currency }}",
            "confidence": "={{ $(\"Normalize Document Intake\").item.json.confidence }}",
            "validation_errors": "={{ $(\"Normalize Document Intake\").item.json.validation_errors }}",
            "review_reason": "={{ $(\"Normalize Document Intake\").item.json.review_reason }}",
            "archive_path": "={{ $(\"Normalize Document Intake\").item.json.archive_path }}",
            "ocr_confidence": "={{ $(\"Normalize Document Intake\").item.json.ocr_confidence }}",
            "model_transport_chars": "={{ $(\"Normalize Document Intake\").item.json.model_transport_chars }}",
            "pii_redacted_for_model": "={{ $(\"Normalize Document Intake\").item.json.pii_redacted_for_model }}",
            "review_alert_sent": "={{ $(\"Normalize Document Intake\").item.json.review_alert_sent }}",
            "review_alert_id": "={{ $(\"Normalize Document Intake\").item.json.review_alert_id }}",
            "ai_raw_json": "={{ $(\"Normalize Document Intake\").item.json.ai_raw_json }}",
            "model_prompt_excerpt": "={{ $(\"Normalize Document Intake\").item.json.model_prompt_excerpt }}",
            "raw_event_json": "={{ $(\"Normalize Document Intake\").item.json.raw_event_json }}",
            "last_execution_id": "={{ $(\"Normalize Document Intake\").item.json.last_execution_id }}",
            "last_error_class": "={{ $(\"Normalize Document Intake\").item.json.last_error_class }}",
            "last_error_message": "={{ $(\"Normalize Document Intake\").item.json.last_error_message }}",
            "created_at": "={{ $(\"Normalize Document Intake\").item.json.created_at }}",
            "updated_at": "={{ $(\"Normalize Document Intake\").item.json.updated_at }}"
          },
          "schema": [
            {
              "id": "document_key",
              "displayName": "document_key",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "attachment_id",
              "displayName": "attachment_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "filename",
              "displayName": "filename",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "mime_type",
              "displayName": "mime_type",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "file_sha256",
              "displayName": "file_sha256",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "displayName": "status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "document_type",
              "displayName": "document_type",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "party_name",
              "displayName": "party_name",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "document_date",
              "displayName": "document_date",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "amount_total",
              "displayName": "amount_total",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": false
            },
            {
              "id": "currency",
              "displayName": "currency",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "confidence",
              "displayName": "confidence",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": false
            },
            {
              "id": "validation_errors",
              "displayName": "validation_errors",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "review_reason",
              "displayName": "review_reason",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "archive_path",
              "displayName": "archive_path",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "ocr_confidence",
              "displayName": "ocr_confidence",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": false
            },
            {
              "id": "model_transport_chars",
              "displayName": "model_transport_chars",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": false
            },
            {
              "id": "pii_redacted_for_model",
              "displayName": "pii_redacted_for_model",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "boolean",
              "canBeUsedToMatch": false
            },
            {
              "id": "review_alert_sent",
              "displayName": "review_alert_sent",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "boolean",
              "canBeUsedToMatch": false
            },
            {
              "id": "review_alert_id",
              "displayName": "review_alert_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "ai_raw_json",
              "displayName": "ai_raw_json",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "model_prompt_excerpt",
              "displayName": "model_prompt_excerpt",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "raw_event_json",
              "displayName": "raw_event_json",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "last_execution_id",
              "displayName": "last_execution_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "last_error_class",
              "displayName": "last_error_class",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "last_error_message",
              "displayName": "last_error_message",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "created_at",
              "displayName": "created_at",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "dateTime",
              "canBeUsedToMatch": false
            },
            {
              "id": "updated_at",
              "displayName": "updated_at",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "dateTime",
              "canBeUsedToMatch": false
            }
          ]
        }
      }
    },
    {
      "id": "2bd12599-932f-4f94-9739-e08777003d59",
      "name": "Mark Document Claim Dead Letter",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2600,
        160
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "const pruneStore = (obj, max = 5000) => {\n  const keys = Object.keys(obj);\n  for (let i = 0; i < keys.length - max; i++) delete obj[keys[i]];\n};\nconst n = $('Normalize Document Intake').item.json;\nconst record = $input.item.json || {};\nconst store = $getWorkflowStaticData('global');\nstore.document_claims = store.document_claims || {};\npruneStore(store.document_claims);\nstore.document_claims[n.document_key] = { ...(store.document_claims[n.document_key] || {}), status: 'Dead Letter', record_id: record.id || '', completed_at: new Date().toISOString() };\nreturn { json: record };"
      }
    },
    {
      "id": "f05da482-2fc1-4620-8e08-e224dee9c708",
      "name": "Respond Document Dead Letter",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.5,
      "position": [
        2860,
        160
      ],
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ { ok: true, status: \"dead_letter\", document_key: $(\"Normalize Document Intake\").item.json.document_key, record_id: $json.id || \"\", reason: $(\"Normalize Document Intake\").item.json.review_reason || $(\"Normalize Document Intake\").item.json.validation_errors } }}",
        "options": {
          "responseCode": 200
        }
      }
    },
    {
      "id": "1eaa6cd5-9324-4449-ba02-60ed3bbceccc",
      "name": "OCR Usable?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        2340,
        420
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "leftValue": "={{ $(\"Normalize Document Intake\").item.json.status }}",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "rightValue": "AI Pending"
            },
            {
              "leftValue": "={{ $(\"Normalize Document Intake\").item.json.ocr_usable }}",
              "operator": {
                "type": "boolean",
                "operation": "true"
              },
              "rightValue": true
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "b8c999fe-d452-4a05-86e4-73c36d335c05",
      "name": "Extract Document Fields",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "typeVersion": 2.3,
      "position": [
        2600,
        340
      ],
      "parameters": {
        "resource": "text",
        "operation": "response",
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "gpt-4o-mini"
        },
        "responses": {
          "values": [
            {
              "type": "text",
              "role": "system",
              "content": "You extract document metadata for a law/accounting office. Return only JSON text, not markdown. Closed document_type enum: Invoice, Contract, Receipt, Other. Closed currency enum: PLN, EUR, USD, GBP, Unknown. Extract only: document_type, party_name, document_date as YYYY-MM-DD or null, amount_total as number or null, currency, confidence 0..1, field_confidence object with document_type, party_name, document_date, amount_total 0..1, needs_human_review boolean, review_reason string, evidence object with short text snippets. If the text is OCR garbage or a type does not fit the enum, use Other and needs_human_review=true. Never invent missing fields."
            },
            {
              "type": "text",
              "role": "user",
              "content": "=Filename: {{ $(\"Normalize Document Intake\").item.json.filename_for_model }}\nMIME: {{ $(\"Normalize Document Intake\").item.json.mime_type }}\nOCR confidence: {{ $(\"Normalize Document Intake\").item.json.ocr_confidence }}\nRedacted OCR excerpt for extraction only:\n\"\"\"{{ $(\"Normalize Document Intake\").item.json.ai_prompt_text }}\"\"\""
            }
          ]
        },
        "simplify": true,
        "options": {
          "temperature": 0,
          "store": false
        }
      }
    },
    {
      "id": "a075a974-ea0d-4293-abac-0ad1336678c6",
      "name": "Validate AI Extraction",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2860,
        340
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "const base = $('Normalize Document Intake').item.json;\nconst raw = $input.item.json;\nconst extractText = (value) => {\n  if (typeof value === 'string') return value;\n  if (Array.isArray(value)) return value.map(extractText).filter(Boolean).join('\\n');\n  if (value && typeof value === 'object') {\n    if (typeof value.text === 'string') return value.text;\n    if (typeof value.output_text === 'string') return value.output_text;\n    if (value.content) return extractText(value.content);\n    if (value.output) return extractText(value.output);\n  }\n  return '';\n};\nlet ai = raw.output ?? raw.text ?? raw.content ?? raw;\nlet parsedFrom = 'object';\nif (typeof ai === 'string') {\n  parsedFrom = 'string';\n  const cleaned = ai.replace(/^\\s*```(?:json)?\\s*/i, '').replace(/\\s*```\\s*$/i, '').trim();\n  try { ai = JSON.parse(cleaned); } catch { ai = null; }\n} else {\n  const extracted = extractText(ai);\n  if (extracted) {\n    const cleaned = extracted.replace(/^\\s*```(?:json)?\\s*/i, '').replace(/\\s*```\\s*$/i, '').trim();\n    try { ai = JSON.parse(cleaned); parsedFrom = 'nested_text'; } catch { /* keep object */ }\n  }\n}\nconst allowedTypes = ['Invoice', 'Contract', 'Receipt', 'Other'];\nconst allowedCurrency = ['PLN', 'EUR', 'USD', 'GBP', 'Unknown'];\nconst reasons = [];\nconst warnings = [];\nconst htmlEscape = (value) => String(value ?? '').replace(/[&<>\"']/g, ch => ({\n  '&': '&amp;',\n  '<': '&lt;',\n  '>': '&gt;',\n  '\"': '&quot;',\n  \"'\": '&#39;',\n}[ch]));\nif (!ai || typeof ai !== 'object' || Array.isArray(ai)) reasons.push('AI output unparseable or not an object');\nai = ai && typeof ai === 'object' && !Array.isArray(ai) ? ai : {};\nconst enumPick = (value, allowed, fallback, label) => {\n  const v = typeof value === 'string' ? value.trim() : '';\n  if (allowed.includes(v)) return v;\n  reasons.push(label + ' outside closed enum');\n  return fallback;\n};\nconst clamp01 = (value, label) => {\n  let n = Number(value);\n  if (!Number.isFinite(n)) {\n    reasons.push(label + ' missing or nonnumeric');\n    n = 0;\n  }\n  return Math.max(0, Math.min(1, n));\n};\nconst document_type = enumPick(ai.document_type, allowedTypes, 'Other', 'document_type');\nconst currency = enumPick(ai.currency || 'Unknown', allowedCurrency, 'Unknown', 'currency');\nconst confidence = clamp01(ai.confidence, 'confidence');\nconst fc = ai.field_confidence && typeof ai.field_confidence === 'object' ? ai.field_confidence : {};\nconst typeConfidence = clamp01(fc.document_type ?? confidence, 'field_confidence.document_type');\nconst partyConfidence = clamp01(fc.party_name ?? confidence, 'field_confidence.party_name');\nconst dateConfidence = clamp01(fc.document_date ?? confidence, 'field_confidence.document_date');\nconst amountConfidence = clamp01(fc.amount_total ?? confidence, 'field_confidence.amount_total');\nconst party_name = typeof ai.party_name === 'string' ? ai.party_name.replace(/\\s+/g, ' ').trim().slice(0, 140) : '';\nif (party_name.length < 2) reasons.push('party_name missing or too short');\nlet document_date = typeof ai.document_date === 'string' ? ai.document_date.trim() : '';\nif (document_date && !/^\\d{4}-\\d{2}-\\d{2}$/.test(document_date)) {\n  reasons.push('document_date not YYYY-MM-DD');\n  document_date = '';\n}\nif (document_date) {\n  const d = new Date(document_date + 'T00:00:00Z');\n  if (!Number.isNaN(d.getTime()) && d.toISOString().slice(0, 10) !== document_date) {\n    reasons.push('document_date not a real calendar date');\n    document_date = '';\n  }\n  const min = new Date('1990-01-01T00:00:00Z');\n  const max = new Date(Date.now() + 366 * 24 * 60 * 60 * 1000);\n  if (Number.isNaN(d.getTime()) || d < min || d > max) {\n    reasons.push('document_date outside sane range');\n    document_date = '';\n  }\n}\nif (!document_date) reasons.push('document_date missing');\nlet amount_total = ai.amount_total === null || ai.amount_total === undefined || ai.amount_total === '' ? null : Number(ai.amount_total);\nif (amount_total !== null && (!Number.isFinite(amount_total) || amount_total < 0 || amount_total > 10000000)) {\n  reasons.push('amount_total outside sane range');\n  amount_total = null;\n}\nif ((document_type === 'Invoice' || document_type === 'Receipt') && amount_total === null) reasons.push('amount_total required for Invoice/Receipt');\nif (document_type === 'Contract' && amount_total === null) warnings.push('amount_total missing for Contract; allowed as incomplete non-filing field');\nif (document_type === 'Other') reasons.push('document_type Other requires human review');\nif (confidence < 0.45) reasons.push('very low confidence');\nif ((document_type === 'Invoice' || document_type === 'Receipt') && currency === 'Unknown') reasons.push('currency required for Invoice/Receipt');\nif (base.status && base.status !== 'AI Pending') reasons.push('intake status not eligible for auto-file: ' + base.status);\nif (base.validation_errors) reasons.push('intake validation errors: ' + String(base.validation_errors).slice(0, 300));\nconst reviewReason = [\n  typeof ai.review_reason === 'string' ? ai.review_reason.trim().slice(0, 500) : '',\n  ...reasons,\n  ...warnings,\n].filter(Boolean).join('; ');\nconst criticalReasons = reasons.length > 0;\nconst amountConfidenceOk = document_type === 'Contract' && amount_total === null ? true : amountConfidence >= 0.75;\nconst auto_file = !criticalReasons && confidence >= 0.82 && typeConfidence >= 0.8 && partyConfidence >= 0.75 && dateConfidence >= 0.75 && amountConfidenceOk && (amount_total !== null || document_type === 'Contract') && ai.needs_human_review !== true;\nconst safeParty = (party_name || 'unknown-party').toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '').slice(0, 60) || 'unknown-party';\nconst safeFilename = (base.filename || 'document').toLowerCase().replace(/[^a-z0-9._-]+/g, '-').replace(/\\.{2,}/g, '.').replace(/^[.-]+|[.-]+$/g, '').slice(0, 100) || 'document';\nconst year = document_date ? document_date.slice(0, 4) : 'unknown-year';\nconst shortKey = base.document_key.slice(0, 12);\nconst archiveName = (document_date || 'unknown-date') + '__' + safeParty + '__' + shortKey + '__' + safeFilename;\nconst reviewName = shortKey + '__' + safeFilename;\nconst archive_path = auto_file\n  ? ['archive', document_type, year, archiveName].join('/')\n  : ['review', document_type || 'Other', reviewName].join('/');\nconst finalReviewReason = auto_file ? warnings.join('; ') : reviewReason;\nreturn { json: {\n  ...base,\n  status: auto_file ? 'Filed' : 'Needs Review',\n  document_type,\n  party_name,\n  filename_html: htmlEscape(base.filename),\n  party_name_html: htmlEscape(party_name),\n  document_date,\n  amount_total,\n  currency,\n  confidence,\n  validation_errors: reasons.join('; '),\n  review_reason: finalReviewReason,\n  review_reason_html: htmlEscape(finalReviewReason),\n  archive_path,\n  review_alert_sent: false,\n  review_alert_id: '',\n  ai_raw_json: JSON.stringify({ parsedFrom, ai }).slice(0, 9000),\n  last_error_class: auto_file ? '' : 'business',\n  last_error_message: auto_file ? '' : reviewReason,\n  auto_file,\n  updated_at: new Date().toISOString(),\n} };",
        "parameters": null
      }
    },
    {
      "id": "6122cb1b-f202-4f7e-bdfb-77fee234aaf3",
      "name": "AI Validated Auto File?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        3120,
        340
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "leftValue": "={{ $(\"Validate AI Extraction\").item.json.auto_file }}",
              "operator": {
                "type": "boolean",
                "operation": "true"
              },
              "rightValue": true
            }
          ],
          "combinator": "and"
        }
      }
    },
    {
      "id": "33a14688-b046-46ea-b602-df6dc952f4b7",
      "name": "Insert Filed Document Record",
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [
        3380,
        220
      ],
      "parameters": {
        "resource": "row",
        "operation": "insert",
        "dataTableId": {
          "__rl": true,
          "mode": "id",
          "value": "REPLACE_WITH_TABLE_ID",
          "cachedResultName": "Intake_Documents"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "document_key": "={{ $(\"Validate AI Extraction\").item.json.document_key }}",
            "attachment_id": "={{ $(\"Validate AI Extraction\").item.json.attachment_id }}",
            "filename": "={{ $(\"Validate AI Extraction\").item.json.filename }}",
            "mime_type": "={{ $(\"Validate AI Extraction\").item.json.mime_type }}",
            "file_sha256": "={{ $(\"Validate AI Extraction\").item.json.file_sha256 }}",
            "status": "={{ $(\"Validate AI Extraction\").item.json.status }}",
            "document_type": "={{ $(\"Validate AI Extraction\").item.json.document_type }}",
            "party_name": "={{ $(\"Validate AI Extraction\").item.json.party_name }}",
            "document_date": "={{ $(\"Validate AI Extraction\").item.json.document_date }}",
            "amount_total": "={{ $(\"Validate AI Extraction\").item.json.amount_total }}",
            "currency": "={{ $(\"Validate AI Extraction\").item.json.currency }}",
            "confidence": "={{ $(\"Validate AI Extraction\").item.json.confidence }}",
            "validation_errors": "={{ $(\"Validate AI Extraction\").item.json.validation_errors }}",
            "review_reason": "={{ $(\"Validate AI Extraction\").item.json.review_reason }}",
            "archive_path": "={{ $(\"Validate AI Extraction\").item.json.archive_path }}",
            "ocr_confidence": "={{ $(\"Validate AI Extraction\").item.json.ocr_confidence }}",
            "model_transport_chars": "={{ $(\"Validate AI Extraction\").item.json.model_transport_chars }}",
            "pii_redacted_for_model": "={{ $(\"Validate AI Extraction\").item.json.pii_redacted_for_model }}",
            "review_alert_sent": "={{ $(\"Validate AI Extraction\").item.json.review_alert_sent }}",
            "review_alert_id": "={{ $(\"Validate AI Extraction\").item.json.review_alert_id }}",
            "ai_raw_json": "={{ $(\"Validate AI Extraction\").item.json.ai_raw_json }}",
            "model_prompt_excerpt": "={{ $(\"Validate AI Extraction\").item.json.model_prompt_excerpt }}",
            "raw_event_json": "={{ $(\"Validate AI Extraction\").item.json.raw_event_json }}",
            "last_execution_id": "={{ $(\"Validate AI Extraction\").item.json.last_execution_id }}",
            "last_error_class": "={{ $(\"Validate AI Extraction\").item.json.last_error_class }}",
            "last_error_message": "={{ $(\"Validate AI Extraction\").item.json.last_error_message }}",
            "created_at": "={{ $(\"Validate AI Extraction\").item.json.created_at }}",
            "updated_at": "={{ $(\"Validate AI Extraction\").item.json.updated_at }}"
          },
          "schema": [
            {
              "id": "document_key",
              "displayName": "document_key",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "attachment_id",
              "displayName": "attachment_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "filename",
              "displayName": "filename",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "mime_type",
              "displayName": "mime_type",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "file_sha256",
              "displayName": "file_sha256",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "displayName": "status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "document_type",
              "displayName": "document_type",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "party_name",
              "displayName": "party_name",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "document_date",
              "displayName": "document_date",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "amount_total",
              "displayName": "amount_total",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": false
            },
            {
              "id": "currency",
              "displayName": "currency",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "confidence",
              "displayName": "confidence",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": false
            },
            {
              "id": "validation_errors",
              "displayName": "validation_errors",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "review_reason",
              "displayName": "review_reason",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "archive_path",
              "displayName": "archive_path",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "ocr_confidence",
              "displayName": "ocr_confidence",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": false
            },
            {
              "id": "model_transport_chars",
              "displayName": "model_transport_chars",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": false
            },
            {
              "id": "pii_redacted_for_model",
              "displayName": "pii_redacted_for_model",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "boolean",
              "canBeUsedToMatch": false
            },
            {
              "id": "review_alert_sent",
              "displayName": "review_alert_sent",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "boolean",
              "canBeUsedToMatch": false
            },
            {
              "id": "review_alert_id",
              "displayName": "review_alert_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "ai_raw_json",
              "displayName": "ai_raw_json",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "model_prompt_excerpt",
              "displayName": "model_prompt_excerpt",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "raw_event_json",
              "displayName": "raw_event_json",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "last_execution_id",
              "displayName": "last_execution_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "last_error_class",
              "displayName": "last_error_class",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "last_error_message",
              "displayName": "last_error_message",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "created_at",
              "displayName": "created_at",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "dateTime",
              "canBeUsedToMatch": false
            },
            {
              "id": "updated_at",
              "displayName": "updated_at",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "dateTime",
              "canBeUsedToMatch": false
            }
          ]
        }
      }
    },
    {
      "id": "2f48edf5-00c4-4baf-abda-2e02afedc43b",
      "name": "Mark Document Claim Filed",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3640,
        220
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "const pruneStore = (obj, max = 5000) => {\n  const keys = Object.keys(obj);\n  for (let i = 0; i < keys.length - max; i++) delete obj[keys[i]];\n};\nconst n = $('Validate AI Extraction').item.json;\nconst record = $input.item.json || {};\nconst store = $getWorkflowStaticData('global');\nstore.document_claims = store.document_claims || {};\npruneStore(store.document_claims);\nstore.document_claims[n.document_key] = { ...(store.document_claims[n.document_key] || {}), status: 'Filed', record_id: record.id || '', completed_at: new Date().toISOString(), archive_path: n.archive_path };\nreturn { json: record };"
      }
    },
    {
      "id": "0b8fe78b-62f5-4879-bd09-2ba770821507",
      "name": "Respond Document Filed",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.5,
      "position": [
        3900,
        220
      ],
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ { ok: true, status: \"filed\", document_key: $(\"Validate AI Extraction\").item.json.document_key, record_id: $json.id || \"\", document_type: $(\"Validate AI Extraction\").item.json.document_type, archive_path: $(\"Validate AI Extraction\").item.json.archive_path, confidence: $(\"Validate AI Extraction\").item.json.confidence } }}",
        "options": {
          "responseCode": 200
        }
      }
    },
    {
      "id": "2cd52bf5-3bc9-4757-ad64-c2fc8c7c5b64",
      "name": "Insert AI Needs Review",
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [
        3380,
        520
      ],
      "parameters": {
        "resource": "row",
        "operation": "insert",
        "dataTableId": {
          "__rl": true,
          "mode": "id",
          "value": "REPLACE_WITH_TABLE_ID",
          "cachedResultName": "Intake_Documents"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "document_key": "={{ $(\"Validate AI Extraction\").item.json.document_key }}",
            "attachment_id": "={{ $(\"Validate AI Extraction\").item.json.attachment_id }}",
            "filename": "={{ $(\"Validate AI Extraction\").item.json.filename }}",
            "mime_type": "={{ $(\"Validate AI Extraction\").item.json.mime_type }}",
            "file_sha256": "={{ $(\"Validate AI Extraction\").item.json.file_sha256 }}",
            "status": "={{ $(\"Validate AI Extraction\").item.json.status }}",
            "document_type": "={{ $(\"Validate AI Extraction\").item.json.document_type }}",
            "party_name": "={{ $(\"Validate AI Extraction\").item.json.party_name }}",
            "document_date": "={{ $(\"Validate AI Extraction\").item.json.document_date }}",
            "amount_total": "={{ $(\"Validate AI Extraction\").item.json.amount_total }}",
            "currency": "={{ $(\"Validate AI Extraction\").item.json.currency }}",
            "confidence": "={{ $(\"Validate AI Extraction\").item.json.confidence }}",
            "validation_errors": "={{ $(\"Validate AI Extraction\").item.json.validation_errors }}",
            "review_reason": "={{ $(\"Validate AI Extraction\").item.json.review_reason }}",
            "archive_path": "={{ $(\"Validate AI Extraction\").item.json.archive_path }}",
            "ocr_confidence": "={{ $(\"Validate AI Extraction\").item.json.ocr_confidence }}",
            "model_transport_chars": "={{ $(\"Validate AI Extraction\").item.json.model_transport_chars }}",
            "pii_redacted_for_model": "={{ $(\"Validate AI Extraction\").item.json.pii_redacted_for_model }}",
            "review_alert_sent": "={{ $(\"Validate AI Extraction\").item.json.review_alert_sent }}",
            "review_alert_id": "={{ $(\"Validate AI Extraction\").item.json.review_alert_id }}",
            "ai_raw_json": "={{ $(\"Validate AI Extraction\").item.json.ai_raw_json }}",
            "model_prompt_excerpt": "={{ $(\"Validate AI Extraction\").item.json.model_prompt_excerpt }}",
            "raw_event_json": "={{ $(\"Validate AI Extraction\").item.json.raw_event_json }}",
            "last_execution_id": "={{ $(\"Validate AI Extraction\").item.json.last_execution_id }}",
            "last_error_class": "={{ $(\"Validate AI Extraction\").item.json.last_error_class }}",
            "last_error_message": "={{ $(\"Validate AI Extraction\").item.json.last_error_message }}",
            "created_at": "={{ $(\"Validate AI Extraction\").item.json.created_at }}",
            "updated_at": "={{ $(\"Validate AI Extraction\").item.json.updated_at }}"
          },
          "schema": [
            {
              "id": "document_key",
              "displayName": "document_key",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "attachment_id",
              "displayName": "attachment_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "filename",
              "displayName": "filename",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "mime_type",
              "displayName": "mime_type",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "file_sha256",
              "displayName": "file_sha256",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "displayName": "status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "document_type",
              "displayName": "document_type",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "party_name",
              "displayName": "party_name",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "document_date",
              "displayName": "document_date",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "amount_total",
              "displayName": "amount_total",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": false
            },
            {
              "id": "currency",
              "displayName": "currency",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "confidence",
              "displayName": "confidence",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": false
            },
            {
              "id": "validation_errors",
              "displayName": "validation_errors",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "review_reason",
              "displayName": "review_reason",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "archive_path",
              "displayName": "archive_path",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "ocr_confidence",
              "displayName": "ocr_confidence",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": false
            },
            {
              "id": "model_transport_chars",
              "displayName": "model_transport_chars",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": false
            },
            {
              "id": "pii_redacted_for_model",
              "displayName": "pii_redacted_for_model",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "boolean",
              "canBeUsedToMatch": false
            },
            {
              "id": "review_alert_sent",
              "displayName": "review_alert_sent",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "boolean",
              "canBeUsedToMatch": false
            },
            {
              "id": "review_alert_id",
              "displayName": "review_alert_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "ai_raw_json",
              "displayName": "ai_raw_json",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "model_prompt_excerpt",
              "displayName": "model_prompt_excerpt",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "raw_event_json",
              "displayName": "raw_event_json",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "last_execution_id",
              "displayName": "last_execution_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "last_error_class",
              "displayName": "last_error_class",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "last_error_message",
              "displayName": "last_error_message",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "created_at",
              "displayName": "created_at",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "dateTime",
              "canBeUsedToMatch": false
            },
            {
              "id": "updated_at",
              "displayName": "updated_at",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "dateTime",
              "canBeUsedToMatch": false
            }
          ]
        }
      }
    },
    {
      "id": "6b36480d-4f55-4c86-8814-f29d771fc195",
      "name": "Send Controlled AI Review Alert",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.2,
      "position": [
        3640,
        520
      ],
      "parameters": {
        "resource": "message",
        "operation": "send",
        "sendTo": "ops@example.com",
        "subject": "=[TEST] AI review: {{ $(\"Validate AI Extraction\").item.json.filename }}",
        "emailType": "html",
        "message": "=<p><strong>Document held for human review</strong></p><p>Filename: {{ $(\"Validate AI Extraction\").item.json.filename_html }}</p><p>Type: {{ $(\"Validate AI Extraction\").item.json.document_type }}</p><p>Party: {{ $(\"Validate AI Extraction\").item.json.party_name_html }}</p><p>Confidence: {{ $(\"Validate AI Extraction\").item.json.confidence }}</p><p>Reason: {{ $(\"Validate AI Extraction\").item.json.review_reason_html }}</p><p>Safe review path: {{ $(\"Validate AI Extraction\").item.json.archive_path }}</p><p>Record: {{ $(\"Insert AI Needs Review\").item.json.id }}</p>",
        "options": {
          "appendAttribution": false,
          "senderName": "Acme Automation"
        }
      }
    },
    {
      "id": "d17b9340-4836-4fc8-88ab-8d312188d0c3",
      "name": "Build AI Review Alert Update",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3900,
        520
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "const row = $('Insert AI Needs Review').item.json;\nconst email = $input.item.json || {};\nreturn { json: { id: row.id, status: 'Needs Review', review_alert_sent: true, review_alert_id: email.id || '', updated_at: new Date().toISOString(), last_execution_id: $('Validate AI Extraction').item.json.last_execution_id } };"
      }
    },
    {
      "id": "8fff1539-37b4-4cec-b35c-289b5e6f11cb",
      "name": "Update AI Review Alert Sent",
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [
        4160,
        520
      ],
      "parameters": {
        "resource": "row",
        "operation": "update",
        "dataTableId": {
          "__rl": true,
          "mode": "id",
          "value": "REPLACE_WITH_TABLE_ID",
          "cachedResultName": "Intake_Documents"
        },
        "matchType": "allConditions",
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "condition": "eq",
              "keyValue": "={{ $json.id }}"
            }
          ]
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "status": "={{ $json.status }}",
            "review_alert_sent": "={{ $json.review_alert_sent }}",
            "review_alert_id": "={{ $json.review_alert_id }}",
            "updated_at": "={{ $json.updated_at }}",
            "last_execution_id": "={{ $json.last_execution_id }}"
          },
          "schema": [
            {
              "id": "status",
              "displayName": "status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "review_alert_sent",
              "displayName": "review_alert_sent",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "boolean",
              "canBeUsedToMatch": false
            },
            {
              "id": "review_alert_id",
              "displayName": "review_alert_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "updated_at",
              "displayName": "updated_at",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "dateTime",
              "canBeUsedToMatch": false
            },
            {
              "id": "last_execution_id",
              "displayName": "last_execution_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            }
          ]
        }
      }
    },
    {
      "id": "d046c026-211f-469b-a9de-f27f2cb53c91",
      "name": "Mark Document Claim AI Review",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        4420,
        520
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "const pruneStore = (obj, max = 5000) => {\n  const keys = Object.keys(obj);\n  for (let i = 0; i < keys.length - max; i++) delete obj[keys[i]];\n};\nconst n = $('Validate AI Extraction').item.json;\nconst record = $input.item.json || {};\nconst store = $getWorkflowStaticData('global');\nstore.document_claims = store.document_claims || {};\npruneStore(store.document_claims);\nstore.document_claims[n.document_key] = { ...(store.document_claims[n.document_key] || {}), status: 'Needs Review', record_id: record.id || '', completed_at: new Date().toISOString(), archive_path: n.archive_path };\nreturn { json: record };"
      }
    },
    {
      "id": "553d8580-bb34-4bf1-882a-00904d29be5c",
      "name": "Respond AI Needs Review",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.5,
      "position": [
        4680,
        520
      ],
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ { ok: true, status: \"needs_review\", queue: \"human_review\", document_key: $(\"Validate AI Extraction\").item.json.document_key, record_id: $json.id || \"\", document_type: $(\"Validate AI Extraction\").item.json.document_type, reason: $(\"Validate AI Extraction\").item.json.review_reason, archive_path: $(\"Validate AI Extraction\").item.json.archive_path } }}",
        "options": {
          "responseCode": 200
        }
      }
    },
    {
      "id": "7cc913b2-b0c2-4c19-a454-2a6f6f076503",
      "name": "Insert OCR Needs Review",
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [
        2600,
        600
      ],
      "parameters": {
        "resource": "row",
        "operation": "insert",
        "dataTableId": {
          "__rl": true,
          "mode": "id",
          "value": "REPLACE_WITH_TABLE_ID",
          "cachedResultName": "Intake_Documents"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "document_key": "={{ $(\"Normalize Document Intake\").item.json.document_key }}",
            "attachment_id": "={{ $(\"Normalize Document Intake\").item.json.attachment_id }}",
            "filename": "={{ $(\"Normalize Document Intake\").item.json.filename }}",
            "mime_type": "={{ $(\"Normalize Document Intake\").item.json.mime_type }}",
            "file_sha256": "={{ $(\"Normalize Document Intake\").item.json.file_sha256 }}",
            "status": "={{ $(\"Normalize Document Intake\").item.json.status }}",
            "document_type": "={{ $(\"Normalize Document Intake\").item.json.document_type }}",
            "party_name": "={{ $(\"Normalize Document Intake\").item.json.party_name }}",
            "document_date": "={{ $(\"Normalize Document Intake\").item.json.document_date }}",
            "amount_total": "={{ $(\"Normalize Document Intake\").item.json.amount_total }}",
            "currency": "={{ $(\"Normalize Document Intake\").item.json.currency }}",
            "confidence": "={{ $(\"Normalize Document Intake\").item.json.confidence }}",
            "validation_errors": "={{ $(\"Normalize Document Intake\").item.json.validation_errors }}",
            "review_reason": "={{ $(\"Normalize Document Intake\").item.json.review_reason }}",
            "archive_path": "={{ $(\"Normalize Document Intake\").item.json.archive_path }}",
            "ocr_confidence": "={{ $(\"Normalize Document Intake\").item.json.ocr_confidence }}",
            "model_transport_chars": "={{ $(\"Normalize Document Intake\").item.json.model_transport_chars }}",
            "pii_redacted_for_model": "={{ $(\"Normalize Document Intake\").item.json.pii_redacted_for_model }}",
            "review_alert_sent": "={{ $(\"Normalize Document Intake\").item.json.review_alert_sent }}",
            "review_alert_id": "={{ $(\"Normalize Document Intake\").item.json.review_alert_id }}",
            "ai_raw_json": "={{ $(\"Normalize Document Intake\").item.json.ai_raw_json }}",
            "model_prompt_excerpt": "={{ $(\"Normalize Document Intake\").item.json.model_prompt_excerpt }}",
            "raw_event_json": "={{ $(\"Normalize Document Intake\").item.json.raw_event_json }}",
            "last_execution_id": "={{ $(\"Normalize Document Intake\").item.json.last_execution_id }}",
            "last_error_class": "={{ $(\"Normalize Document Intake\").item.json.last_error_class }}",
            "last_error_message": "={{ $(\"Normalize Document Intake\").item.json.last_error_message }}",
            "created_at": "={{ $(\"Normalize Document Intake\").item.json.created_at }}",
            "updated_at": "={{ $(\"Normalize Document Intake\").item.json.updated_at }}"
          },
          "schema": [
            {
              "id": "document_key",
              "displayName": "document_key",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "attachment_id",
              "displayName": "attachment_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "filename",
              "displayName": "filename",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "mime_type",
              "displayName": "mime_type",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "file_sha256",
              "displayName": "file_sha256",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "displayName": "status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "document_type",
              "displayName": "document_type",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "party_name",
              "displayName": "party_name",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "document_date",
              "displayName": "document_date",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "amount_total",
              "displayName": "amount_total",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": false
            },
            {
              "id": "currency",
              "displayName": "currency",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "confidence",
              "displayName": "confidence",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": false
            },
            {
              "id": "validation_errors",
              "displayName": "validation_errors",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "review_reason",
              "displayName": "review_reason",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "archive_path",
              "displayName": "archive_path",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "ocr_confidence",
              "displayName": "ocr_confidence",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": false
            },
            {
              "id": "model_transport_chars",
              "displayName": "model_transport_chars",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "number",
              "canBeUsedToMatch": false
            },
            {
              "id": "pii_redacted_for_model",
              "displayName": "pii_redacted_for_model",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "boolean",
              "canBeUsedToMatch": false
            },
            {
              "id": "review_alert_sent",
              "displayName": "review_alert_sent",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "boolean",
              "canBeUsedToMatch": false
            },
            {
              "id": "review_alert_id",
              "displayName": "review_alert_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "ai_raw_json",
              "displayName": "ai_raw_json",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "model_prompt_excerpt",
              "displayName": "model_prompt_excerpt",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "raw_event_json",
              "displayName": "raw_event_json",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "last_execution_id",
              "displayName": "last_execution_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "last_error_class",
              "displayName": "last_error_class",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "last_error_message",
              "displayName": "last_error_message",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "created_at",
              "displayName": "created_at",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "dateTime",
              "canBeUsedToMatch": false
            },
            {
              "id": "updated_at",
              "displayName": "updated_at",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "dateTime",
              "canBeUsedToMatch": false
            }
          ]
        }
      }
    },
    {
      "id": "7df17a97-c2fc-4482-861d-8546ec6d2411",
      "name": "Send Controlled OCR Review Alert",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.2,
      "position": [
        2860,
        600
      ],
      "parameters": {
        "resource": "message",
        "operation": "send",
        "sendTo": "ops@example.com",
        "subject": "=[TEST] OCR review: {{ $(\"Normalize Document Intake\").item.json.filename }}",
        "emailType": "html",
        "message": "=<p><strong>Document held for OCR review</strong></p><p>Filename: {{ $(\"Normalize Document Intake\").item.json.filename_html }}</p><p>Reason: {{ $(\"Normalize Document Intake\").item.json.review_reason_html }}</p><p>Record: {{ $(\"Insert OCR Needs Review\").item.json.id }}</p><p>No archive filing was performed.</p>",
        "options": {
          "appendAttribution": false,
          "senderName": "Acme Automation"
        }
      }
    },
    {
      "id": "d240b371-4ce6-45fd-af6a-37128e18d198",
      "name": "Build OCR Review Alert Update",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3120,
        600
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "const row = $('Insert OCR Needs Review').item.json;\nconst email = $input.item.json || {};\nreturn { json: { id: row.id, status: 'Needs Review', review_alert_sent: true, review_alert_id: email.id || '', updated_at: new Date().toISOString(), last_execution_id: $('Normalize Document Intake').item.json.last_execution_id } };"
      }
    },
    {
      "id": "04a7eda1-79db-42a6-8966-0c42353a5ee6",
      "name": "Update OCR Review Alert Sent",
      "type": "n8n-nodes-base.dataTable",
      "typeVersion": 1.1,
      "position": [
        3380,
        600
      ],
      "parameters": {
        "resource": "row",
        "operation": "update",
        "dataTableId": {
          "__rl": true,
          "mode": "id",
          "value": "REPLACE_WITH_TABLE_ID",
          "cachedResultName": "Intake_Documents"
        },
        "matchType": "allConditions",
        "filters": {
          "conditions": [
            {
              "keyName": "id",
              "condition": "eq",
              "keyValue": "={{ $json.id }}"
            }
          ]
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "status": "={{ $json.status }}",
            "review_alert_sent": "={{ $json.review_alert_sent }}",
            "review_alert_id": "={{ $json.review_alert_id }}",
            "updated_at": "={{ $json.updated_at }}",
            "last_execution_id": "={{ $json.last_execution_id }}"
          },
          "schema": [
            {
              "id": "status",
              "displayName": "status",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": true
            },
            {
              "id": "review_alert_sent",
              "displayName": "review_alert_sent",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "boolean",
              "canBeUsedToMatch": false
            },
            {
              "id": "review_alert_id",
              "displayName": "review_alert_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            },
            {
              "id": "updated_at",
              "displayName": "updated_at",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "dateTime",
              "canBeUsedToMatch": false
            },
            {
              "id": "last_execution_id",
              "displayName": "last_execution_id",
              "required": false,
              "defaultMatch": false,
              "display": true,
              "type": "string",
              "canBeUsedToMatch": false
            }
          ]
        }
      }
    },
    {
      "id": "cb9a04a2-7626-4721-b7b4-24c59f0d96f1",
      "name": "Mark Document Claim OCR Review",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3640,
        600
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "language": "javaScript",
        "jsCode": "const pruneStore = (obj, max = 5000) => {\n  const keys = Object.keys(obj);\n  for (let i = 0; i < keys.length - max; i++) delete obj[keys[i]];\n};\nconst n = $('Normalize Document Intake').item.json;\nconst record = $input.item.json || {};\nconst store = $getWorkflowStaticData('global');\nstore.document_claims = store.document_claims || {};\npruneStore(store.document_claims);\nstore.document_claims[n.document_key] = { ...(store.document_claims[n.document_key] || {}), status: 'Needs Review', record_id: record.id || '', completed_at: new Date().toISOString() };\nreturn { json: record };"
      }
    },
    {
      "id": "4c4c3562-b2db-46c3-922e-bb559b5ba5b8",
      "name": "Respond OCR Needs Review",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.5,
      "position": [
        3900,
        600
      ],
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ { ok: true, status: \"needs_review\", queue: \"human_review\", document_key: $(\"Normalize Document Intake\").item.json.document_key, record_id: $json.id || \"\", reason: $(\"Normalize Document Intake\").item.json.review_reason } }}",
        "options": {
          "responseCode": 200
        }
      }
    },
    {
      "id": "6022c6e2-be3e-43d2-80c6-af2a09dac53f",
      "name": "Respond Intake Unauthorized",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.5,
      "position": [
        780,
        80
      ],
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ { ok: false, status: \"unauthorized\", reason: $json.auth_reason } }}",
        "options": {
          "responseCode": 401
        }
      }
    }
  ],
  "nodeGroups": [],
  "activeVersion": null,
  "parentFolderId": null,
  "scopes": [
    "execution:reveal",
    "workflow:create",
    "workflow:delete",
    "workflow:disableRedaction",
    "workflow:enableRedaction",
    "workflow:execute",
    "workflow:execute-chat",
    "workflow:export",
    "workflow:import",
    "workflow:list",
    "workflow:move",
    "workflow:publish",
    "workflow:read",
    "workflow:share",
    "workflow:unpublish",
    "workflow:unshare",
    "workflow:update"
  ],
  "canExecute": true
}