{
  "id": "CODWF01OrderIngestion",
  "name": "COD · WF-01 Order Ingestion",
  "active": false,
  "nodes": [
    {
      "parameters": {
        "content": "## Layer 1 · Order Ingestion\nAuthenticate and normalize the storefront payload, enrich phone and geography, score fraud risk, select a carrier manifest, reserve stock atomically through the internal API, respond to the store, then dispatch customer/admin notifications.",
        "height": 240,
        "width": 2120,
        "color": 5
      },
      "id": "wf01-note-layer",
      "name": "Layer 1 · Order Ingestion",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -1260,
        -420
      ]
    },
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "orders",
        "authentication": "none",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "wf01-webhook",
      "name": "Store Order Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2.1,
      "position": [
        -1200,
        0
      ],
      "webhookId": "cod-orders-public-v1"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "wf01-auth-key",
              "leftValue": "={{ $json.headers['x-api-key'] || '' }}",
              "rightValue": "={{ $env.ORDER_WEBHOOK_KEY }}",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "wf01-auth",
      "name": "Authenticate Store Webhook Key",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        -1100,
        0
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ { error: 'UNAUTHORIZED' } }}",
        "options": {
          "responseCode": 401
        }
      },
      "id": "wf01-auth-response",
      "name": "Respond Unauthorized",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.5,
      "position": [
        -900,
        180
      ]
    },
    {
      "parameters": {
        "jsCode": "let __smartCodRun;\n(() => {\n  // n8n/code/sanitize.ts\n  var arabicIndic = \"\\u0660\\u0661\\u0662\\u0663\\u0664\\u0665\\u0666\\u0667\\u0668\\u0669\";\n  var easternArabicIndic = \"\\u06F0\\u06F1\\u06F2\\u06F3\\u06F4\\u06F5\\u06F6\\u06F7\\u06F8\\u06F9\";\n  function toAsciiDigits(value) {\n    return [...value].map((character) => {\n      const arabicIndex = arabicIndic.indexOf(character);\n      if (arabicIndex >= 0) return String(arabicIndex);\n      const easternIndex = easternArabicIndic.indexOf(character);\n      return easternIndex >= 0 ? String(easternIndex) : character;\n    }).join(\"\");\n  }\n  function cleanText(value) {\n    return typeof value === \"string\" ? toAsciiDigits(value).replace(/[\\u0000-\\u001f\\u007f]/g, \" \").replace(/\\s+/g, \" \").trim() : \"\";\n  }\n  function cleanOptionalText(value) {\n    const cleaned = cleanText(value);\n    return cleaned || void 0;\n  }\n  function sanitizeOrder(input) {\n    const customer = typeof input.customer === \"object\" && input.customer ? input.customer : {};\n    const shipping = typeof input.shipping === \"object\" && input.shipping ? input.shipping : {};\n    const items = Array.isArray(input.items) ? input.items : [];\n    const sanitizedItems = items.map((item) => {\n      const record = typeof item === \"object\" && item ? item : {};\n      return {\n        sku: cleanText(record.sku).toUpperCase(),\n        qty: Number(record.qty),\n        unitPrice: Number(record.unitPrice),\n        name: cleanOptionalText(record.name)\n      };\n    });\n    const shippingFee = Number(input.shippingFee ?? 0);\n    const discount = Number(input.discount ?? 0);\n    const subtotal = sanitizedItems.reduce((total, item) => total + item.qty * item.unitPrice, 0);\n    return {\n      externalId: cleanOptionalText(input.externalId),\n      source: cleanText(input.source) || \"unknown\",\n      customer: {\n        name: cleanText(customer.name),\n        phone: cleanText(customer.phone),\n        email: cleanOptionalText(customer.email)?.toLowerCase()\n      },\n      shipping: {\n        address: cleanText(shipping.address),\n        city: cleanOptionalText(shipping.city),\n        governorate: cleanOptionalText(shipping.governorate),\n        country: cleanOptionalText(shipping.country)?.toUpperCase()\n      },\n      items: sanitizedItems,\n      subtotal,\n      shippingFee,\n      discount,\n      codAmount: subtotal + shippingFee - discount,\n      currency: (cleanText(input.currency) || \"EGP\").toUpperCase(),\n      notes: cleanOptionalText(input.notes)\n    };\n  }\n  function run(items) {\n    return items.map((item) => {\n      const webhookBody = typeof item.json.body === \"object\" && item.json.body ? item.json.body : item.json;\n      return { ...item, json: sanitizeOrder(webhookBody) };\n    });\n  }\n\n  // sanitize.bundle-entry.ts\n  __smartCodRun = run;\n})();\nreturn __smartCodRun($input.all(), { now: new Date().toISOString() });"
      },
      "id": "wf01-sanitize",
      "name": "Sanitize Phone & Input Data",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -980,
        0
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "wf01-required-name",
              "leftValue": "={{ $json.customer.name }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              }
            },
            {
              "id": "wf01-required-phone",
              "leftValue": "={{ $json.customer.phone }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              }
            },
            {
              "id": "wf01-required-address",
              "leftValue": "={{ $json.shipping.address }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              }
            },
            {
              "id": "wf01-required-items",
              "leftValue": "={{ $json.items.length }}",
              "rightValue": 0,
              "operator": {
                "type": "number",
                "operation": "gt"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "wf01-required",
      "name": "Required Order Fields Present?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        -760,
        0
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ { error: 'VALIDATION_ERROR', details: 'customer.name, customer.phone, shipping.address and at least one item are required' } }}",
        "options": {
          "responseCode": 422
        }
      },
      "id": "wf01-validation-response",
      "name": "Respond Validation Error",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.5,
      "position": [
        -540,
        180
      ]
    },
    {
      "parameters": {
        "jsCode": "let __smartCodRun;\n(() => {\n  // shared/data/phone-rules.json\n  var phone_rules_default = {\n    defaultCountry: \"EG\",\n    genericE164Pattern: \"^\\\\+[1-9]\\\\d{7,14}$\",\n    countries: {\n      EG: {\n        dialCode: \"+20\",\n        localPattern: \"^01[0125]\\\\d{8}$\",\n        e164Pattern: \"^\\\\+201[0125]\\\\d{8}$\",\n        operators: {\n          \"010\": \"Vodafone\",\n          \"011\": \"e&\",\n          \"012\": \"Orange\",\n          \"015\": \"WE\"\n        }\n      },\n      SA: {\n        dialCode: \"+966\",\n        localPattern: \"^05\\\\d{8}$\",\n        e164Pattern: \"^\\\\+9665\\\\d{8}$\",\n        operators: {}\n      },\n      AE: {\n        dialCode: \"+971\",\n        localPattern: \"^05\\\\d{8}$\",\n        e164Pattern: \"^\\\\+9715\\\\d{8}$\",\n        operators: {}\n      },\n      KW: {\n        dialCode: \"+965\",\n        localPattern: \"^[569]\\\\d{7}$\",\n        e164Pattern: \"^\\\\+965[569]\\\\d{7}$\",\n        operators: {}\n      },\n      QA: {\n        dialCode: \"+974\",\n        localPattern: \"^[3567]\\\\d{7}$\",\n        e164Pattern: \"^\\\\+974[3567]\\\\d{7}$\",\n        operators: {}\n      },\n      BH: {\n        dialCode: \"+973\",\n        localPattern: \"^[36]\\\\d{7}$\",\n        e164Pattern: \"^\\\\+973[36]\\\\d{7}$\",\n        operators: {}\n      },\n      OM: {\n        dialCode: \"+968\",\n        localPattern: \"^[79]\\\\d{7}$\",\n        e164Pattern: \"^\\\\+968[79]\\\\d{7}$\",\n        operators: {}\n      }\n    }\n  };\n\n  // n8n/code/sanitize.ts\n  var arabicIndic = \"\\u0660\\u0661\\u0662\\u0663\\u0664\\u0665\\u0666\\u0667\\u0668\\u0669\";\n  var easternArabicIndic = \"\\u06F0\\u06F1\\u06F2\\u06F3\\u06F4\\u06F5\\u06F6\\u06F7\\u06F8\\u06F9\";\n  function toAsciiDigits(value) {\n    return [...value].map((character) => {\n      const arabicIndex = arabicIndic.indexOf(character);\n      if (arabicIndex >= 0) return String(arabicIndex);\n      const easternIndex = easternArabicIndic.indexOf(character);\n      return easternIndex >= 0 ? String(easternIndex) : character;\n    }).join(\"\");\n  }\n\n  // n8n/code/phone.ts\n  var entries = Object.entries(phone_rules_default.countries);\n  function normalizeCountry(value) {\n    const country = value?.trim().toUpperCase();\n    return entries.some(([code]) => code === country) ? country : void 0;\n  }\n  function countryFromDialCode(phone) {\n    return entries.sort(([, left], [, right]) => right.dialCode.length - left.dialCode.length).find(([, rule]) => phone.startsWith(rule.dialCode))?.[0];\n  }\n  function normalizePhone(rawValue, countryHint) {\n    const raw = String(rawValue ?? \"\");\n    let compact = toAsciiDigits(raw).trim().replace(/[\\s().-]/g, \"\");\n    if (compact.startsWith(\"00\")) compact = `+${compact.slice(2)}`;\n    compact = compact.replace(/(?!^)\\+/g, \"\").replace(/[^+\\d]/g, \"\");\n    let country = normalizeCountry(countryHint);\n    if (compact.startsWith(\"+\")) country = countryFromDialCode(compact) ?? country;\n    country ??= phone_rules_default.defaultCountry;\n    const rule = phone_rules_default.countries[country];\n    let normalized = compact;\n    if (!normalized.startsWith(\"+\") && new RegExp(rule.localPattern).test(normalized)) {\n      const national = normalized.startsWith(\"0\") ? normalized.slice(1) : normalized;\n      normalized = `${rule.dialCode}${national}`;\n    } else if (!normalized.startsWith(\"+\") && normalized.startsWith(rule.dialCode.slice(1))) {\n      normalized = `+${normalized}`;\n    }\n    country = countryFromDialCode(normalized) ?? country;\n    const countryRule = phone_rules_default.countries[country];\n    const countryValid = new RegExp(countryRule.e164Pattern).test(normalized);\n    const genericValid = new RegExp(phone_rules_default.genericE164Pattern).test(normalized);\n    const valid = entries.some(([code]) => normalized.startsWith(phone_rules_default.countries[code].dialCode)) ? countryValid : genericValid;\n    let operator = null;\n    if (country === \"EG\" && normalized.startsWith(\"+20\")) {\n      const localPrefix = `0${normalized.slice(3, 5)}`;\n      operator = countryRule.operators[localPrefix] ?? null;\n    }\n    return { raw, normalized, country, valid, operator };\n  }\n  function run(items) {\n    return items.map((item) => {\n      const customer = item.json.customer ?? {};\n      const shipping = item.json.shipping ?? {};\n      const result = normalizePhone(customer.phone ?? item.json.phone, String(shipping.country ?? item.json.country ?? \"\"));\n      return {\n        ...item,\n        json: {\n          ...item.json,\n          customer: { ...customer, phoneE164: result.normalized, telecomOperator: result.operator },\n          phoneValid: result.valid,\n          phoneCountry: result.country\n        }\n      };\n    });\n  }\n\n  // phone.bundle-entry.ts\n  __smartCodRun = run;\n})();\nreturn __smartCodRun($input.all(), { now: new Date().toISOString() });"
      },
      "id": "wf01-phone",
      "name": "Validate Phone Number E.164 Structure",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -540,
        -40
      ]
    },
    {
      "parameters": {
        "jsCode": "let __smartCodRun;\n(() => {\n  // shared/data/eg-governorates.json\n  var eg_governorates_default = [\n    {\n      code: \"CAI\",\n      ar: \"\\u0627\\u0644\\u0642\\u0627\\u0647\\u0631\\u0629\",\n      en: \"Cairo\",\n      aliases: [\"\\u0627\\u0644\\u0642\\u0627\\u0647\\u0631\\u0647\", \"\\u0642\\u0627\\u0647\\u0631\\u0629\", \"cairo\", \"al qahirah\", \"nasr city\", \"\\u0645\\u062F\\u064A\\u0646\\u0629 \\u0646\\u0635\\u0631\", \"\\u0645\\u0635\\u0631 \\u0627\\u0644\\u062C\\u062F\\u064A\\u062F\\u0629\", \"heliopolis\", \"\\u0627\\u0644\\u0645\\u0639\\u0627\\u062F\\u064A\", \"maadi\", \"\\u0627\\u0644\\u062A\\u062C\\u0645\\u0639 \\u0627\\u0644\\u062E\\u0627\\u0645\\u0633\", \"new cairo\", \"\\u0634\\u0628\\u0631\\u0627\", \"\\u062D\\u0644\\u0648\\u0627\\u0646\"],\n      zone: \"METRO\"\n    },\n    {\n      code: \"GIZ\",\n      ar: \"\\u0627\\u0644\\u062C\\u064A\\u0632\\u0629\",\n      en: \"Giza\",\n      aliases: [\"\\u0627\\u0644\\u062C\\u064A\\u0632\\u0647\", \"\\u062C\\u064A\\u0632\\u0629\", \"giza\", \"gizeh\", \"6 october\", \"6th of october\", \"\\u0666 \\u0623\\u0643\\u062A\\u0648\\u0628\\u0631\", \"\\u0627\\u0644\\u0633\\u0627\\u062F\\u0633 \\u0645\\u0646 \\u0623\\u0643\\u062A\\u0648\\u0628\\u0631\", \"\\u0627\\u0644\\u0634\\u064A\\u062E \\u0632\\u0627\\u064A\\u062F\", \"sheikh zayed\", \"\\u0627\\u0644\\u0647\\u0631\\u0645\", \"haram\", \"\\u0627\\u0644\\u062F\\u0642\\u064A\", \"dokki\", \"\\u0627\\u0644\\u0645\\u0647\\u0646\\u062F\\u0633\\u064A\\u0646\"],\n      zone: \"METRO\"\n    },\n    {\n      code: \"ALX\",\n      ar: \"\\u0627\\u0644\\u0625\\u0633\\u0643\\u0646\\u062F\\u0631\\u064A\\u0629\",\n      en: \"Alexandria\",\n      aliases: [\"\\u0627\\u0644\\u0627\\u0633\\u0643\\u0646\\u062F\\u0631\\u064A\\u0629\", \"\\u0627\\u0644\\u0625\\u0633\\u0643\\u0646\\u062F\\u0631\\u064A\\u0647\", \"\\u0627\\u0633\\u0643\\u0646\\u062F\\u0631\\u064A\\u0629\", \"alexandria\", \"alex\", \"\\u0633\\u0645\\u0648\\u062D\\u0629\", \"smouha\", \"\\u0633\\u064A\\u062F\\u064A \\u062C\\u0627\\u0628\\u0631\", \"\\u0627\\u0644\\u0645\\u0646\\u062A\\u0632\\u0629\", \"\\u0627\\u0644\\u0639\\u062C\\u0645\\u064A\", \"borg el arab\", \"\\u0628\\u0631\\u062C \\u0627\\u0644\\u0639\\u0631\\u0628\"],\n      zone: \"METRO\"\n    },\n    {\n      code: \"DK\",\n      ar: \"\\u0627\\u0644\\u062F\\u0642\\u0647\\u0644\\u064A\\u0629\",\n      en: \"Dakahlia\",\n      aliases: [\"\\u0627\\u0644\\u062F\\u0642\\u0647\\u0644\\u064A\\u0647\", \"dakahlia\", \"dakhelya\", \"\\u0627\\u0644\\u0645\\u0646\\u0635\\u0648\\u0631\\u0629\", \"mansoura\", \"\\u0637\\u0644\\u062E\\u0627\", \"talkha\", \"\\u0645\\u064A\\u062A \\u063A\\u0645\\u0631\"],\n      zone: \"REGIONAL\"\n    },\n    {\n      code: \"BA\",\n      ar: \"\\u0627\\u0644\\u0628\\u062D\\u0631 \\u0627\\u0644\\u0623\\u062D\\u0645\\u0631\",\n      en: \"Red Sea\",\n      aliases: [\"\\u0627\\u0644\\u0628\\u062D\\u0631 \\u0627\\u0644\\u0627\\u062D\\u0645\\u0631\", \"red sea\", \"\\u0627\\u0644\\u063A\\u0631\\u062F\\u0642\\u0629\", \"hurghada\", \"\\u0633\\u0641\\u0627\\u062C\\u0627\", \"\\u0645\\u0631\\u0633\\u0649 \\u0639\\u0644\\u0645\", \"marsa alam\"],\n      zone: \"REGIONAL\"\n    },\n    {\n      code: \"BH\",\n      ar: \"\\u0627\\u0644\\u0628\\u062D\\u064A\\u0631\\u0629\",\n      en: \"Beheira\",\n      aliases: [\"\\u0627\\u0644\\u0628\\u062D\\u064A\\u0631\\u0647\", \"beheira\", \"behera\", \"\\u062F\\u0645\\u0646\\u0647\\u0648\\u0631\", \"damanhur\", \"\\u0643\\u0641\\u0631 \\u0627\\u0644\\u062F\\u0648\\u0627\\u0631\", \"\\u0631\\u0634\\u064A\\u062F\"],\n      zone: \"REGIONAL\"\n    },\n    {\n      code: \"FYM\",\n      ar: \"\\u0627\\u0644\\u0641\\u064A\\u0648\\u0645\",\n      en: \"Fayoum\",\n      aliases: [\"\\u0627\\u0644\\u0641\\u064A\\u0648\\u0645\", \"\\u0641\\u064A\\u0648\\u0645\", \"fayoum\", \"faiyum\", \"\\u0633\\u0646\\u0648\\u0631\\u0633\", \"\\u0625\\u0637\\u0633\\u0627\"],\n      zone: \"REGIONAL\"\n    },\n    {\n      code: \"GH\",\n      ar: \"\\u0627\\u0644\\u063A\\u0631\\u0628\\u064A\\u0629\",\n      en: \"Gharbia\",\n      aliases: [\"\\u0627\\u0644\\u063A\\u0631\\u0628\\u064A\\u0647\", \"gharbia\", \"\\u0637\\u0646\\u0637\\u0627\", \"tanta\", \"\\u0627\\u0644\\u0645\\u062D\\u0644\\u0629 \\u0627\\u0644\\u0643\\u0628\\u0631\\u0649\", \"mahalla\", \"\\u0632\\u0641\\u062A\\u0649\"],\n      zone: \"REGIONAL\"\n    },\n    {\n      code: \"IS\",\n      ar: \"\\u0627\\u0644\\u0625\\u0633\\u0645\\u0627\\u0639\\u064A\\u0644\\u064A\\u0629\",\n      en: \"Ismailia\",\n      aliases: [\"\\u0627\\u0644\\u0627\\u0633\\u0645\\u0627\\u0639\\u064A\\u0644\\u064A\\u0629\", \"\\u0627\\u0644\\u0625\\u0633\\u0645\\u0627\\u0639\\u064A\\u0644\\u064A\\u0647\", \"ismailia\", \"\\u0627\\u0644\\u062A\\u0644 \\u0627\\u0644\\u0643\\u0628\\u064A\\u0631\", \"\\u0641\\u0627\\u064A\\u062F\"],\n      zone: \"REGIONAL\"\n    },\n    {\n      code: \"MNF\",\n      ar: \"\\u0627\\u0644\\u0645\\u0646\\u0648\\u0641\\u064A\\u0629\",\n      en: \"Monufia\",\n      aliases: [\"\\u0627\\u0644\\u0645\\u0646\\u0648\\u0641\\u064A\\u0647\", \"\\u0627\\u0644\\u0645\\u0646\\u0648\\u0641\\u064A\\u0629\", \"monufia\", \"menofia\", \"\\u0634\\u0628\\u064A\\u0646 \\u0627\\u0644\\u0643\\u0648\\u0645\", \"shebin el kom\", \"\\u0645\\u0646\\u0648\\u0641\", \"\\u0627\\u0644\\u0633\\u0627\\u062F\\u0627\\u062A\"],\n      zone: \"REGIONAL\"\n    },\n    {\n      code: \"MN\",\n      ar: \"\\u0627\\u0644\\u0645\\u0646\\u064A\\u0627\",\n      en: \"Minya\",\n      aliases: [\"\\u0627\\u0644\\u0645\\u0646\\u064A\\u0627\", \"\\u0645\\u0646\\u064A\\u0627\", \"minya\", \"\\u0645\\u0644\\u0648\\u064A\", \"mallawi\", \"\\u0633\\u0645\\u0627\\u0644\\u0648\\u0637\", \"\\u0628\\u0646\\u064A \\u0645\\u0632\\u0627\\u0631\"],\n      zone: \"REGIONAL\"\n    },\n    {\n      code: \"KB\",\n      ar: \"\\u0627\\u0644\\u0642\\u0644\\u064A\\u0648\\u0628\\u064A\\u0629\",\n      en: \"Qalyubia\",\n      aliases: [\"\\u0627\\u0644\\u0642\\u0644\\u064A\\u0648\\u0628\\u064A\\u0647\", \"qalyubia\", \"qaliubiya\", \"\\u0628\\u0646\\u0647\\u0627\", \"banha\", \"\\u0634\\u0628\\u0631\\u0627 \\u0627\\u0644\\u062E\\u064A\\u0645\\u0629\", \"\\u0627\\u0644\\u0639\\u0628\\u0648\\u0631\", \"\\u0627\\u0644\\u062E\\u0627\\u0646\\u0643\\u0629\"],\n      zone: \"REGIONAL\"\n    },\n    {\n      code: \"WAD\",\n      ar: \"\\u0627\\u0644\\u0648\\u0627\\u062F\\u064A \\u0627\\u0644\\u062C\\u062F\\u064A\\u062F\",\n      en: \"New Valley\",\n      aliases: [\"\\u0627\\u0644\\u0648\\u0627\\u062F\\u0649 \\u0627\\u0644\\u062C\\u062F\\u064A\\u062F\", \"new valley\", \"el wadi el gedid\", \"\\u0627\\u0644\\u062E\\u0627\\u0631\\u062C\\u0629\", \"kharga\", \"\\u0627\\u0644\\u062F\\u0627\\u062E\\u0644\\u0629\"],\n      zone: \"REGIONAL\"\n    },\n    {\n      code: \"SUZ\",\n      ar: \"\\u0627\\u0644\\u0633\\u0648\\u064A\\u0633\",\n      en: \"Suez\",\n      aliases: [\"\\u0627\\u0644\\u0633\\u0648\\u064A\\u0633\", \"\\u0633\\u0648\\u064A\\u0633\", \"suez\", \"\\u0627\\u0644\\u0639\\u064A\\u0646 \\u0627\\u0644\\u0633\\u062E\\u0646\\u0629\", \"ain sokhna\"],\n      zone: \"REGIONAL\"\n    },\n    {\n      code: \"ASN\",\n      ar: \"\\u0623\\u0633\\u0648\\u0627\\u0646\",\n      en: \"Aswan\",\n      aliases: [\"\\u0627\\u0633\\u0648\\u0627\\u0646\", \"aswan\", \"\\u0625\\u062F\\u0641\\u0648\", \"edfu\", \"\\u0643\\u0648\\u0645 \\u0623\\u0645\\u0628\\u0648\", \"\\u0646\\u0635\\u0631 \\u0627\\u0644\\u0646\\u0648\\u0628\\u0629\"],\n      zone: \"REGIONAL\"\n    },\n    {\n      code: \"AST\",\n      ar: \"\\u0623\\u0633\\u064A\\u0648\\u0637\",\n      en: \"Assiut\",\n      aliases: [\"\\u0627\\u0633\\u064A\\u0648\\u0637\", \"\\u0623\\u0633\\u064A\\u0648\\u0637\", \"assiut\", \"asyut\", \"\\u062F\\u064A\\u0631\\u0648\\u0637\", \"\\u0645\\u0646\\u0641\\u0644\\u0648\\u0637\", \"\\u0627\\u0644\\u0642\\u0648\\u0635\\u064A\\u0629\"],\n      zone: \"REGIONAL\"\n    },\n    {\n      code: \"BNS\",\n      ar: \"\\u0628\\u0646\\u064A \\u0633\\u0648\\u064A\\u0641\",\n      en: \"Beni Suef\",\n      aliases: [\"\\u0628\\u0646\\u0649 \\u0633\\u0648\\u064A\\u0641\", \"beni suef\", \"bani suwayf\", \"\\u0627\\u0644\\u0648\\u0627\\u0633\\u0637\\u0649\", \"\\u0628\\u0628\\u0627\", \"\\u0646\\u0627\\u0635\\u0631 \\u0628\\u0646\\u064A \\u0633\\u0648\\u064A\\u0641\"],\n      zone: \"REGIONAL\"\n    },\n    {\n      code: \"PTS\",\n      ar: \"\\u0628\\u0648\\u0631\\u0633\\u0639\\u064A\\u062F\",\n      en: \"Port Said\",\n      aliases: [\"\\u0628\\u0648\\u0631\\u062A \\u0633\\u0639\\u064A\\u062F\", \"port said\", \"portsaid\", \"\\u0628\\u0648\\u0631 \\u0641\\u0624\\u0627\\u062F\"],\n      zone: \"REGIONAL\"\n    },\n    {\n      code: \"DT\",\n      ar: \"\\u062F\\u0645\\u064A\\u0627\\u0637\",\n      en: \"Damietta\",\n      aliases: [\"\\u062F\\u0645\\u064A\\u0627\\u0637\", \"damietta\", \"domyat\", \"\\u0631\\u0623\\u0633 \\u0627\\u0644\\u0628\\u0631\", \"ras el bar\", \"\\u062F\\u0645\\u064A\\u0627\\u0637 \\u0627\\u0644\\u062C\\u062F\\u064A\\u062F\\u0629\", \"\\u0643\\u0641\\u0631 \\u0633\\u0639\\u062F\"],\n      zone: \"REGIONAL\"\n    },\n    {\n      code: \"SHR\",\n      ar: \"\\u0627\\u0644\\u0634\\u0631\\u0642\\u064A\\u0629\",\n      en: \"Sharqia\",\n      aliases: [\"\\u0627\\u0644\\u0634\\u0631\\u0642\\u064A\\u0647\", \"sharqia\", \"sharkia\", \"\\u0627\\u0644\\u0632\\u0642\\u0627\\u0632\\u064A\\u0642\", \"zagazig\", \"\\u0627\\u0644\\u0639\\u0627\\u0634\\u0631 \\u0645\\u0646 \\u0631\\u0645\\u0636\\u0627\\u0646\", \"10th of ramadan\", \"\\u0628\\u0644\\u0628\\u064A\\u0633\", \"\\u0645\\u0646\\u064A\\u0627 \\u0627\\u0644\\u0642\\u0645\\u062D\"],\n      zone: \"REGIONAL\"\n    },\n    {\n      code: \"JS\",\n      ar: \"\\u062C\\u0646\\u0648\\u0628 \\u0633\\u064A\\u0646\\u0627\\u0621\",\n      en: \"South Sinai\",\n      aliases: [\"\\u062C\\u0646\\u0648\\u0628 \\u0633\\u064A\\u0646\\u0627\", \"south sinai\", \"\\u0634\\u0631\\u0645 \\u0627\\u0644\\u0634\\u064A\\u062E\", \"sharm el sheikh\", \"\\u062F\\u0647\\u0628\", \"dahab\", \"\\u0637\\u0648\\u0631 \\u0633\\u064A\\u0646\\u0627\\u0621\", \"\\u0646\\u0648\\u064A\\u0628\\u0639\"],\n      zone: \"REGIONAL\"\n    },\n    {\n      code: \"KFS\",\n      ar: \"\\u0643\\u0641\\u0631 \\u0627\\u0644\\u0634\\u064A\\u062E\",\n      en: \"Kafr El Sheikh\",\n      aliases: [\"\\u0643\\u0641\\u0631 \\u0627\\u0644\\u0634\\u064A\\u062E\", \"kafr el sheikh\", \"kafr al shaykh\", \"\\u062F\\u0633\\u0648\\u0642\", \"desouk\", \"\\u0628\\u0644\\u0637\\u064A\\u0645\", \"\\u0641\\u0648\\u0647\"],\n      zone: \"REGIONAL\"\n    },\n    {\n      code: \"MT\",\n      ar: \"\\u0645\\u0637\\u0631\\u0648\\u062D\",\n      en: \"Matrouh\",\n      aliases: [\"\\u0645\\u0631\\u0633\\u0649 \\u0645\\u0637\\u0631\\u0648\\u062D\", \"matrouh\", \"marsa matruh\", \"\\u0627\\u0644\\u0633\\u0627\\u062D\\u0644 \\u0627\\u0644\\u0634\\u0645\\u0627\\u0644\\u064A\", \"north coast\", \"\\u0627\\u0644\\u0639\\u0644\\u0645\\u064A\\u0646\", \"alamein\", \"\\u0633\\u064A\\u0648\\u0629\"],\n      zone: \"REGIONAL\"\n    },\n    {\n      code: \"LX\",\n      ar: \"\\u0627\\u0644\\u0623\\u0642\\u0635\\u0631\",\n      en: \"Luxor\",\n      aliases: [\"\\u0627\\u0644\\u0627\\u0642\\u0635\\u0631\", \"\\u0623\\u0642\\u0635\\u0631\", \"luxor\", \"\\u0627\\u0644\\u0642\\u0631\\u0646\\u0629\", \"\\u0625\\u0633\\u0646\\u0627\", \"esna\"],\n      zone: \"REGIONAL\"\n    },\n    {\n      code: \"KN\",\n      ar: \"\\u0642\\u0646\\u0627\",\n      en: \"Qena\",\n      aliases: [\"\\u0642\\u0646\\u0627\", \"qena\", \"kina\", \"\\u0646\\u062C\\u0639 \\u062D\\u0645\\u0627\\u062F\\u064A\", \"nag hammadi\", \"\\u0642\\u0648\\u0635\", \"\\u062F\\u0634\\u0646\\u0627\"],\n      zone: \"REGIONAL\"\n    },\n    {\n      code: \"SIN\",\n      ar: \"\\u0634\\u0645\\u0627\\u0644 \\u0633\\u064A\\u0646\\u0627\\u0621\",\n      en: \"North Sinai\",\n      aliases: [\"\\u0634\\u0645\\u0627\\u0644 \\u0633\\u064A\\u0646\\u0627\", \"north sinai\", \"\\u0627\\u0644\\u0639\\u0631\\u064A\\u0634\", \"arish\", \"\\u0628\\u0626\\u0631 \\u0627\\u0644\\u0639\\u0628\\u062F\", \"\\u0631\\u0641\\u062D\"],\n      zone: \"REGIONAL\"\n    },\n    {\n      code: \"SHG\",\n      ar: \"\\u0633\\u0648\\u0647\\u0627\\u062C\",\n      en: \"Sohag\",\n      aliases: [\"\\u0633\\u0648\\u0647\\u0627\\u062C\", \"sohag\", \"suhag\", \"\\u0623\\u062E\\u0645\\u064A\\u0645\", \"akhmim\", \"\\u0637\\u0647\\u0637\\u0627\", \"\\u062C\\u0631\\u062C\\u0627\"],\n      zone: \"REGIONAL\"\n    }\n  ];\n\n  // shared/data/gulf-countries.json\n  var gulf_countries_default = [\n    {\n      code: \"SA\",\n      dialCode: \"+966\",\n      ar: \"\\u0627\\u0644\\u0645\\u0645\\u0644\\u0643\\u0629 \\u0627\\u0644\\u0639\\u0631\\u0628\\u064A\\u0629 \\u0627\\u0644\\u0633\\u0639\\u0648\\u062F\\u064A\\u0629\",\n      en: \"Saudi Arabia\",\n      aliases: [\"\\u0627\\u0644\\u0633\\u0639\\u0648\\u062F\\u064A\\u0629\", \"\\u0627\\u0644\\u0633\\u0639\\u0648\\u062F\\u064A\\u0647\", \"ksa\", \"saudi\", \"saudi arabia\", \"riyadh\", \"\\u0627\\u0644\\u0631\\u064A\\u0627\\u0636\", \"jeddah\", \"\\u062C\\u062F\\u0629\"],\n      zone: \"GULF\"\n    },\n    {\n      code: \"AE\",\n      dialCode: \"+971\",\n      ar: \"\\u0627\\u0644\\u0625\\u0645\\u0627\\u0631\\u0627\\u062A \\u0627\\u0644\\u0639\\u0631\\u0628\\u064A\\u0629 \\u0627\\u0644\\u0645\\u062A\\u062D\\u062F\\u0629\",\n      en: \"United Arab Emirates\",\n      aliases: [\"\\u0627\\u0644\\u0625\\u0645\\u0627\\u0631\\u0627\\u062A\", \"\\u0627\\u0644\\u0627\\u0645\\u0627\\u0631\\u0627\\u062A\", \"uae\", \"emirates\", \"dubai\", \"\\u062F\\u0628\\u064A\", \"abu dhabi\", \"\\u0623\\u0628\\u0648\\u0638\\u0628\\u064A\", \"sharjah\", \"\\u0627\\u0644\\u0634\\u0627\\u0631\\u0642\\u0629\"],\n      zone: \"GULF\"\n    },\n    {\n      code: \"KW\",\n      dialCode: \"+965\",\n      ar: \"\\u0627\\u0644\\u0643\\u0648\\u064A\\u062A\",\n      en: \"Kuwait\",\n      aliases: [\"\\u0627\\u0644\\u0643\\u0648\\u064A\\u062A\", \"kuwait\", \"kuwait city\", \"\\u0645\\u062F\\u064A\\u0646\\u0629 \\u0627\\u0644\\u0643\\u0648\\u064A\\u062A\"],\n      zone: \"GULF\"\n    },\n    {\n      code: \"QA\",\n      dialCode: \"+974\",\n      ar: \"\\u0642\\u0637\\u0631\",\n      en: \"Qatar\",\n      aliases: [\"\\u0642\\u0637\\u0631\", \"qatar\", \"doha\", \"\\u0627\\u0644\\u062F\\u0648\\u062D\\u0629\"],\n      zone: \"GULF\"\n    },\n    {\n      code: \"BH\",\n      dialCode: \"+973\",\n      ar: \"\\u0627\\u0644\\u0628\\u062D\\u0631\\u064A\\u0646\",\n      en: \"Bahrain\",\n      aliases: [\"\\u0627\\u0644\\u0628\\u062D\\u0631\\u064A\\u0646\", \"bahrain\", \"manama\", \"\\u0627\\u0644\\u0645\\u0646\\u0627\\u0645\\u0629\"],\n      zone: \"GULF\"\n    },\n    {\n      code: \"OM\",\n      dialCode: \"+968\",\n      ar: \"\\u0633\\u0644\\u0637\\u0646\\u0629 \\u0639\\u0645\\u0627\\u0646\",\n      en: \"Oman\",\n      aliases: [\"\\u0639\\u0645\\u0627\\u0646\", \"\\u0633\\u0644\\u0637\\u0646\\u0629 \\u0639\\u0645\\u0627\\u0646\", \"oman\", \"muscat\", \"\\u0645\\u0633\\u0642\\u0637\"],\n      zone: \"GULF\"\n    }\n  ];\n\n  // n8n/code/sanitize.ts\n  var arabicIndic = \"\\u0660\\u0661\\u0662\\u0663\\u0664\\u0665\\u0666\\u0667\\u0668\\u0669\";\n  var easternArabicIndic = \"\\u06F0\\u06F1\\u06F2\\u06F3\\u06F4\\u06F5\\u06F6\\u06F7\\u06F8\\u06F9\";\n  function toAsciiDigits(value) {\n    return [...value].map((character) => {\n      const arabicIndex = arabicIndic.indexOf(character);\n      if (arabicIndex >= 0) return String(arabicIndex);\n      const easternIndex = easternArabicIndic.indexOf(character);\n      return easternIndex >= 0 ? String(easternIndex) : character;\n    }).join(\"\");\n  }\n\n  // n8n/code/geo.ts\n  function searchable(value) {\n    return toAsciiDigits(String(value ?? \"\")).toLowerCase().normalize(\"NFKD\").replace(/[\\u064b-\\u065f\\u0670]/g, \"\").replace(/[إأآ]/g, \"\\u0627\").replace(/ى/g, \"\\u064A\").replace(/ة/g, \"\\u0647\").replace(/[^\\p{L}\\p{N}]+/gu, \" \").replace(/\\s+/g, \" \").trim();\n  }\n  function containsTerm(haystack, term) {\n    const normalizedTerm = searchable(term);\n    return normalizedTerm.length > 0 && ` ${haystack} `.includes(` ${normalizedTerm} `);\n  }\n  function explicitCountryCode(value) {\n    const raw = String(value ?? \"\").trim();\n    if (/^[a-z]{2}$/i.test(raw)) return raw.toUpperCase();\n    const normalized = searchable(raw);\n    if (!normalized) return void 0;\n    if (normalized === \"eg\" || normalized === \"egypt\" || normalized === \"\\u0645\\u0635\\u0631\") return \"EG\";\n    return gulf_countries_default.find(\n      (country) => normalized === country.code.toLowerCase() || normalized === searchable(country.ar) || normalized === searchable(country.en) || country.aliases.some((alias) => normalized === searchable(alias))\n    )?.code;\n  }\n  function countryFromText(text) {\n    if ([\"\\u0645\\u0635\\u0631\", \"egypt\", \"cairo\", \"\\u0627\\u0644\\u0642\\u0627\\u0647\\u0631\\u0647\", \"giza\", \"\\u0627\\u0644\\u062C\\u064A\\u0632\\u0647\", \"alexandria\", \"\\u0627\\u0644\\u0627\\u0633\\u0643\\u0646\\u062F\\u0631\\u064A\\u0647\"].some((term) => containsTerm(text, term))) return \"EG\";\n    return gulf_countries_default.find(\n      (country) => [country.ar, country.en, ...country.aliases].some((term) => containsTerm(text, term))\n    )?.code;\n  }\n  function countryFromPhone(phone) {\n    const value = String(phone ?? \"\").replace(/\\s/g, \"\");\n    if (value.startsWith(\"+20\")) return \"EG\";\n    return gulf_countries_default.find((country) => value.startsWith(country.dialCode))?.code;\n  }\n  function parseGeo(input) {\n    const locationText = searchable([input.governorate, input.city, input.address].filter(Boolean).join(\" \"));\n    const country = explicitCountryCode(input.country) ?? countryFromText(locationText) ?? countryFromPhone(input.phoneE164) ?? \"EG\";\n    const governorateMatch = country === \"EG\" ? eg_governorates_default.flatMap((candidate) => [candidate.ar, candidate.en, ...candidate.aliases].map((term) => ({ candidate, term }))).sort((left, right) => searchable(right.term).length - searchable(left.term).length).find(({ term }) => containsTerm(locationText, term)) : void 0;\n    const governorate = governorateMatch?.candidate;\n    const inferredCity = governorate ? [...governorate.aliases].filter((alias) => searchable(alias) !== searchable(governorate.ar) && searchable(alias) !== searchable(governorate.en)).sort((left, right) => searchable(right).length - searchable(left).length).find((alias) => containsTerm(locationText, alias)) : void 0;\n    const gulfCountry = gulf_countries_default.find((candidate) => candidate.code === country);\n    const zone = governorate?.zone ?? (gulfCountry ? \"GULF\" : country === \"EG\" ? \"REGIONAL\" : \"INTL\");\n    return {\n      country,\n      governorate: governorate ? { code: governorate.code, ar: governorate.ar, en: governorate.en } : null,\n      city: String(input.city ?? \"\").trim() || inferredCity || governorateMatch?.term || null,\n      zone\n    };\n  }\n  function run(items) {\n    return items.map((item) => {\n      const customer = item.json.customer ?? {};\n      const shipping = item.json.shipping ?? {};\n      const geo = parseGeo({\n        address: shipping.address ?? item.json.address,\n        city: shipping.city ?? item.json.city,\n        governorate: shipping.governorate ?? item.json.governorate,\n        country: shipping.country ?? item.json.country,\n        phoneE164: customer.phoneE164 ?? item.json.phoneE164\n      });\n      return { ...item, json: { ...item.json, geo } };\n    });\n  }\n\n  // geo.bundle-entry.ts\n  __smartCodRun = run;\n})();\nreturn __smartCodRun($input.all(), { now: new Date().toISOString() });"
      },
      "id": "wf01-geo",
      "name": "Parse Governorate & City Geo-Location",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -300,
        -40
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "wf01-address-line",
              "name": "addressLine",
              "value": "={{ $json.shipping.address }}",
              "type": "string"
            },
            {
              "id": "wf01-city",
              "name": "city",
              "value": "={{ $json.geo.city || $json.shipping.city || '' }}",
              "type": "string"
            },
            {
              "id": "wf01-governorate",
              "name": "governorate",
              "value": "={{ $json.geo.governorate?.ar || $json.shipping.governorate || '' }}",
              "type": "string"
            },
            {
              "id": "wf01-country",
              "name": "country",
              "value": "={{ $json.geo.country }}",
              "type": "string"
            },
            {
              "id": "wf01-zone",
              "name": "zone",
              "value": "={{ $json.geo.zone }}",
              "type": "string"
            },
            {
              "id": "wf01-normalized-address",
              "name": "addressNormalized",
              "value": "={{ [$json.shipping.address, $json.geo.city, $json.geo.governorate?.ar].filter(Boolean).join(' ') }}",
              "type": "string"
            }
          ]
        },
        "includeOtherFields": true,
        "options": {}
      },
      "id": "wf01-address",
      "name": "Enrich Address Details",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -60,
        -40
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "wf01-operator",
              "name": "telecomOperator",
              "value": "={{ $json.customer.telecomOperator || 'Unknown' }}",
              "type": "string"
            }
          ]
        },
        "includeOtherFields": true,
        "options": {}
      },
      "id": "wf01-operator-node",
      "name": "Detect Telecom Operator",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        180,
        -40
      ]
    },
    {
      "parameters": {
        "url": "={{ $env.INTERNAL_API_URL }}/api/internal/settings",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "timeout": 10000
        }
      },
      "id": "wf01-settings",
      "name": "Fetch Store Settings",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        420,
        -40
      ],
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 1000,
      "credentials": {
        "httpHeaderAuth": {
          "id": "cred_internal_api",
          "name": "COD Internal API Bearer"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "={{ $env.INTERNAL_API_URL }}/api/internal/risk-context",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={{ JSON.stringify({ phoneE164: $('Detect Telecom Operator').item.json.customer.phoneE164, addressNormalized: $('Detect Telecom Operator').item.json.addressNormalized, name: $('Detect Telecom Operator').item.json.customer.name, ...($('Detect Telecom Operator').item.json.customer.email ? { email: $('Detect Telecom Operator').item.json.customer.email } : {}) }) }}",
        "options": {
          "timeout": 10000
        }
      },
      "id": "wf01-risk-context",
      "name": "Fetch Risk Context (Dup, Blacklist, History)",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        660,
        -40
      ],
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 1000,
      "credentials": {
        "httpHeaderAuth": {
          "id": "cred_internal_api",
          "name": "COD Internal API Bearer"
        }
      }
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "wf01-merge-customer",
              "name": "customer",
              "value": "={{ $('Detect Telecom Operator').item.json.customer }}",
              "type": "object"
            },
            {
              "id": "wf01-merge-shipping",
              "name": "shipping",
              "value": "={{ $('Detect Telecom Operator').item.json.shipping }}",
              "type": "object"
            },
            {
              "id": "wf01-merge-items",
              "name": "items",
              "value": "={{ $('Detect Telecom Operator').item.json.items }}",
              "type": "array"
            },
            {
              "id": "wf01-merge-original",
              "name": "orderInput",
              "value": "={{ $('Detect Telecom Operator').item.json }}",
              "type": "object"
            },
            {
              "id": "wf01-merge-geo",
              "name": "geo",
              "value": "={{ $('Detect Telecom Operator').item.json.geo }}",
              "type": "object"
            },
            {
              "id": "wf01-merge-settings",
              "name": "settings",
              "value": "={{ $('Fetch Store Settings').item.json }}",
              "type": "object"
            },
            {
              "id": "wf01-merge-risk-context",
              "name": "riskContext",
              "value": "={{ $json }}",
              "type": "object"
            },
            {
              "id": "wf01-merge-phone-valid",
              "name": "phoneValid",
              "value": "={{ $('Detect Telecom Operator').item.json.phoneValid }}",
              "type": "boolean"
            },
            {
              "id": "wf01-merge-cod",
              "name": "codAmount",
              "value": "={{ $('Detect Telecom Operator').item.json.codAmount }}",
              "type": "number"
            }
          ]
        },
        "options": {}
      },
      "id": "wf01-context-merge",
      "name": "Merge Order, Settings & Risk Context",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        900,
        -40
      ]
    },
    {
      "parameters": {
        "jsCode": "let __smartCodRun;\n(() => {\n  // n8n/code/risk-score.ts\n  var labels = {\n    PHONE_BLACKLISTED: [\"\\u0631\\u0642\\u0645 \\u0627\\u0644\\u0647\\u0627\\u062A\\u0641 \\u0641\\u064A \\u0642\\u0627\\u0626\\u0645\\u0629 \\u0627\\u0644\\u062D\\u0638\\u0631\", \"Phone is blacklisted\"],\n    PHONE_INVALID: [\"\\u0631\\u0642\\u0645 \\u0627\\u0644\\u0647\\u0627\\u062A\\u0641 \\u063A\\u064A\\u0631 \\u0635\\u0627\\u0644\\u062D\", \"Phone is invalid\"],\n    ADDRESS_BLACKLISTED: [\"\\u0627\\u0644\\u0639\\u0646\\u0648\\u0627\\u0646 \\u064A\\u062D\\u062A\\u0648\\u064A \\u0639\\u0644\\u0649 \\u0639\\u0628\\u0627\\u0631\\u0629 \\u0645\\u062D\\u0638\\u0648\\u0631\\u0629\", \"Address contains a blocked keyword\"],\n    NAME_BLACKLISTED: [\"\\u0627\\u0644\\u0627\\u0633\\u0645 \\u0641\\u064A \\u0642\\u0627\\u0626\\u0645\\u0629 \\u0627\\u0644\\u062D\\u0638\\u0631\", \"Name is blacklisted\"],\n    DUPLICATE_30M: [\"\\u0637\\u0644\\u0628 \\u0645\\u0643\\u0631\\u0631 \\u062E\\u0644\\u0627\\u0644 30 \\u062F\\u0642\\u064A\\u0642\\u0629\", \"Duplicate order within 30 minutes\"],\n    BAD_HISTORY_2_PLUS: [\"\\u0637\\u0644\\u0628\\u0627\\u0646 \\u0645\\u0644\\u063A\\u064A\\u0627\\u0646 \\u0623\\u0648 \\u0645\\u0631\\u062A\\u062C\\u0639\\u0627\\u0646 \\u0633\\u0627\\u0628\\u0642\\u064B\\u0627\", \"Two or more prior cancellations/returns\"],\n    BAD_HISTORY_1: [\"\\u0637\\u0644\\u0628 \\u0645\\u0644\\u063A\\u064A \\u0623\\u0648 \\u0645\\u0631\\u062A\\u062C\\u0639 \\u0633\\u0627\\u0628\\u0642\\u064B\\u0627\", \"One prior cancellation/return\"],\n    SUSPICIOUS_DIGITS: [\"\\u0631\\u0642\\u0645 \\u0627\\u0644\\u0647\\u0627\\u062A\\u0641 \\u064A\\u062D\\u062A\\u0648\\u064A \\u0623\\u0631\\u0642\\u0627\\u0645\\u064B\\u0627 \\u0645\\u062A\\u0643\\u0631\\u0631\\u0629 \\u0623\\u0648 \\u0645\\u062A\\u0633\\u0644\\u0633\\u0644\\u0629\", \"Phone contains repeated or sequential digits\"],\n    FAKE_NAME: [\"\\u0627\\u0644\\u0627\\u0633\\u0645 \\u064A\\u0628\\u062F\\u0648 \\u063A\\u064A\\u0631 \\u062D\\u0642\\u064A\\u0642\\u064A\", \"Name appears fake\"],\n    INCOMPLETE_ADDRESS: [\"\\u0627\\u0644\\u0639\\u0646\\u0648\\u0627\\u0646 \\u0642\\u0635\\u064A\\u0631 \\u0623\\u0648 \\u0627\\u0644\\u0645\\u0648\\u0642\\u0639 \\u063A\\u064A\\u0631 \\u0645\\u0643\\u062A\\u0645\\u0644\", \"Address is short or location is incomplete\"],\n    HIGH_VALUE_FIRST_ORDER: [\"\\u0623\\u0648\\u0644 \\u0637\\u0644\\u0628 \\u0628\\u0642\\u064A\\u0645\\u0629 \\u0645\\u0631\\u062A\\u0641\\u0639\\u0629\", \"High-value first order\"],\n    HIGH_QUANTITY: [\"\\u0643\\u0645\\u064A\\u0629 \\u0645\\u0631\\u062A\\u0641\\u0639\\u0629 \\u0644\\u0645\\u0646\\u062A\\u062C \\u0648\\u0627\\u062D\\u062F\", \"High quantity for one SKU\"],\n    DELIVERED_HISTORY: [\"\\u0644\\u0644\\u0639\\u0645\\u064A\\u0644 \\u0637\\u0644\\u0628 \\u0645\\u0633\\u062A\\u0644\\u0645 \\u0633\\u0627\\u0628\\u0642\\u064B\\u0627\", \"Customer has a delivered order\"],\n    TELEGRAM_LINKED: [\"\\u062D\\u0633\\u0627\\u0628 \\u062A\\u064A\\u0644\\u064A\\u062C\\u0631\\u0627\\u0645 \\u0645\\u0631\\u062A\\u0628\\u0637\", \"Telegram is linked\"]\n  };\n  function reason(code, points) {\n    const [labelAr, labelEn] = labels[code];\n    return { code, points, labelAr, labelEn };\n  }\n  function hasSuspiciousDigits(phone) {\n    const digits = String(phone ?? \"\").replace(/\\D/g, \"\");\n    if (/(\\d)\\1{5,}/.test(digits)) return true;\n    const sequences = [\"0123456789\", \"1234567890\", \"9876543210\", \"0987654321\"];\n    return sequences.some((sequence) => {\n      for (let length = 6; length <= sequence.length; length += 1) {\n        for (let start = 0; start + length <= sequence.length; start += 1) {\n          if (digits.includes(sequence.slice(start, start + length))) return true;\n        }\n      }\n      return false;\n    });\n  }\n  function isFakeName(name) {\n    const normalized = name.toLowerCase().replace(/[^\\p{L}\\p{N}]/gu, \"\");\n    const letters = normalized.replace(/[^\\p{L}]/gu, \"\");\n    return letters.length < 3 || /\\d/.test(normalized) || /(test|asdf|qwerty|fake|تجربه|اختبار)/iu.test(normalized) || /(.)\\1{4,}/u.test(normalized);\n  }\n  function scoreRisk(input) {\n    const reasons = [];\n    const add = (code, points) => reasons.push(reason(code, points));\n    const badHistory = input.context.history.cancelled + input.context.history.returned;\n    if (input.context.blacklist.phone) add(\"PHONE_BLACKLISTED\", 100);\n    if (!input.phoneValid) add(\"PHONE_INVALID\", 40);\n    if (input.context.blacklist.addressKeyword) add(\"ADDRESS_BLACKLISTED\", 40);\n    if (input.context.blacklist.name) add(\"NAME_BLACKLISTED\", 20);\n    if (input.context.duplicates30m > 0) add(\"DUPLICATE_30M\", 30);\n    if (badHistory >= 2) add(\"BAD_HISTORY_2_PLUS\", 25);\n    else if (badHistory === 1) add(\"BAD_HISTORY_1\", 10);\n    if (hasSuspiciousDigits(input.phoneE164)) add(\"SUSPICIOUS_DIGITS\", 25);\n    if (isFakeName(input.name)) add(\"FAKE_NAME\", 20);\n    if (input.address.trim().length < 15 || !input.governorate || !input.city) add(\"INCOMPLETE_ADDRESS\", 15);\n    if (input.context.history.total === 0 && input.codAmount > (input.highValueThreshold ?? 3e3)) {\n      add(\"HIGH_VALUE_FIRST_ORDER\", 10);\n    }\n    if (input.items.some((item) => item.qty > 5)) add(\"HIGH_QUANTITY\", 10);\n    if (input.context.history.delivered > 0) add(\"DELIVERED_HISTORY\", -15);\n    if (input.context.telegramLinked) add(\"TELEGRAM_LINKED\", -5);\n    const score = Math.max(0, Math.min(100, reasons.reduce((total, entry) => total + entry.points, 0)));\n    const thresholds = input.thresholds ?? { block: 70, review: 40 };\n    const level = score >= thresholds.block ? \"HIGH\" : score >= thresholds.review ? \"MEDIUM\" : \"LOW\";\n    const initialStatus = level === \"HIGH\" ? \"BLOCKED\" : level === \"MEDIUM\" ? \"NEEDS_REVIEW\" : \"PENDING_CONFIRMATION\";\n    return { score, level, initialStatus, reasons };\n  }\n  function run(items) {\n    return items.map((item) => {\n      const customer = item.json.customer ?? {};\n      const shipping = item.json.shipping ?? {};\n      const geo = item.json.geo ?? {};\n      const settings = item.json.settings ?? {};\n      const risk = scoreRisk({\n        phoneE164: String(customer.phoneE164 ?? item.json.phoneE164 ?? \"\"),\n        phoneValid: Boolean(item.json.phoneValid),\n        name: String(customer.name ?? item.json.name ?? \"\"),\n        address: String(shipping.address ?? item.json.address ?? \"\"),\n        governorate: String(geo.governorate?.ar ?? shipping.governorate ?? \"\") || null,\n        city: String(geo.city ?? shipping.city ?? \"\") || null,\n        codAmount: Number(item.json.codAmount ?? item.json.total ?? 0),\n        items: item.json.items ?? [],\n        context: item.json.riskContext,\n        thresholds: settings.riskThresholds,\n        highValueThreshold: Number(settings.highValueThreshold ?? 3e3)\n      });\n      return { ...item, json: { ...item.json, risk } };\n    });\n  }\n\n  // risk-score.bundle-entry.ts\n  __smartCodRun = run;\n})();\nreturn __smartCodRun($input.all(), { now: new Date().toISOString() });"
      },
      "id": "wf01-risk-score",
      "name": "Dynamic Risk Scoring Engine (0-100)",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1140,
        -40
      ]
    },
    {
      "parameters": {
        "jsCode": "let __smartCodRun;\n(() => {\n  // n8n/code/carrier-route.ts\n  var DEFAULT_ZONE_RULES = {\n    METRO: { carrier: \"BOSTA\", service: \"BOSTA EXPRESS METRO\" },\n    REGIONAL: { carrier: \"ARAMEX\", service: \"ARAMEX REGIONAL\" },\n    GULF: { carrier: \"DHL\", service: \"DHL GULF EXPRESS\" },\n    INTL: { carrier: \"DHL\", service: \"DHL INTERNATIONAL\" }\n  };\n  function routeCarrier(zone, rules = DEFAULT_ZONE_RULES) {\n    const route = rules[zone];\n    if (!route) throw new Error(`No carrier route configured for zone ${zone}`);\n    return { zone, ...route };\n  }\n  function run(items) {\n    return items.map((item) => {\n      const geo = item.json.geo ?? {};\n      const settings = item.json.settings ?? {};\n      const rules = settings.zoneRules ?? DEFAULT_ZONE_RULES;\n      const route = routeCarrier(String(geo.zone ?? item.json.zone), rules);\n      return { ...item, json: { ...item.json, route } };\n    });\n  }\n\n  // carrier-route.bundle-entry.ts\n  __smartCodRun = run;\n})();\nreturn __smartCodRun($input.all(), { now: new Date().toISOString() });"
      },
      "id": "wf01-carrier-route",
      "name": "Multi-Carrier Destination Router",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1380,
        -40
      ]
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "wf01-route-bosta",
                    "leftValue": "={{ $json.route.carrier }}",
                    "rightValue": "BOSTA",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Bosta"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "wf01-route-aramex",
                    "leftValue": "={{ $json.route.carrier }}",
                    "rightValue": "ARAMEX",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Aramex"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "wf01-route-dhl",
                    "leftValue": "={{ $json.route.carrier }}",
                    "rightValue": "DHL",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "DHL"
            }
          ]
        },
        "options": {
          "fallbackOutput": "none"
        }
      },
      "id": "wf01-carrier-switch",
      "name": "Carrier Assignment Switch",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.4,
      "position": [
        1620,
        -40
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "wf01-bosta-carrier",
              "name": "carrier",
              "value": "BOSTA",
              "type": "string"
            },
            {
              "id": "wf01-bosta-service",
              "name": "carrierService",
              "value": "={{ $json.route.service }}",
              "type": "string"
            },
            {
              "id": "wf01-bosta-address",
              "name": "addressLine",
              "value": "={{ $json.orderInput.shipping.address }}",
              "type": "string"
            },
            {
              "id": "wf01-bosta-city",
              "name": "city",
              "value": "={{ $json.geo.city || $json.orderInput.shipping.city }}",
              "type": "string"
            },
            {
              "id": "wf01-bosta-governorate",
              "name": "governorate",
              "value": "={{ $json.geo.governorate?.ar || $json.orderInput.shipping.governorate }}",
              "type": "string"
            },
            {
              "id": "wf01-bosta-country",
              "name": "country",
              "value": "={{ $json.geo.country }}",
              "type": "string"
            },
            {
              "id": "wf01-bosta-currency",
              "name": "currency",
              "value": "={{ $json.orderInput.currency }}",
              "type": "string"
            }
          ]
        },
        "includeOtherFields": true,
        "options": {}
      },
      "id": "wf01-bosta-assign",
      "name": "Assign Carrier A (Bosta Express)",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1880,
        -200
      ]
    },
    {
      "parameters": {
        "jsCode": "let __smartCodRun;\n(() => {\n  // n8n/code/manifest.ts\n  function bostaManifest(order) {\n    return {\n      provider: \"BOSTA\",\n      type: \"PACKAGING_MANIFEST\",\n      reference: order.id ?? order.externalId,\n      service: order.carrierService,\n      receiver: { name: order.customer.name, phone: order.customer.phoneE164 },\n      dropOffAddress: {\n        firstLine: order.addressLine,\n        city: order.city,\n        zone: order.governorate,\n        country: order.country\n      },\n      cod: { amount: order.codAmount, currency: order.currency },\n      packages: order.items.map((item) => ({ sku: item.sku, quantity: item.qty }))\n    };\n  }\n  function aramexManifest(order) {\n    return {\n      provider: \"ARAMEX\",\n      type: \"PACKAGING_MANIFEST\",\n      reference: order.id ?? order.externalId,\n      productGroup: \"DOM\",\n      productType: \"CDS\",\n      service: order.carrierService,\n      consignee: {\n        name: order.customer.name,\n        phone: order.customer.phoneE164,\n        email: order.customer.email,\n        address: order.addressLine,\n        city: order.city,\n        state: order.governorate,\n        countryCode: order.country\n      },\n      cashOnDelivery: { value: order.codAmount, currency: order.currency },\n      pieces: order.items.map((item) => ({ reference: item.sku, quantity: item.qty }))\n    };\n  }\n  function dhlManifest(order) {\n    return {\n      provider: \"DHL\",\n      type: \"CUSTOMS_DECLARATION\",\n      reference: order.id ?? order.externalId,\n      service: order.carrierService,\n      receiver: {\n        name: order.customer.name,\n        phone: order.customer.phoneE164,\n        email: order.customer.email,\n        address: order.addressLine,\n        city: order.city,\n        region: order.governorate,\n        countryCode: order.country\n      },\n      duties: \"DAP\",\n      declaredValue: { value: order.codAmount, currency: order.currency },\n      commodities: order.items.map((item) => ({\n        description: item.sku,\n        quantity: item.qty,\n        unitPrice: item.unitPrice ?? 0,\n        countryOfOrigin: \"EG\"\n      }))\n    };\n  }\n  function createManifest(order) {\n    if (order.carrier === \"BOSTA\") return bostaManifest(order);\n    if (order.carrier === \"ARAMEX\") return aramexManifest(order);\n    return dhlManifest(order);\n  }\n  function run(items) {\n    return items.map((item) => {\n      const source = item.json.order && typeof item.json.order === \"object\" ? item.json.order : item.json;\n      return {\n        ...item,\n        json: { ...item.json, manifest: createManifest(source) }\n      };\n    });\n  }\n\n  // manifest.bundle-entry.ts\n  __smartCodRun = run;\n})();\nreturn __smartCodRun($input.all(), { now: new Date().toISOString() });"
      },
      "id": "wf01-bosta-manifest",
      "name": "Format Bosta Packaging Manifest",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2140,
        -200
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "wf01-aramex-carrier",
              "name": "carrier",
              "value": "ARAMEX",
              "type": "string"
            },
            {
              "id": "wf01-aramex-service",
              "name": "carrierService",
              "value": "={{ $json.route.service }}",
              "type": "string"
            },
            {
              "id": "wf01-aramex-address",
              "name": "addressLine",
              "value": "={{ $json.orderInput.shipping.address }}",
              "type": "string"
            },
            {
              "id": "wf01-aramex-city",
              "name": "city",
              "value": "={{ $json.geo.city || $json.orderInput.shipping.city }}",
              "type": "string"
            },
            {
              "id": "wf01-aramex-governorate",
              "name": "governorate",
              "value": "={{ $json.geo.governorate?.ar || $json.orderInput.shipping.governorate }}",
              "type": "string"
            },
            {
              "id": "wf01-aramex-country",
              "name": "country",
              "value": "={{ $json.geo.country }}",
              "type": "string"
            },
            {
              "id": "wf01-aramex-currency",
              "name": "currency",
              "value": "={{ $json.orderInput.currency }}",
              "type": "string"
            }
          ]
        },
        "includeOtherFields": true,
        "options": {}
      },
      "id": "wf01-aramex-assign",
      "name": "Assign Carrier B (Aramex Regional)",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1880,
        -40
      ]
    },
    {
      "parameters": {
        "jsCode": "let __smartCodRun;\n(() => {\n  // n8n/code/manifest.ts\n  function bostaManifest(order) {\n    return {\n      provider: \"BOSTA\",\n      type: \"PACKAGING_MANIFEST\",\n      reference: order.id ?? order.externalId,\n      service: order.carrierService,\n      receiver: { name: order.customer.name, phone: order.customer.phoneE164 },\n      dropOffAddress: {\n        firstLine: order.addressLine,\n        city: order.city,\n        zone: order.governorate,\n        country: order.country\n      },\n      cod: { amount: order.codAmount, currency: order.currency },\n      packages: order.items.map((item) => ({ sku: item.sku, quantity: item.qty }))\n    };\n  }\n  function aramexManifest(order) {\n    return {\n      provider: \"ARAMEX\",\n      type: \"PACKAGING_MANIFEST\",\n      reference: order.id ?? order.externalId,\n      productGroup: \"DOM\",\n      productType: \"CDS\",\n      service: order.carrierService,\n      consignee: {\n        name: order.customer.name,\n        phone: order.customer.phoneE164,\n        email: order.customer.email,\n        address: order.addressLine,\n        city: order.city,\n        state: order.governorate,\n        countryCode: order.country\n      },\n      cashOnDelivery: { value: order.codAmount, currency: order.currency },\n      pieces: order.items.map((item) => ({ reference: item.sku, quantity: item.qty }))\n    };\n  }\n  function dhlManifest(order) {\n    return {\n      provider: \"DHL\",\n      type: \"CUSTOMS_DECLARATION\",\n      reference: order.id ?? order.externalId,\n      service: order.carrierService,\n      receiver: {\n        name: order.customer.name,\n        phone: order.customer.phoneE164,\n        email: order.customer.email,\n        address: order.addressLine,\n        city: order.city,\n        region: order.governorate,\n        countryCode: order.country\n      },\n      duties: \"DAP\",\n      declaredValue: { value: order.codAmount, currency: order.currency },\n      commodities: order.items.map((item) => ({\n        description: item.sku,\n        quantity: item.qty,\n        unitPrice: item.unitPrice ?? 0,\n        countryOfOrigin: \"EG\"\n      }))\n    };\n  }\n  function createManifest(order) {\n    if (order.carrier === \"BOSTA\") return bostaManifest(order);\n    if (order.carrier === \"ARAMEX\") return aramexManifest(order);\n    return dhlManifest(order);\n  }\n  function run(items) {\n    return items.map((item) => {\n      const source = item.json.order && typeof item.json.order === \"object\" ? item.json.order : item.json;\n      return {\n        ...item,\n        json: { ...item.json, manifest: createManifest(source) }\n      };\n    });\n  }\n\n  // manifest.bundle-entry.ts\n  __smartCodRun = run;\n})();\nreturn __smartCodRun($input.all(), { now: new Date().toISOString() });"
      },
      "id": "wf01-aramex-manifest",
      "name": "Format Aramex Packaging Manifest",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2140,
        -40
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "wf01-dhl-carrier",
              "name": "carrier",
              "value": "DHL",
              "type": "string"
            },
            {
              "id": "wf01-dhl-service",
              "name": "carrierService",
              "value": "={{ $json.route.service }}",
              "type": "string"
            },
            {
              "id": "wf01-dhl-address",
              "name": "addressLine",
              "value": "={{ $json.orderInput.shipping.address }}",
              "type": "string"
            },
            {
              "id": "wf01-dhl-city",
              "name": "city",
              "value": "={{ $json.geo.city || $json.orderInput.shipping.city }}",
              "type": "string"
            },
            {
              "id": "wf01-dhl-governorate",
              "name": "governorate",
              "value": "={{ $json.geo.governorate?.ar || $json.orderInput.shipping.governorate || $json.geo.city }}",
              "type": "string"
            },
            {
              "id": "wf01-dhl-country",
              "name": "country",
              "value": "={{ $json.geo.country }}",
              "type": "string"
            },
            {
              "id": "wf01-dhl-currency",
              "name": "currency",
              "value": "={{ $json.orderInput.currency }}",
              "type": "string"
            }
          ]
        },
        "includeOtherFields": true,
        "options": {}
      },
      "id": "wf01-dhl-assign",
      "name": "Assign Carrier C (DHL Gulf or Intl)",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1880,
        120
      ]
    },
    {
      "parameters": {
        "jsCode": "let __smartCodRun;\n(() => {\n  // n8n/code/manifest.ts\n  function bostaManifest(order) {\n    return {\n      provider: \"BOSTA\",\n      type: \"PACKAGING_MANIFEST\",\n      reference: order.id ?? order.externalId,\n      service: order.carrierService,\n      receiver: { name: order.customer.name, phone: order.customer.phoneE164 },\n      dropOffAddress: {\n        firstLine: order.addressLine,\n        city: order.city,\n        zone: order.governorate,\n        country: order.country\n      },\n      cod: { amount: order.codAmount, currency: order.currency },\n      packages: order.items.map((item) => ({ sku: item.sku, quantity: item.qty }))\n    };\n  }\n  function aramexManifest(order) {\n    return {\n      provider: \"ARAMEX\",\n      type: \"PACKAGING_MANIFEST\",\n      reference: order.id ?? order.externalId,\n      productGroup: \"DOM\",\n      productType: \"CDS\",\n      service: order.carrierService,\n      consignee: {\n        name: order.customer.name,\n        phone: order.customer.phoneE164,\n        email: order.customer.email,\n        address: order.addressLine,\n        city: order.city,\n        state: order.governorate,\n        countryCode: order.country\n      },\n      cashOnDelivery: { value: order.codAmount, currency: order.currency },\n      pieces: order.items.map((item) => ({ reference: item.sku, quantity: item.qty }))\n    };\n  }\n  function dhlManifest(order) {\n    return {\n      provider: \"DHL\",\n      type: \"CUSTOMS_DECLARATION\",\n      reference: order.id ?? order.externalId,\n      service: order.carrierService,\n      receiver: {\n        name: order.customer.name,\n        phone: order.customer.phoneE164,\n        email: order.customer.email,\n        address: order.addressLine,\n        city: order.city,\n        region: order.governorate,\n        countryCode: order.country\n      },\n      duties: \"DAP\",\n      declaredValue: { value: order.codAmount, currency: order.currency },\n      commodities: order.items.map((item) => ({\n        description: item.sku,\n        quantity: item.qty,\n        unitPrice: item.unitPrice ?? 0,\n        countryOfOrigin: \"EG\"\n      }))\n    };\n  }\n  function createManifest(order) {\n    if (order.carrier === \"BOSTA\") return bostaManifest(order);\n    if (order.carrier === \"ARAMEX\") return aramexManifest(order);\n    return dhlManifest(order);\n  }\n  function run(items) {\n    return items.map((item) => {\n      const source = item.json.order && typeof item.json.order === \"object\" ? item.json.order : item.json;\n      return {\n        ...item,\n        json: { ...item.json, manifest: createManifest(source) }\n      };\n    });\n  }\n\n  // manifest.bundle-entry.ts\n  __smartCodRun = run;\n})();\nreturn __smartCodRun($input.all(), { now: new Date().toISOString() });"
      },
      "id": "wf01-dhl-manifest",
      "name": "Format DHL Customs Declaration",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2140,
        120
      ]
    },
    {
      "parameters": {
        "url": "={{ $env.INTERNAL_API_URL }}/api/internal/products/stock",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "skus",
              "value": "={{ $json.items.map(item => item.sku).join(',') }}"
            }
          ]
        },
        "options": {
          "timeout": 10000
        }
      },
      "id": "wf01-stock",
      "name": "Check Product Stock Availability",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        2400,
        -40
      ],
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 1000,
      "credentials": {
        "httpHeaderAuth": {
          "id": "cred_internal_api",
          "name": "COD Internal API Bearer"
        }
      }
    },
    {
      "parameters": {
        "method": "POST",
        "url": "={{ $env.INTERNAL_API_URL }}/api/internal/orders",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={{ (() => { const data = $('Multi-Carrier Destination Router').item.json; const input = data.orderInput; return JSON.stringify({ externalId: input.externalId, source: input.source, customer: { name: data.customer.name, phoneE164: data.customer.phoneE164, email: data.customer.email, country: data.geo.country, telecomOperator: data.customer.telecomOperator || undefined }, addressRaw: input.shipping.address, addressLine: input.shipping.address, city: data.geo.city || input.shipping.city || undefined, governorate: data.geo.governorate?.ar || input.shipping.governorate || undefined, country: data.geo.country, zone: data.geo.zone, carrier: data.route.carrier, carrierService: data.route.service, initialStatus: data.risk.initialStatus, riskScore: data.risk.score, riskLevel: data.risk.level, riskReasons: data.risk.reasons, items: input.items, shippingFee: input.shippingFee, discount: input.discount, currency: input.currency, notes: input.notes }); })() }}",
        "options": {
          "timeout": 10000
        }
      },
      "id": "wf01-create-order",
      "name": "Create Order & Reserve Inventory",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        2640,
        -40
      ],
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 1000,
      "credentials": {
        "httpHeaderAuth": {
          "id": "cred_internal_api",
          "name": "COD Internal API Bearer"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "let __smartCodRun;\n(() => {\n  // n8n/code/manifest.ts\n  function bostaManifest(order) {\n    return {\n      provider: \"BOSTA\",\n      type: \"PACKAGING_MANIFEST\",\n      reference: order.id ?? order.externalId,\n      service: order.carrierService,\n      receiver: { name: order.customer.name, phone: order.customer.phoneE164 },\n      dropOffAddress: {\n        firstLine: order.addressLine,\n        city: order.city,\n        zone: order.governorate,\n        country: order.country\n      },\n      cod: { amount: order.codAmount, currency: order.currency },\n      packages: order.items.map((item) => ({ sku: item.sku, quantity: item.qty }))\n    };\n  }\n  function aramexManifest(order) {\n    return {\n      provider: \"ARAMEX\",\n      type: \"PACKAGING_MANIFEST\",\n      reference: order.id ?? order.externalId,\n      productGroup: \"DOM\",\n      productType: \"CDS\",\n      service: order.carrierService,\n      consignee: {\n        name: order.customer.name,\n        phone: order.customer.phoneE164,\n        email: order.customer.email,\n        address: order.addressLine,\n        city: order.city,\n        state: order.governorate,\n        countryCode: order.country\n      },\n      cashOnDelivery: { value: order.codAmount, currency: order.currency },\n      pieces: order.items.map((item) => ({ reference: item.sku, quantity: item.qty }))\n    };\n  }\n  function dhlManifest(order) {\n    return {\n      provider: \"DHL\",\n      type: \"CUSTOMS_DECLARATION\",\n      reference: order.id ?? order.externalId,\n      service: order.carrierService,\n      receiver: {\n        name: order.customer.name,\n        phone: order.customer.phoneE164,\n        email: order.customer.email,\n        address: order.addressLine,\n        city: order.city,\n        region: order.governorate,\n        countryCode: order.country\n      },\n      duties: \"DAP\",\n      declaredValue: { value: order.codAmount, currency: order.currency },\n      commodities: order.items.map((item) => ({\n        description: item.sku,\n        quantity: item.qty,\n        unitPrice: item.unitPrice ?? 0,\n        countryOfOrigin: \"EG\"\n      }))\n    };\n  }\n  function createManifest(order) {\n    if (order.carrier === \"BOSTA\") return bostaManifest(order);\n    if (order.carrier === \"ARAMEX\") return aramexManifest(order);\n    return dhlManifest(order);\n  }\n  function run(items) {\n    return items.map((item) => {\n      const source = item.json.order && typeof item.json.order === \"object\" ? item.json.order : item.json;\n      return {\n        ...item,\n        json: { ...item.json, manifest: createManifest(source) }\n      };\n    });\n  }\n\n  // manifest.bundle-entry.ts\n  __smartCodRun = run;\n})();\nreturn __smartCodRun($input.all(), { now: new Date().toISOString() });"
      },
      "id": "wf01-final-manifest",
      "name": "Preserve Carrier Manifest",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2880,
        -40
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ { orderId: $json.order.id, status: $json.order.status, riskScore: $json.order.riskScore, riskLevel: $json.order.riskLevel, carrier: $json.order.carrier, zone: $json.order.zone, confirmationUrl: $json.confirmationUrl, telegramLink: $json.telegramLink, manifest: $json.manifest } }}",
        "options": {
          "responseCode": 200
        }
      },
      "id": "wf01-response",
      "name": "Respond to Webhook",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.5,
      "position": [
        3120,
        -220
      ]
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "wf01-risk-high",
                    "leftValue": "={{ $json.order.status }}",
                    "rightValue": "BLOCKED",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "HIGH"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "wf01-risk-medium",
                    "leftValue": "={{ $json.order.status }}",
                    "rightValue": "NEEDS_REVIEW",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "MEDIUM"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "wf01-risk-low",
                    "leftValue": "={{ $json.order.status }}",
                    "rightValue": "PENDING_CONFIRMATION",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "LOW"
            }
          ]
        },
        "options": {
          "fallbackOutput": "none"
        }
      },
      "id": "wf01-risk-switch",
      "name": "Risk & Fraud Switch",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.4,
      "position": [
        3120,
        20
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "wf01-fraud-audience",
              "name": "audience",
              "value": "admin",
              "type": "string"
            },
            {
              "id": "wf01-fraud-channel",
              "name": "channel",
              "value": "auto",
              "type": "string"
            },
            {
              "id": "wf01-fraud-template",
              "name": "template",
              "value": "fraud_alert",
              "type": "string"
            },
            {
              "id": "wf01-fraud-language",
              "name": "language",
              "value": "ar",
              "type": "string"
            },
            {
              "id": "wf01-fraud-vars",
              "name": "vars",
              "value": "={{ { orderId: $json.order.id, riskScore: $json.order.riskScore, riskReasons: ($json.order.riskReasons || []).map(reason => reason.labelAr || reason.code).join('، ') } }}",
              "type": "object"
            }
          ]
        },
        "options": {}
      },
      "id": "wf01-fraud-payload",
      "name": "Prepare High-Risk Fraud Alert",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        3380,
        -40
      ]
    },
    {
      "parameters": {
        "workflowId": {
          "__rl": true,
          "value": "CODWF00SendNotification",
          "mode": "id"
        },
        "mode": "once",
        "options": {
          "waitForSubWorkflow": true
        }
      },
      "id": "wf01-fraud-alert",
      "name": "Send High-Risk Fraud Alert",
      "type": "n8n-nodes-base.executeWorkflow",
      "typeVersion": 1.3,
      "position": [
        3620,
        -40
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "wf01-review-audience",
              "name": "audience",
              "value": "admin",
              "type": "string"
            },
            {
              "id": "wf01-review-channel",
              "name": "channel",
              "value": "auto",
              "type": "string"
            },
            {
              "id": "wf01-review-template",
              "name": "template",
              "value": "review_alert",
              "type": "string"
            },
            {
              "id": "wf01-review-language",
              "name": "language",
              "value": "ar",
              "type": "string"
            },
            {
              "id": "wf01-review-vars",
              "name": "vars",
              "value": "={{ { orderId: $json.order.id, riskScore: $json.order.riskScore } }}",
              "type": "object"
            }
          ]
        },
        "options": {}
      },
      "id": "wf01-review-payload",
      "name": "Prepare Human Review Alert",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        3380,
        100
      ]
    },
    {
      "parameters": {
        "workflowId": {
          "__rl": true,
          "value": "CODWF00SendNotification",
          "mode": "id"
        },
        "mode": "once",
        "options": {
          "waitForSubWorkflow": true
        }
      },
      "id": "wf01-review-alert",
      "name": "Send Review Alert",
      "type": "n8n-nodes-base.executeWorkflow",
      "typeVersion": 1.3,
      "position": [
        3620,
        100
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "wf01-confirm-audience",
              "name": "audience",
              "value": "customer",
              "type": "string"
            },
            {
              "id": "wf01-confirm-channel",
              "name": "channel",
              "value": "auto",
              "type": "string"
            },
            {
              "id": "wf01-confirm-template",
              "name": "template",
              "value": "confirmation",
              "type": "string"
            },
            {
              "id": "wf01-confirm-language",
              "name": "language",
              "value": "ar",
              "type": "string"
            },
            {
              "id": "wf01-confirm-order",
              "name": "orderId",
              "value": "={{ $json.order.id }}",
              "type": "string"
            },
            {
              "id": "wf01-confirm-email",
              "name": "email",
              "value": "={{ $json.order.customer.email || '' }}",
              "type": "string"
            },
            {
              "id": "wf01-confirm-chat",
              "name": "chatId",
              "value": "={{ $json.order.customer.telegramChatId || '' }}",
              "type": "string"
            },
            {
              "id": "wf01-confirm-vars",
              "name": "vars",
              "value": "={{ { orderId: $json.order.id, customerName: $json.order.customer.name, codAmount: $json.order.codAmount, currency: $json.order.currency, confirmationUrl: $json.confirmationUrl, telegramLink: $json.telegramLink } }}",
              "type": "object"
            },
            {
              "id": "wf01-confirm-buttons",
              "name": "buttons",
              "value": "={{ [{ text: '✅ تأكيد', callbackData: 'act:confirm:' + $json.order.id }, { text: '❌ إلغاء', callbackData: 'act:cancel:' + $json.order.id }] }}",
              "type": "array"
            }
          ]
        },
        "options": {}
      },
      "id": "wf01-confirm-payload",
      "name": "Prepare Customer Confirmation",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        3380,
        240
      ]
    },
    {
      "parameters": {
        "workflowId": {
          "__rl": true,
          "value": "CODWF00SendNotification",
          "mode": "id"
        },
        "mode": "once",
        "options": {
          "waitForSubWorkflow": true
        }
      },
      "id": "wf01-confirm",
      "name": "Send Customer Confirmation",
      "type": "n8n-nodes-base.executeWorkflow",
      "typeVersion": 1.3,
      "position": [
        3620,
        240
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "={{ $env.INTERNAL_API_URL }}/api/internal/orders/{{ $('Preserve Carrier Manifest').item.json.order.id }}/contact-attempt",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendBody": true,
        "contentType": "raw",
        "rawContentType": "application/json",
        "body": "={{ JSON.stringify({ actor: 'n8n' }) }}",
        "options": {
          "timeout": 10000
        }
      },
      "id": "wf01-contact-attempt",
      "name": "Log Contact Attempt",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        3860,
        240
      ],
      "retryOnFail": true,
      "maxTries": 3,
      "waitBetweenTries": 1000,
      "credentials": {
        "httpHeaderAuth": {
          "id": "cred_internal_api",
          "name": "COD Internal API Bearer"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "wf01-low-stock-count",
              "leftValue": "={{ $('Preserve Carrier Manifest').item.json.lowStock.length }}",
              "rightValue": 0,
              "operator": {
                "type": "number",
                "operation": "gt"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "wf01-low-stock-switch",
      "name": "Low-Stock Switch",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        4100,
        100
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "wf01-stock-audience",
              "name": "audience",
              "value": "admin",
              "type": "string"
            },
            {
              "id": "wf01-stock-channel",
              "name": "channel",
              "value": "auto",
              "type": "string"
            },
            {
              "id": "wf01-stock-template",
              "name": "template",
              "value": "low_stock_alert",
              "type": "string"
            },
            {
              "id": "wf01-stock-language",
              "name": "language",
              "value": "ar",
              "type": "string"
            },
            {
              "id": "wf01-stock-vars",
              "name": "vars",
              "value": "={{ { sku: $('Preserve Carrier Manifest').item.json.lowStock[0].sku, available: $('Preserve Carrier Manifest').item.json.lowStock[0].onHand - $('Preserve Carrier Manifest').item.json.lowStock[0].reserved } }}",
              "type": "object"
            }
          ]
        },
        "options": {}
      },
      "id": "wf01-low-stock-payload",
      "name": "Prepare Low-Stock Restock Alert",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        4340,
        40
      ]
    },
    {
      "parameters": {
        "workflowId": {
          "__rl": true,
          "value": "CODWF00SendNotification",
          "mode": "id"
        },
        "mode": "once",
        "options": {
          "waitForSubWorkflow": true
        }
      },
      "id": "wf01-low-stock-alert",
      "name": "Push Low-Stock Restock Alert",
      "type": "n8n-nodes-base.executeWorkflow",
      "typeVersion": 1.3,
      "position": [
        4580,
        40
      ]
    }
  ],
  "connections": {
    "Store Order Webhook": {
      "main": [
        [
          {
            "node": "Authenticate Store Webhook Key",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Authenticate Store Webhook Key": {
      "main": [
        [
          {
            "node": "Sanitize Phone & Input Data",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Respond Unauthorized",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sanitize Phone & Input Data": {
      "main": [
        [
          {
            "node": "Required Order Fields Present?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Required Order Fields Present?": {
      "main": [
        [
          {
            "node": "Validate Phone Number E.164 Structure",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Respond Validation Error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Phone Number E.164 Structure": {
      "main": [
        [
          {
            "node": "Parse Governorate & City Geo-Location",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Governorate & City Geo-Location": {
      "main": [
        [
          {
            "node": "Enrich Address Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Enrich Address Details": {
      "main": [
        [
          {
            "node": "Detect Telecom Operator",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Detect Telecom Operator": {
      "main": [
        [
          {
            "node": "Fetch Store Settings",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Store Settings": {
      "main": [
        [
          {
            "node": "Fetch Risk Context (Dup, Blacklist, History)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Risk Context (Dup, Blacklist, History)": {
      "main": [
        [
          {
            "node": "Merge Order, Settings & Risk Context",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Order, Settings & Risk Context": {
      "main": [
        [
          {
            "node": "Dynamic Risk Scoring Engine (0-100)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Dynamic Risk Scoring Engine (0-100)": {
      "main": [
        [
          {
            "node": "Multi-Carrier Destination Router",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Multi-Carrier Destination Router": {
      "main": [
        [
          {
            "node": "Carrier Assignment Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Carrier Assignment Switch": {
      "main": [
        [
          {
            "node": "Assign Carrier A (Bosta Express)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Assign Carrier B (Aramex Regional)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Assign Carrier C (DHL Gulf or Intl)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Assign Carrier A (Bosta Express)": {
      "main": [
        [
          {
            "node": "Format Bosta Packaging Manifest",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Bosta Packaging Manifest": {
      "main": [
        [
          {
            "node": "Check Product Stock Availability",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Assign Carrier B (Aramex Regional)": {
      "main": [
        [
          {
            "node": "Format Aramex Packaging Manifest",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format Aramex Packaging Manifest": {
      "main": [
        [
          {
            "node": "Check Product Stock Availability",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Assign Carrier C (DHL Gulf or Intl)": {
      "main": [
        [
          {
            "node": "Format DHL Customs Declaration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format DHL Customs Declaration": {
      "main": [
        [
          {
            "node": "Check Product Stock Availability",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Product Stock Availability": {
      "main": [
        [
          {
            "node": "Create Order & Reserve Inventory",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Order & Reserve Inventory": {
      "main": [
        [
          {
            "node": "Preserve Carrier Manifest",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Preserve Carrier Manifest": {
      "main": [
        [
          {
            "node": "Respond to Webhook",
            "type": "main",
            "index": 0
          },
          {
            "node": "Risk & Fraud Switch",
            "type": "main",
            "index": 0
          },
          {
            "node": "Low-Stock Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Risk & Fraud Switch": {
      "main": [
        [
          {
            "node": "Prepare High-Risk Fraud Alert",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Prepare Human Review Alert",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Prepare Customer Confirmation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare High-Risk Fraud Alert": {
      "main": [
        [
          {
            "node": "Send High-Risk Fraud Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send High-Risk Fraud Alert": {
      "main": [
        []
      ]
    },
    "Prepare Human Review Alert": {
      "main": [
        [
          {
            "node": "Send Review Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Review Alert": {
      "main": [
        []
      ]
    },
    "Prepare Customer Confirmation": {
      "main": [
        [
          {
            "node": "Send Customer Confirmation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Customer Confirmation": {
      "main": [
        [
          {
            "node": "Log Contact Attempt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Contact Attempt": {
      "main": [
        []
      ]
    },
    "Low-Stock Switch": {
      "main": [
        [
          {
            "node": "Prepare Low-Stock Restock Alert",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "Prepare Low-Stock Restock Alert": {
      "main": [
        [
          {
            "node": "Push Low-Stock Restock Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "errorWorkflow": "CODWF99ErrorHandler",
    "timezone": "Africa/Cairo"
  },
  "versionId": "f0100000-0000-4000-8000-000000000000",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "tags": []
}
