{
  "name": "Nodbot - Wildberries orders stock price sync with safeguards",
  "nodes": [
    {
      "parameters": {
        "path": "wildberries-orders-stock-sync",
        "responseMode": "responseNode",
        "httpMethod": "POST"
      },
      "id": "1",
      "name": "Webhook input",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {
        "jsCode": "const src = $json.body ?? $json;\nconst vendorCode = String(src.vendor_code ?? src.vendorCode ?? '').trim().toUpperCase();\nconst nmId = Number(src.nm_id ?? src.nmID ?? 0);\nconst barcode = String(src.barcode ?? '').trim();\nconst wbOrderId = String(src.wb_order_id ?? src.orderId ?? '').trim();\nif (!wbOrderId) throw new Error('No Wildberries order id');\nif (!vendorCode && !barcode && !nmId) throw new Error(`No WB mapping keys for order ${wbOrderId}`);\nconst availableQty = Math.max(0, Number(src.stock_physical ?? src.qty ?? 0) - Number(src.reserve ?? 0) - Number(src.safety_stock ?? 1));\nreturn [{ json: {\n  idempotency_key: `wildberries:fbs:${wbOrderId}`,\n  mapping: { vendor_code: vendorCode, nm_id: nmId, barcode },\n  warehouse_id: String(src.warehouse_id ?? ''),\n  available_qty_for_wb: availableQty,\n  operation: src.event_type?.includes('order') ? 'import_order' : 'sync_stock',\n  price_policy: { max_drop_percent: 15, require_approval: Number(src.price_change_percent ?? 0) < -15 },\n  audit: { event_id: src.event_id, received_at: new Date().toISOString() }\n}}];"
      },
      "id": "2",
      "name": "Normalize and validate",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        240,
        0
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "INSERT INTO integration_events (idempotency_key, payload, created_at) VALUES ($1, $2, now()) ON CONFLICT (idempotency_key) DO NOTHING RETURNING id;"
      },
      "id": "3",
      "name": "Check idempotency",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2,
      "position": [
        480,
        0
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "={{$env.TARGET_API_URL}}",
        "sendBody": true,
        "contentType": "json",
        "jsonBody": "={{$json}}"
      },
      "id": "4",
      "name": "Call target API",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "position": [
        720,
        0
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ { ok: true, idempotency_key: $json.idempotency_key } }}"
      },
      "id": "5",
      "name": "Respond 200",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        960,
        0
      ]
    }
  ],
  "connections": {
    "Webhook input": {
      "main": [
        [
          {
            "node": "Normalize and validate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize and validate": {
      "main": [
        [
          {
            "node": "Check idempotency",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check idempotency": {
      "main": [
        [
          {
            "node": "Call target API",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Call target API": {
      "main": [
        [
          {
            "node": "Respond 200",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "meta": {
    "templateCredsSetupCompleted": false
  }
}