{
  "name": "extraction-automation",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "/ingest-file",
        "responseMode": "responseNode",
        "options": {
          "binaryPropertyName": "file"
        }
      },
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        -368,
        -816
      ],
      "id": "05e853fd-3056-45fe-8297-64f6a4b23622",
      "name": "Webhook"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "105f5d55-5c1c-47f0-bd6a-14121a90d600",
              "name": "File Name",
              "value": "={{$binary.file0.fileName}}",
              "type": "string"
            },
            {
              "id": "5db364a7-675b-4a66-86aa-86f0e3b1fef3",
              "name": "Mime Type",
              "value": "={{$binary.file0.mimeType}}",
              "type": "string"
            },
            {
              "id": "8095b594-6dce-48c5-9b07-5881a4c87ca5",
              "name": "File Size",
              "value": "={{$binary.file0.fileSize}}",
              "type": "string"
            },
            {
              "id": "841ccb3b-8111-4f11-97ec-382baf848e08",
              "name": "isBinary",
              "value": "={{!!$binary.file0}}",
              "type": "string"
            }
          ]
        },
        "includeOtherFields": true,
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -144,
        -816
      ],
      "id": "c2970f8c-5f5a-48e5-bfc5-a573554889ed",
      "name": "Edit Fields"
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "{\n  \"status\": \"400\",\n  \"message\": \"Unsupported file type\"\n}",
        "options": {}
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.5,
      "position": [
        864,
        -112
      ],
      "id": "91accdd5-1791-41ac-948e-16a5664d102b",
      "name": "Respond to Webhook"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "e7acff39-3107-473e-b2d3-d51e65ae0877",
              "leftValue": "={{ $json['File Name'] }}",
              "rightValue": ".xlsx",
              "operator": {
                "type": "string",
                "operation": "endsWith"
              }
            },
            {
              "id": "685323a6-545b-482e-a2e0-4cb87e9b654f",
              "leftValue": "={{ $json['Mime Type'] }}",
              "rightValue": "spreadsheet",
              "operator": {
                "type": "string",
                "operation": "contains"
              }
            }
          ],
          "combinator": "or"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        528,
        -816
      ],
      "id": "5dccd18a-5331-42c9-8ed1-d889475f3be0",
      "name": "If - .xlsx"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "5196ac4d-dc2b-418f-9cd7-d198b5479786",
              "leftValue": "={{ $('Edit Fields').item.json['File Name'] }}",
              "rightValue": ".csv",
              "operator": {
                "type": "string",
                "operation": "endsWith"
              }
            }
          ],
          "combinator": "or"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        512,
        -624
      ],
      "id": "2a3052f0-7306-40d0-94d3-c7bf7d45ac90",
      "name": "If- .csv"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "5196ac4d-dc2b-418f-9cd7-d198b5479786",
              "leftValue": "={{ $('Edit Fields').item.json['File Name'] }}",
              "rightValue": ".docx",
              "operator": {
                "type": "string",
                "operation": "endsWith"
              }
            },
            {
              "id": "82b86833-71b6-490c-8fb5-dc8cbba54f4a",
              "leftValue": "={{ $('Edit Fields').item.json['Mime Type'] }}",
              "rightValue": "wordprocessingml",
              "operator": {
                "type": "string",
                "operation": "contains"
              }
            }
          ],
          "combinator": "or"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        528,
        -368
      ],
      "id": "dd4c9f6e-8257-4906-8fe4-92279101cf0d",
      "name": "If- .docx"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 3
          },
          "conditions": [
            {
              "id": "5196ac4d-dc2b-418f-9cd7-d198b5479786",
              "leftValue": "={{ $('Edit Fields').item.json['File Name'] }}",
              "rightValue": ".pdf",
              "operator": {
                "type": "string",
                "operation": "endsWith"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.3,
      "position": [
        528,
        -128
      ],
      "id": "1cd84799-ec83-455d-8150-a857f265861e",
      "name": "If- .pdf"
    },
    {
      "parameters": {
        "operation": "xlsx",
        "binaryPropertyName": "file0",
        "options": {
          "headerRow": true,
          "rawData": false
        }
      },
      "type": "n8n-nodes-base.extractFromFile",
      "typeVersion": 1.1,
      "position": [
        752,
        -1008
      ],
      "id": "2659516f-d122-4761-8a7e-1ae15a161a7e",
      "name": "Extract from xlsx"
    },
    {
      "parameters": {
        "operation": "xlsx",
        "binaryPropertyName": "file0",
        "options": {
          "headerRow": true,
          "rawData": false
        }
      },
      "type": "n8n-nodes-base.extractFromFile",
      "typeVersion": 1.1,
      "position": [
        768,
        -640
      ],
      "id": "86f8e8ef-4a62-400a-b2f1-46d57f9df41a",
      "name": "Extract from csv"
    },
    {
      "parameters": {
        "jsCode": "// ======================================================\n// Schema-Driven Normalization (Correct, Stable Version)\n// ======================================================\n\n// ------------------\n// Fetch envelope\n// ------------------\nconst envelope = items[0]?.json;\n\nif (!envelope?.inputSchema || !envelope.inputSchema.input_columns) {\n  throw new Error(\"inputSchema missing or invalid\");\n}\n\nif (!Array.isArray(envelope.rows)) {\n  throw new Error(\"rows missing or invalid\");\n}\n\nconst inputSchema = envelope.inputSchema;\nconst schemaColumns = inputSchema.input_columns;\nconst rows = envelope.rows;\n\n// ------------------\n// Type converters\n// ------------------\nfunction toNumber(value, decimals) {\n  if (value === null || value === undefined || value === \"\") return null;\n  const num = Number(value);\n  if (Number.isNaN(num)) return null;\n  return typeof decimals === \"number\"\n    ? Number(num.toFixed(decimals))\n    : num;\n}\n\nfunction toDate(value) {\n  if (!value) return null;\n  const d = new Date(value);\n  return isNaN(d.getTime()) ? null : d.toISOString().split(\"T\")[0];\n}\n\nfunction toString(value) {\n  if (value === null || value === undefined) return null;\n  return String(value).trim();\n}\n\n// ------------------\n// Normalize rows\n// ------------------\nconst normalizedRows = rows.map((row) => {\n  const normalized = {};\n\n  for (const [outputKey, columnDef] of Object.entries(schemaColumns)) {\n    const inputColumnName = columnDef.label;\n    const rawValue = row[inputColumnName];\n\n    switch (columnDef.type) {\n      case \"number\":\n        normalized[outputKey] = toNumber(rawValue, columnDef.decimal_places);\n        break;\n      case \"date\":\n        normalized[outputKey] = toDate(rawValue);\n        break;\n      case \"string\":\n        normalized[outputKey] = toString(rawValue);\n        break;\n      default:\n        normalized[outputKey] = null;\n    }\n  }\n\n  return normalized;\n});\n\n// ------------------\n// Output (deterministic envelope)\n// ------------------\nreturn [{\n  json: {\n    documentType: envelope.documentType,\n    inputSchema: envelope.inputSchema,\n    rows: normalizedRows\n  }\n}];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1168,
        -1008
      ],
      "id": "89070a8d-f53e-4b2c-a68c-023c25d487a2",
      "name": "normalization- xlsx"
    },
    {
      "parameters": {
        "jsCode": "// Input rows from Normalize step\nconst inputRows = items[0].json.rows;\n\n// === OUTPUT SCHEMA (Option A: hardcoded) ===\nconst fieldMappings = {\n  CONTRACT_ID: { label: 'ID', visible: true },\n  Col_B: { label: 'Process Type', visible: true },\n  Col_C: { label: 'New OR Renewal', visible: true, default_value: 'New' },\n  Col_D: { label: 'Previous Policy No', visible: true },\n  CONTRACT_CODE: { label: 'UMR No.', visible: true },\n  CEDANT: { label: 'Cedant Code', visible: true },\n  CEDANT_NAME: { label: 'Cedant Name', visible: true },\n  Col_H: { label: 'Billing Entity', visible: true },\n  Col_I: { label: 'Original Insured', visible: true },\n  BROKER_NAME: { label: 'Placing Co-Broker', visible: true },\n  SUB_CLASS_NAME: { label: 'Insurance Class', visible: true },\n  Col_L: { label: 'Insurance Product Name', visible: true },\n  CONTRACT_NAME: { label: 'CONTRACT', visible: true },\n  Col_N: { label: 'Issue Date', visible: true },\n  EFFECTIVE_PERIOD_FROM: { label: 'Policy Effective Date', visible: true },\n  EFFECTIVE_PERIOD_TO: { label: 'Policy Expiry Date', visible: true },\n  PREM_WARR_DAYS: { label: 'Premium Warranty', visible: true },\n  PREM_WARR_DATE: { label: 'PPW Date', visible: true },\n  Col_S: { label: 'Type of Placement', visible: true },\n  CONTRACT_TYPE: { label: 'Contract Type', visible: true },\n  BROKER_IN_CHARGE_NAME: { label: 'Servicer Name', visible: true },\n  BROKER_IN_CHARGE_CODE: { label: 'Servicer Short Name', visible: true },\n  ACCEPTANCE_STATUS: { label: 'Status', visible: true },\n  ORIG_CURR_EPI: { label: 'Min Deposit Premium', visible: true },\n  SIGNED_SHARE: { label: 'RI Order(%)', visible: true },\n  CURRENCY: { label: 'Currency', visible: true },\n  Col_AA: { label: 'Premium Amount', visible: true },\n  Col_AB: { label: 'RI Comm(%)', visible: true },\n  Col_AC: { label: 'RI Comm Amt', visible: true },\n  Col_AD: { label: 'Net RI Prem', visible: true },\n  Col_AE: { label: 'Total Amt', visible: true },\n  Col_AF: { label: 'Total', visible: true },\n  Col_AG: { label: 'PremiumP', visible: true },\n  REINSURER_NAME: { label: 'Re Insurer', visible: true },\n  Col_AI: { label: 'LOL', visible: true },\n  BRKG_CALC_METHOD: { label: 'Brokerage Basis', visible: true },\n  EGNPI: { label: 'GNPI', visible: true },\n  PREM_RATING_BASE: { label: 'Rate', visible: true },\n  Col_AM: { label: 'Prem', visible: true },\n  PREM_RATE_PCT: { label: 'Prem Rate %', visible: true },\n  Col_AP: { label: 'Premium Amt', visible: true },\n  RI_SIGNED_SHARE: { label: 'Pre%', visible: true },\n  Col_AR: { label: 'Gross Prem', visible: true },\n  GROSS_BRKG_PCT: { label: 'Brkg %', visible: true },\n  Col_AT: { label: 'Brkg Amt', visible: true },\n  RI_BROKER_NAME: { label: 'RI Placing Co-Broker', visible: true },\n  Col_AV: { label: 'Quantity', visible: true },\n  Col_AW: { label: 'Leader', visible: true },\n  Col_AX: { label: 'Tax Type', visible: true },\n  Col_AY: { label: 'Branch Details', visible: true },\n  Col_AZ: { label: 'Assigned To', visible: true },\n  UW_YEAR: { label: 'UW Year', visible: true },\n  ENDORSEMENT_NO: { label: 'Endorsement No.', visible: true },\n  BRANCH_NAME: { label: 'Branch Name', visible: true },\n  DEPARTMENT_NAME: { label: 'Department Name', visible: true },\n  OUR_REF: { label: 'ASF No.', visible: true },\n  FUND_TYPE_NAME: { label: 'Fund Type', visible: true },\n  PREM_ALERT: { label: 'Prem Alert', visible: true },\n  PROCESS_STATUS: { label: 'Process Status', visible: true },\n  BILL_TYPE: { label: 'Bill Type', visible: true },\n  CLASS_NAME: { label: 'Class', visible: true },\n  CLAIM_ALERT: { label: 'Claim Alert', visible: true },\n  LAYER: { label: 'Layer', visible: true },\n  BASIS_OF_COVER: { label: 'Basis of Cover', visible: true },\n  PORTFOLIO: { label: 'Portfolio', visible: true },\n  NOTICE_PERIOD: { label: 'Notice Period', visible: true },\n  ACC_FREQ: { label: 'Acc Freq', visible: true },\n  RENDER_DEADLINE: { label: 'Render Deadline', visible: true },\n  SETTLEMENT_DEADLINE: { label: 'Statement Deadline', visible: true },\n  PLA_LIMIT: { label: 'PLA Limit', visible: true },\n  CASH_CALL_LIMIT: { label: 'Cash Call Limit', visible: true },\n  ORIG_CURR_DEDUCTIBLE: { label: 'Original Currency Deductible', visible: true },\n  RATE_ON_LINE: { label: 'Rate on Line', visible: true },\n  QS_CEDED: { label: 'QS Ceded', visible: true },\n  NO_OF_LINES: { label: 'No of Lines', visible: true },\n  MAX_RETENTION: { label: 'Max Retention', visible: true },\n  MAX_LIMIT: { label: 'Max Limit', visible: true },\n  ORIGINAL_EPI: { label: 'Original EPI', visible: true },\n  REVISED_EPI: { label: 'Revised EPI', visible: true },\n  PREMIUM_RESERVE_PCT: { label: 'Premium Reserve %', visible: true },\n  PREMIUM_RESERVE_DESC: { label: 'Premium Reserve Description', visible: true },\n  LOSS_RESERVE_PCT: { label: 'Loss Reserve %', visible: true },\n  INT_ON_RESERVE_PCT: { label: 'INT on Reserve %', visible: true },\n  INT_ON_RESERVE_DESC: { label: 'INT on Reserve Description', visible: true },\n  TAX_ON_INTEREST_PCT: { label: 'Tax on Interest %', visible: true },\n  TAX_ON_INTEREST_DESC: { label: 'Tax on Interest Description', visible: true },\n  COMMISSION_PCT: { label: 'Commission %', visible: true },\n  COMMISSION_DESC: { label: 'Commission Description', visible: true },\n  PROVISIONAL_COMM_PCT: { label: 'Provisional Commission %', visible: true },\n  OVERRIDING_COMM: { label: 'Overriding Commission', visible: true },\n  TAXES_AND_CHARGES: { label: 'Taxes and Charges', visible: true },\n  PROFIT_COMM: { label: 'Profit Commission', visible: true },\n  PROFIT_COMM_ME: { label: 'Profit Commission Me', visible: true },\n  PROFIT_COMM_BASIS: { label: 'Profit Comm Basis', visible: true },\n  PORTFOLIO_PREM_IN: { label: 'Portfolio Prem In', visible: true },\n  PORTFOLIO_LOSS_IN: { label: 'Portfolio Loss In', visible: true },\n  PORTFOLIO_LOSS_OUT: { label: 'Portfolio Loss Out', visible: true },\n  SOURCE_BRKG_PCT: { label: 'Source Brkg%', visible: true },\n  ORIG_CURR_AGG_LIMIT: { label: 'Original Currency Agg Limit', visible: true },\n  ORIG_CURR_AGG_DEDUCTIBLE: { label: 'Original Currency Agg Deductible', visible: true },\n  ORIG_CURR_AGG_INDEM_PER_EVENT: {\n    label: 'Original Currency Agg Indem Per Event',\n    visible: true\n  },\n  NO_OF_REINSTATEMENT: { label: 'No. of Reinstatement', visible: true },\n  REINSTATEMENT_BASIS: { label: 'Reinstatement Basis', visible: true },\n  REINSTATEMENT_AGG_LIMIT: { label: 'Reinstatement Agg Limit', visible: true },\n  NO_OF_STATEMENTS: { label: 'No. of Statements', visible: true },\n  FIRST_STATEMENT_DUE: { label: 'First Statement Due', visible: true },\n  INFORMATION: { label: 'Information', visible: true }\n};\n\n\n// === SCHEMA APPLICATION ===\nconst outputRows = inputRows.map(row => {\n  const out = {};\n\n  for (const [sourceKey, config] of Object.entries(fieldMappings)) {\n    if (config.visible === false) continue;\n\n    let value = row[sourceKey];\n\n    if (\n      (value === undefined || value === null || value === '') &&\n      config.default_value !== undefined\n    ) {\n      value = config.default_value;\n    }\n\n    out[config.label] = value ?? '';\n  }\n\n  return out;\n});\n\n// n8n expects array of items\nreturn outputRows.map(r => ({ json: r }));\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1632,
        -1008
      ],
      "id": "88f80d18-c14f-49b4-bc02-ccc9b2e55c6f",
      "name": "mapping schema"
    },
    {
      "parameters": {
        "operation": "xlsx",
        "binaryPropertyName": "output",
        "options": {}
      },
      "type": "n8n-nodes-base.convertToFile",
      "typeVersion": 1.1,
      "position": [
        1856,
        -1008
      ],
      "id": "e8c6ba04-8e51-45b4-be8c-94c533ec78de",
      "name": "Convert to File"
    },
    {
      "parameters": {
        "respondWith": "binary",
        "options": {}
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.5,
      "position": [
        2080,
        -1008
      ],
      "id": "f0cef090-1ce5-43a8-9c50-a08d49c3c482",
      "name": "Respond to Webhook1"
    },
    {
      "parameters": {
        "jsCode": "const docType = $json.query?.document_type;\n\nif (!docType) {\n  throw new Error(\"document_type is required\");\n}\n\nconst SUPPORTED = [\"generic_v1\"];\n\nif (!SUPPORTED.includes(docType)) {\n  throw new Error(`Unsupported document type: ${docType}`);\n}\n\nreturn [{\n  json: {\n    ...$json,\n    documentType: docType\n  },\n  binary: $binary\n}];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        80,
        -816
      ],
      "id": "9f4b24e9-2e98-43f8-93de-fd52b0b212eb",
      "name": "Resolve document type"
    },
    {
      "parameters": {
        "jsCode": "// ======================================================\n// Input Schema Selector\n// - Schema is treated as authoritative contract\n// ======================================================\n\n// Step 1 must already have set this\nconst documentType = $json.documentType;\n\nif (!documentType) {\n  throw new Error(\"documentType missing. Step 1 not executed.\");\n}\n\n// ====================\n// INPUT SCHEMAS\n// ====================\nconst INPUT_SCHEMAS = {\n  generic_v1: {\n    \"schema_version\": \"1.0\",\n    \"description\": \"Auto-generated schema for data\",\n    \"sheet_name\": \"data\",\n    \"data_type_support\": {\n      \"string\": \"Text values - preserved as-is from Excel cells\",\n      \"number\": \"Numeric values - converted to float for proper decimal precision handling\",\n      \"date\": \"Date values - converted to datetime objects for proper date handling\"\n    },\n    \"input_columns\": {\n      \"UW_YEAR\": { \"label\": \"UW_YEAR\", \"type\": \"number\" },\n      \"CONTRACT_ID\": { \"label\": \"CONTRACT_ID\", \"type\": \"number\" },\n      \"CONTRACT_CODE\": { \"label\": \"CONTRACT_CODE\", \"type\": \"string\" },\n      \"CONTRACT_TYPE\": { \"label\": \"CONTRACT_TYPE\", \"type\": \"string\" },\n      \"ORIGINAL_CONTRACT_ID\": { \"label\": \"ORIGINAL_CONTRACT_ID\", \"type\": \"number\" },\n      \"COUNTRY_ID\": { \"label\": \"COUNTRY_ID\", \"type\": \"number\" },\n      \"COUNTRY\": { \"label\": \"COUNTRY\", \"type\": \"string\" },\n      \"CEDANT\": { \"label\": \"CEDANT\", \"type\": \"number\" },\n      \"CEDANT_NAME\": { \"label\": \"CEDANT_NAME\", \"type\": \"string\" },\n      \"BROKER\": { \"label\": \"BROKER\", \"type\": \"number\" },\n      \"BROKER_NAME\": { \"label\": \"BROKER_NAME\", \"type\": \"string\" },\n      \"CLASS\": { \"label\": \"CLASS\", \"type\": \"number\" },\n      \"CLASS_NAME\": { \"label\": \"CLASS_NAME\", \"type\": \"string\" },\n      \"SUB_CLASS\": { \"label\": \"SUB_CLASS\", \"type\": \"number\" },\n      \"SUB_CLASS_NAME\": { \"label\": \"SUB_CLASS_NAME\", \"type\": \"string\" },\n      \"SUBTYPE\": { \"label\": \"SUBTYPE\", \"type\": \"number\" },\n      \"SUBTYPE_NAME\": { \"label\": \"SUBTYPE_NAME\", \"type\": \"string\" },\n      \"CONTRACT_NAME\": { \"label\": \"CONTRACT_NAME\", \"type\": \"string\" },\n      \"ENDORSEMENT_NO\": { \"label\": \"ENDORSEMENT_NO\", \"type\": \"number\" },\n      \"PERIOD_FROM\": { \"label\": \"PERIOD_FROM\", \"type\": \"date\" },\n      \"PERIOD_TO\": { \"label\": \"PERIOD_TO\", \"type\": \"date\" },\n      \"EFFECTIVE_PERIOD_FROM\": { \"label\": \"EFFECTIVE_PERIOD_FROM\", \"type\": \"date\" },\n      \"EFFECTIVE_PERIOD_TO\": { \"label\": \"EFFECTIVE_PERIOD_TO\", \"type\": \"date\" },\n      \"ACCEPTANCE_STATUS\": { \"label\": \"ACCEPTANCE_STATUS\", \"type\": \"string\" },\n      \"PROCESS_STATUS\": { \"label\": \"PROCESS_STATUS\", \"type\": \"string\" },\n      \"PREM_WARR_DAYS\": { \"label\": \"PREM_WARR_DAYS\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"PREM_WARR_DATE\": { \"label\": \"PREM_WARR_DATE\", \"type\": \"date\" },\n      \"PREM_ALERT\": { \"label\": \"PREM_ALERT\", \"type\": \"string\" },\n      \"CLAIM_ALERT\": { \"label\": \"CLAIM_ALERT\", \"type\": \"string\" },\n      \"BILL_TYPE\": { \"label\": \"BILL_TYPE\", \"type\": \"string\" },\n      \"BRANCH_ID\": { \"label\": \"BRANCH_ID\", \"type\": \"number\" },\n      \"BRANCH_NAME\": { \"label\": \"BRANCH_NAME\", \"type\": \"string\" },\n      \"DEPARTMENT_ID\": { \"label\": \"DEPARTMENT_ID\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"DEPARTMENT_NAME\": { \"label\": \"DEPARTMENT_NAME\", \"type\": \"string\" },\n      \"BROKER_IN_CHARGE_NAME\": { \"label\": \"BROKER_IN_CHARGE_NAME\", \"type\": \"string\" },\n      \"BROKER_IN_CHARGE_CODE\": { \"label\": \"BROKER_IN_CHARGE_CODE\", \"type\": \"string\" },\n      \"OUR_REF\": { \"label\": \"OUR_REF\", \"type\": \"string\" },\n      \"FUND_TYPE\": { \"label\": \"FUND_TYPE\", \"type\": \"number\" },\n      \"FUND_TYPE_NAME\": { \"label\": \"FUND_TYPE_NAME\", \"type\": \"string\" },\n      \"ORDER_SHARE\": { \"label\": \"ORDER_SHARE\", \"type\": \"number\", \"decimal_places\": 2 },\n      \"WRITTEN_SHARE\": { \"label\": \"WRITTEN_SHARE\", \"type\": \"number\", \"decimal_places\": 2 },\n      \"SIGNED_SHARE\": { \"label\": \"SIGNED_SHARE\", \"type\": \"number\", \"decimal_places\": 2 },\n      \"CURRENCY_ID\": { \"label\": \"CURRENCY_ID\", \"type\": \"number\" },\n      \"CURRENCY\": { \"label\": \"CURRENCY\", \"type\": \"string\" },\n      \"LAYER\": { \"label\": \"LAYER\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"BASIS_OF_COVER\": { \"label\": \"BASIS_OF_COVER\", \"type\": \"string\" },\n      \"PORTFOLIO\": { \"label\": \"PORTFOLIO\", \"type\": \"string\" },\n      \"NOTICE_PERIOD\": { \"label\": \"NOTICE_PERIOD\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"ACC_FREQ\": { \"label\": \"ACC_FREQ\", \"type\": \"string\" },\n      \"RENDER_DEADLINE\": { \"label\": \"RENDER_DEADLINE\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"SETTLEMENT_DEADLINE\": { \"label\": \"SETTLEMENT_DEADLINE\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"PLA_LIMIT\": { \"label\": \"PLA_LIMIT\", \"type\": \"number\", \"decimal_places\": 2 },\n      \"CASH_CALL_LIMIT\": { \"label\": \"CASH_CALL_LIMIT\", \"type\": \"number\", \"decimal_places\": 2 },\n      \"ORIG_CURR_LIMIT\": { \"label\": \"ORIG_CURR_LIMIT\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"ORIG_CURR_DEDUCTIBLE\": { \"label\": \"ORIG_CURR_DEDUCTIBLE\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"EGNPI\": { \"label\": \"EGNPI\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"PREM_RATING_BASE\": { \"label\": \"PREM_RATING_BASE\", \"type\": \"string\" },\n      \"PREM_RATE_PCT\": { \"label\": \"PREM_RATE_PCT\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"ORIG_CURR_MINIMUM\": { \"label\": \"ORIG_CURR_MINIMUM\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"ORIG_CURR_DEPOSIT\": { \"label\": \"ORIG_CURR_DEPOSIT\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"ORIG_CURR_EPI\": { \"label\": \"ORIG_CURR_EPI\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"RATE_ON_LINE\": { \"label\": \"RATE_ON_LINE\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"QS_CEDED\": { \"label\": \"QS_CEDED\", \"type\": \"string\" },\n      \"NO_OF_LINES\": { \"label\": \"NO_OF_LINES\", \"type\": \"number\" },\n      \"MAX_RETENTION\": { \"label\": \"MAX_RETENTION\", \"type\": \"string\" },\n      \"MAX_LIMIT\": { \"label\": \"MAX_LIMIT\", \"type\": \"number\", \"decimal_places\": 2 },\n      \"ORIGINAL_EPI\": { \"label\": \"ORIGINAL_EPI\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"REVISED_EPI\": { \"label\": \"REVISED_EPI\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"PREMIUM_RESERVE_PCT\": { \"label\": \"PREMIUM_RESERVE_PCT\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"PREMIUM_RESERVE_DESC\": { \"label\": \"PREMIUM_RESERVE_DESC\", \"type\": \"string\" },\n      \"LOSS_RESERVE_PCT\": { \"label\": \"LOSS_RESERVE_PCT\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"LOSS_RESERVE_DESC\": { \"label\": \"LOSS_RESERVE_DESC\", \"type\": \"string\" },\n      \"INT_ON_RESERVE_PCT\": { \"label\": \"INT_ON_RESERVE_PCT\", \"type\": \"number\" },\n      \"INT_ON_RESERVE_DESC\": { \"label\": \"INT_ON_RESERVE_DESC\", \"type\": \"string\" },\n      \"TAX_ON_INTEREST_PCT\": { \"label\": \"TAX_ON_INTEREST_PCT\", \"type\": \"number\" },\n      \"TAX_ON_INTEREST_DESC\": { \"label\": \"TAX_ON_INTEREST_DESC\", \"type\": \"string\" },\n      \"COMMISSION_PCT\": { \"label\": \"COMMISSION_PCT\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"COMMISSION_DESC\": { \"label\": \"COMMISSION_DESC\", \"type\": \"string\" },\n      \"PROVISIONAL_COMM_PCT\": { \"label\": \"PROVISIONAL_COMM_PCT\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"OVERRIDING_COMM\": { \"label\": \"OVERRIDING_COMM\", \"type\": \"string\" },\n      \"TAXES_AND_CHARGES\": { \"label\": \"TAXES_AND_CHARGES\", \"type\": \"string\" },\n      \"PROFIT_COMM\": { \"label\": \"PROFIT_COMM\", \"type\": \"string\" },\n      \"PROFIT_COMM_ME\": { \"label\": \"PROFIT_COMM_ME\", \"type\": \"string\" },\n      \"PROFIT_COMM_BASIS\": { \"label\": \"PROFIT_COMM_BASIS\", \"type\": \"string\" },\n      \"PORTFOLIO_PREM_IN\": { \"label\": \"PORTFOLIO_PREM_IN\", \"type\": \"string\" },\n      \"PORTFOLIO_PREM_OUT\": { \"label\": \"PORTFOLIO_PREM_OUT\", \"type\": \"string\" },\n      \"PORTFOLIO_LOSS_IN\": { \"label\": \"PORTFOLIO_LOSS_IN\", \"type\": \"string\" },\n      \"PORTFOLIO_LOSS_OUT\": { \"label\": \"PORTFOLIO_LOSS_OUT\", \"type\": \"string\" },\n      \"GROSS_BRKG_PCT\": { \"label\": \"GROSS_BRKG_PCT\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"SOURCE_BRKG_PCT\": { \"label\": \"SOURCE_BRKG_PCT\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"ORIG_CURR_AGG_LIMIT\": { \"label\": \"ORIG_CURR_AGG_LIMIT\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"ORIG_CURR_AGG_DEDUCTIBLE\": { \"label\": \"ORIG_CURR_AGG_DEDUCTIBLE\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"ORIG_CURR_AGG_INDEM_PER_EVENT\": { \"label\": \"ORIG_CURR_AGG_INDEM_PER_EVENT\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"NO_OF_REINSTATEMENT\": { \"label\": \"NO_OF_REINSTATEMENT\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"REINSTATEMENT_BASIS\": { \"label\": \"REINSTATEMENT_BASIS\", \"type\": \"string\" },\n      \"REINSTATEMENT_AGG_LIMIT\": { \"label\": \"REINSTATEMENT_AGG_LIMIT\", \"type\": \"number\", \"decimal_places\": 1 },\n      \"NO_OF_STATEMENTS\": { \"label\": \"NO_OF_STATEMENTS\", \"type\": \"number\" },\n      \"FIRST_STATEMENT_DUE\": { \"label\": \"FIRST_STATEMENT_DUE\", \"type\": \"date\" },\n      \"INFORMATION\": { \"label\": \"INFORMATION\", \"type\": \"string\" }\n    },\n    \"source_file\": \"data.xlsx\",\n    \"generated_at\": \"2025-12-19T08:43:58.206388\"\n  }\n};\n\n// ====================\n// Schema Resolution\n// ====================\nconst inputSchema = INPUT_SCHEMAS[documentType];\n\nif (!inputSchema) {\n  throw new Error(`Unsupported document type: ${documentType}`);\n}\n\n// Pass schema downstream untouched\nreturn [{\n  json: {\n    ...$json,\n    inputSchema\n  },\n  binary: $binary\n}];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        304,
        -816
      ],
      "id": "382fc10d-4a04-40a0-832c-fac8d7edfa15",
      "name": "Select Input Schema"
    },
    {
      "parameters": {
        "jsCode": "// ======================================================\n// Validation (Hard Fail)\n// ======================================================\n\nconst rows = $json.rows;\nconst schema = $json.inputSchema;\n\nif (!Array.isArray(rows)) {\n  throw new Error(\"rows missing or invalid\");\n}\n\nif (!schema || !schema.input_columns) {\n  throw new Error(\"inputSchema missing during validation\");\n}\n\n// ------------------\n// Define critical fields\n// ------------------\nconst REQUIRED_FIELDS = [\n  \"UW_YEAR\",\n  \"CONTRACT_ID\",\n  \"CONTRACT_CODE\"\n];\n\n// ------------------\n// Type check helpers\n// ------------------\nfunction isValidType(value, type) {\n  if (value === null) return true; // null allowed unless required\n  if (type === \"number\") return typeof value === \"number\";\n  if (type === \"string\") return typeof value === \"string\";\n  if (type === \"date\") return typeof value === \"string\"; // ISO date\n  return false;\n}\n\n// ------------------\n// Validate rows\n// ------------------\nrows.forEach((row, rowIndex) => {\n  // Required fields\n  REQUIRED_FIELDS.forEach((field) => {\n    if (row[field] === null || row[field] === undefined) {\n      throw new Error(\n        `Validation error: Missing required field '${field}' at row ${rowIndex + 1}`\n      );\n    }\n  });\n\n  // Type validation\n  for (const [field, def] of Object.entries(schema.input_columns)) {\n    if (!isValidType(row[field], def.type)) {\n      throw new Error(\n        `Validation error: Field '${field}' expected ${def.type} at row ${rowIndex + 1}`\n      );\n    }\n  }\n});\n\n// ------------------\n// Pass through if valid\n// ------------------\nreturn [{\n  json: $json\n}];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1392,
        -1008
      ],
      "id": "e7771816-941e-48d8-b9df-177620a88727",
      "name": "validate-normalized-data"
    },
    {
      "parameters": {
        "jsCode": "const inputSchema = $node[\"Select Input Schema\"].json.inputSchema;\n\nif (!inputSchema) {\n  throw new Error(\"inputSchema not found\");\n}\n\n// Collect all extracted rows\nconst rows = items.map(item => item.json);\n\nreturn [{\n  json: {\n    rows,\n    inputSchema\n  },\n  binary: $binary\n}];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        960,
        -1008
      ],
      "id": "7553ea0b-f787-46a9-bcea-2fc4dbdb687b",
      "name": "Reattach Input Schema"
    },
    {
      "parameters": {
        "jsCode": "const inputSchema = $node[\"Select Input Schema\"].json.inputSchema;\n\nif (!inputSchema) {\n  throw new Error(\"inputSchema not found\");\n}\n\n// Collect all extracted rows\nconst rows = items.map(item => item.json);\n\nreturn [{\n  json: {\n    rows,\n    inputSchema\n  },\n  binary: $binary\n}];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        960,
        -640
      ],
      "id": "536d6956-8997-4318-944b-08869f7f5f0a",
      "name": "Reattach Input Schema1"
    },
    {
      "parameters": {
        "jsCode": "// ======================================================\n// Schema-Driven Normalization (Correct, Stable Version)\n// ======================================================\n\n// ------------------\n// Fetch envelope\n// ------------------\nconst envelope = items[0]?.json;\n\nif (!envelope?.inputSchema || !envelope.inputSchema.input_columns) {\n  throw new Error(\"inputSchema missing or invalid\");\n}\n\nif (!Array.isArray(envelope.rows)) {\n  throw new Error(\"rows missing or invalid\");\n}\n\nconst inputSchema = envelope.inputSchema;\nconst schemaColumns = inputSchema.input_columns;\nconst rows = envelope.rows;\n\n// ------------------\n// Type converters\n// ------------------\nfunction toNumber(value, decimals) {\n  if (value === null || value === undefined || value === \"\") return null;\n  const num = Number(value);\n  if (Number.isNaN(num)) return null;\n  return typeof decimals === \"number\"\n    ? Number(num.toFixed(decimals))\n    : num;\n}\n\nfunction toDate(value) {\n  if (!value) return null;\n  const d = new Date(value);\n  return isNaN(d.getTime()) ? null : d.toISOString().split(\"T\")[0];\n}\n\nfunction toString(value) {\n  if (value === null || value === undefined) return null;\n  return String(value).trim();\n}\n\n// ------------------\n// Normalize rows\n// ------------------\nconst normalizedRows = rows.map((row) => {\n  const normalized = {};\n\n  for (const [outputKey, columnDef] of Object.entries(schemaColumns)) {\n    const inputColumnName = columnDef.label;\n    const rawValue = row[inputColumnName];\n\n    switch (columnDef.type) {\n      case \"number\":\n        normalized[outputKey] = toNumber(rawValue, columnDef.decimal_places);\n        break;\n      case \"date\":\n        normalized[outputKey] = toDate(rawValue);\n        break;\n      case \"string\":\n        normalized[outputKey] = toString(rawValue);\n        break;\n      default:\n        normalized[outputKey] = null;\n    }\n  }\n\n  return normalized;\n});\n\n// ------------------\n// Output (deterministic envelope)\n// ------------------\nreturn [{\n  json: {\n    documentType: envelope.documentType,\n    inputSchema: envelope.inputSchema,\n    rows: normalizedRows\n  }\n}];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1168,
        -640
      ],
      "id": "505d32c2-0e10-406c-abe9-e1de4f7ee929",
      "name": "normalization- xlsx1"
    },
    {
      "parameters": {
        "jsCode": "// ======================================================\n// Validation (Hard Fail)\n// ======================================================\n\nconst rows = $json.rows;\nconst schema = $json.inputSchema;\n\nif (!Array.isArray(rows)) {\n  throw new Error(\"rows missing or invalid\");\n}\n\nif (!schema || !schema.input_columns) {\n  throw new Error(\"inputSchema missing during validation\");\n}\n\n// ------------------\n// Define critical fields\n// ------------------\nconst REQUIRED_FIELDS = [\n  \"UW_YEAR\",\n  \"CONTRACT_ID\",\n  \"CONTRACT_CODE\"\n];\n\n// ------------------\n// Type check helpers\n// ------------------\nfunction isValidType(value, type) {\n  if (value === null) return true; // null allowed unless required\n  if (type === \"number\") return typeof value === \"number\";\n  if (type === \"string\") return typeof value === \"string\";\n  if (type === \"date\") return typeof value === \"string\"; // ISO date\n  return false;\n}\n\n// ------------------\n// Validate rows\n// ------------------\nrows.forEach((row, rowIndex) => {\n  // Required fields\n  REQUIRED_FIELDS.forEach((field) => {\n    if (row[field] === null || row[field] === undefined) {\n      throw new Error(\n        `Validation error: Missing required field '${field}' at row ${rowIndex + 1}`\n      );\n    }\n  });\n\n  // Type validation\n  for (const [field, def] of Object.entries(schema.input_columns)) {\n    if (!isValidType(row[field], def.type)) {\n      throw new Error(\n        `Validation error: Field '${field}' expected ${def.type} at row ${rowIndex + 1}`\n      );\n    }\n  }\n});\n\n// ------------------\n// Pass through if valid\n// ------------------\nreturn [{\n  json: $json\n}];\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1376,
        -640
      ],
      "id": "232ef567-f325-4f68-afef-2d1e4be5cbcd",
      "name": "validate-normalized-data1"
    },
    {
      "parameters": {
        "jsCode": "// Input rows from Normalize step\nconst inputRows = items[0].json.rows;\n\n// === OUTPUT SCHEMA (Option A: hardcoded) ===\nconst fieldMappings = {\n  CONTRACT_ID: { label: 'ID', visible: true },\n  Col_B: { label: 'Process Type', visible: true },\n  Col_C: { label: 'New OR Renewal', visible: true, default_value: 'New' },\n  Col_D: { label: 'Previous Policy No', visible: true },\n  CONTRACT_CODE: { label: 'UMR No.', visible: true },\n  CEDANT: { label: 'Cedant Code', visible: true },\n  CEDANT_NAME: { label: 'Cedant Name', visible: true },\n  Col_H: { label: 'Billing Entity', visible: true },\n  Col_I: { label: 'Original Insured', visible: true },\n  BROKER_NAME: { label: 'Placing Co-Broker', visible: true },\n  SUB_CLASS_NAME: { label: 'Insurance Class', visible: true },\n  Col_L: { label: 'Insurance Product Name', visible: true },\n  CONTRACT_NAME: { label: 'CONTRACT', visible: true },\n  Col_N: { label: 'Issue Date', visible: true },\n  EFFECTIVE_PERIOD_FROM: { label: 'Policy Effective Date', visible: true },\n  EFFECTIVE_PERIOD_TO: { label: 'Policy Expiry Date', visible: true },\n  PREM_WARR_DAYS: { label: 'Premium Warranty', visible: true },\n  PREM_WARR_DATE: { label: 'PPW Date', visible: true },\n  Col_S: { label: 'Type of Placement', visible: true },\n  CONTRACT_TYPE: { label: 'Contract Type', visible: true },\n  BROKER_IN_CHARGE_NAME: { label: 'Servicer Name', visible: true },\n  BROKER_IN_CHARGE_CODE: { label: 'Servicer Short Name', visible: true },\n  ACCEPTANCE_STATUS: { label: 'Status', visible: true },\n  ORIG_CURR_EPI: { label: 'Min Deposit Premium', visible: true },\n  SIGNED_SHARE: { label: 'RI Order(%)', visible: true },\n  CURRENCY: { label: 'Currency', visible: true },\n  Col_AA: { label: 'Premium Amount', visible: true },\n  Col_AB: { label: 'RI Comm(%)', visible: true },\n  Col_AC: { label: 'RI Comm Amt', visible: true },\n  Col_AD: { label: 'Net RI Prem', visible: true },\n  Col_AE: { label: 'Total Amt', visible: true },\n  Col_AF: { label: 'Total', visible: true },\n  Col_AG: { label: 'PremiumP', visible: true },\n  REINSURER_NAME: { label: 'Re Insurer', visible: true },\n  Col_AI: { label: 'LOL', visible: true },\n  BRKG_CALC_METHOD: { label: 'Brokerage Basis', visible: true },\n  EGNPI: { label: 'GNPI', visible: true },\n  PREM_RATING_BASE: { label: 'Rate', visible: true },\n  Col_AM: { label: 'Prem', visible: true },\n  PREM_RATE_PCT: { label: 'Prem Rate %', visible: true },\n  Col_AP: { label: 'Premium Amt', visible: true },\n  RI_SIGNED_SHARE: { label: 'Pre%', visible: true },\n  Col_AR: { label: 'Gross Prem', visible: true },\n  GROSS_BRKG_PCT: { label: 'Brkg %', visible: true },\n  Col_AT: { label: 'Brkg Amt', visible: true },\n  RI_BROKER_NAME: { label: 'RI Placing Co-Broker', visible: true },\n  Col_AV: { label: 'Quantity', visible: true },\n  Col_AW: { label: 'Leader', visible: true },\n  Col_AX: { label: 'Tax Type', visible: true },\n  Col_AY: { label: 'Branch Details', visible: true },\n  Col_AZ: { label: 'Assigned To', visible: true },\n  UW_YEAR: { label: 'UW Year', visible: true },\n  ENDORSEMENT_NO: { label: 'Endorsement No.', visible: true },\n  BRANCH_NAME: { label: 'Branch Name', visible: true },\n  DEPARTMENT_NAME: { label: 'Department Name', visible: true },\n  OUR_REF: { label: 'ASF No.', visible: true },\n  FUND_TYPE_NAME: { label: 'Fund Type', visible: true },\n  PREM_ALERT: { label: 'Prem Alert', visible: true },\n  PROCESS_STATUS: { label: 'Process Status', visible: true },\n  BILL_TYPE: { label: 'Bill Type', visible: true },\n  CLASS_NAME: { label: 'Class', visible: true },\n  CLAIM_ALERT: { label: 'Claim Alert', visible: true },\n  LAYER: { label: 'Layer', visible: true },\n  BASIS_OF_COVER: { label: 'Basis of Cover', visible: true },\n  PORTFOLIO: { label: 'Portfolio', visible: true },\n  NOTICE_PERIOD: { label: 'Notice Period', visible: true },\n  ACC_FREQ: { label: 'Acc Freq', visible: true },\n  RENDER_DEADLINE: { label: 'Render Deadline', visible: true },\n  SETTLEMENT_DEADLINE: { label: 'Statement Deadline', visible: true },\n  PLA_LIMIT: { label: 'PLA Limit', visible: true },\n  CASH_CALL_LIMIT: { label: 'Cash Call Limit', visible: true },\n  ORIG_CURR_DEDUCTIBLE: { label: 'Original Currency Deductible', visible: true },\n  RATE_ON_LINE: { label: 'Rate on Line', visible: true },\n  QS_CEDED: { label: 'QS Ceded', visible: true },\n  NO_OF_LINES: { label: 'No of Lines', visible: true },\n  MAX_RETENTION: { label: 'Max Retention', visible: true },\n  MAX_LIMIT: { label: 'Max Limit', visible: true },\n  ORIGINAL_EPI: { label: 'Original EPI', visible: true },\n  REVISED_EPI: { label: 'Revised EPI', visible: true },\n  PREMIUM_RESERVE_PCT: { label: 'Premium Reserve %', visible: true },\n  PREMIUM_RESERVE_DESC: { label: 'Premium Reserve Description', visible: true },\n  LOSS_RESERVE_PCT: { label: 'Loss Reserve %', visible: true },\n  INT_ON_RESERVE_PCT: { label: 'INT on Reserve %', visible: true },\n  INT_ON_RESERVE_DESC: { label: 'INT on Reserve Description', visible: true },\n  TAX_ON_INTEREST_PCT: { label: 'Tax on Interest %', visible: true },\n  TAX_ON_INTEREST_DESC: { label: 'Tax on Interest Description', visible: true },\n  COMMISSION_PCT: { label: 'Commission %', visible: true },\n  COMMISSION_DESC: { label: 'Commission Description', visible: true },\n  PROVISIONAL_COMM_PCT: { label: 'Provisional Commission %', visible: true },\n  OVERRIDING_COMM: { label: 'Overriding Commission', visible: true },\n  TAXES_AND_CHARGES: { label: 'Taxes and Charges', visible: true },\n  PROFIT_COMM: { label: 'Profit Commission', visible: true },\n  PROFIT_COMM_ME: { label: 'Profit Commission Me', visible: true },\n  PROFIT_COMM_BASIS: { label: 'Profit Comm Basis', visible: true },\n  PORTFOLIO_PREM_IN: { label: 'Portfolio Prem In', visible: true },\n  PORTFOLIO_LOSS_IN: { label: 'Portfolio Loss In', visible: true },\n  PORTFOLIO_LOSS_OUT: { label: 'Portfolio Loss Out', visible: true },\n  SOURCE_BRKG_PCT: { label: 'Source Brkg%', visible: true },\n  ORIG_CURR_AGG_LIMIT: { label: 'Original Currency Agg Limit', visible: true },\n  ORIG_CURR_AGG_DEDUCTIBLE: { label: 'Original Currency Agg Deductible', visible: true },\n  ORIG_CURR_AGG_INDEM_PER_EVENT: {\n    label: 'Original Currency Agg Indem Per Event',\n    visible: true\n  },\n  NO_OF_REINSTATEMENT: { label: 'No. of Reinstatement', visible: true },\n  REINSTATEMENT_BASIS: { label: 'Reinstatement Basis', visible: true },\n  REINSTATEMENT_AGG_LIMIT: { label: 'Reinstatement Agg Limit', visible: true },\n  NO_OF_STATEMENTS: { label: 'No. of Statements', visible: true },\n  FIRST_STATEMENT_DUE: { label: 'First Statement Due', visible: true },\n  INFORMATION: { label: 'Information', visible: true }\n};\n\n\n// === SCHEMA APPLICATION ===\nconst outputRows = inputRows.map(row => {\n  const out = {};\n\n  for (const [sourceKey, config] of Object.entries(fieldMappings)) {\n    if (config.visible === false) continue;\n\n    let value = row[sourceKey];\n\n    if (\n      (value === undefined || value === null || value === '') &&\n      config.default_value !== undefined\n    ) {\n      value = config.default_value;\n    }\n\n    out[config.label] = value ?? '';\n  }\n\n  return out;\n});\n\n// n8n expects array of items\nreturn outputRows.map(r => ({ json: r }));\n"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1600,
        -640
      ],
      "id": "fb656eac-7fbd-46f7-913d-aa33fae7507e",
      "name": "mapping schema1"
    },
    {
      "parameters": {
        "operation": "xlsx",
        "binaryPropertyName": "output",
        "options": {}
      },
      "type": "n8n-nodes-base.convertToFile",
      "typeVersion": 1.1,
      "position": [
        1808,
        -640
      ],
      "id": "b8465683-2117-4fd9-9c1d-fb41953e7916",
      "name": "Convert to File1"
    },
    {
      "parameters": {
        "respondWith": "binary",
        "options": {}
      },
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.5,
      "position": [
        2016,
        -640
      ],
      "id": "0abd2d3b-17fb-48a2-9d98-ebe5cabe504c",
      "name": "Respond to Webhook2"
    }
  ],
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Edit Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Edit Fields": {
      "main": [
        [
          {
            "node": "Resolve document type",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If - .xlsx": {
      "main": [
        [
          {
            "node": "Extract from xlsx",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "If- .csv",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If- .csv": {
      "main": [
        [
          {
            "node": "Extract from csv",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "If- .docx",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If- .docx": {
      "main": [
        [],
        [
          {
            "node": "If- .pdf",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If- .pdf": {
      "main": [
        [],
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from xlsx": {
      "main": [
        [
          {
            "node": "Reattach Input Schema",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract from csv": {
      "main": [
        [
          {
            "node": "Reattach Input Schema1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "normalization- xlsx": {
      "main": [
        [
          {
            "node": "validate-normalized-data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "mapping schema": {
      "main": [
        [
          {
            "node": "Convert to File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert to File": {
      "main": [
        [
          {
            "node": "Respond to Webhook1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Resolve document type": {
      "main": [
        [
          {
            "node": "Select Input Schema",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Select Input Schema": {
      "main": [
        [
          {
            "node": "If - .xlsx",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "validate-normalized-data": {
      "main": [
        [
          {
            "node": "mapping schema",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Reattach Input Schema": {
      "main": [
        [
          {
            "node": "normalization- xlsx",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Reattach Input Schema1": {
      "main": [
        [
          {
            "node": "normalization- xlsx1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "normalization- xlsx1": {
      "main": [
        [
          {
            "node": "validate-normalized-data1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "validate-normalized-data1": {
      "main": [
        [
          {
            "node": "mapping schema1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "mapping schema1": {
      "main": [
        [
          {
            "node": "Convert to File1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert to File1": {
      "main": [
        [
          {
            "node": "Respond to Webhook2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1",
    "binaryMode": "separate",
    "availableInMCP": false
  },
  "versionId": "cb6c338b-db9b-4cf5-a71d-e094aec184d2",
  "id": "kWCdgTDzC2xtw9OWMCRAE",
  "tags": []
}