{
  "id": "e09BrowserReceiptDemo",
  "name": "Browser receipt and idempotency fixture",
  "active": false,
  "nodes": [
    {
      "id": "3ff11937-5d0c-4d2a-b888-92fb99b36ac1",
      "name": "Manual Test",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        0,
        0
      ],
      "parameters": {}
    },
    {
      "id": "f5bcf110-a2be-47a2-b872-c281f856c7bb",
      "name": "Workflow Tool Input",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "typeVersion": 1.1,
      "position": [
        0,
        220
      ],
      "parameters": {
        "workflowInputs": {
          "values": [
            {
              "name": "operation_id",
              "type": "string"
            },
            {
              "name": "scenario",
              "type": "string"
            }
          ]
        },
        "inputSource": "workflowInputs"
      }
    },
    {
      "id": "51a3758f-7387-44c9-9a58-028a20c52d71",
      "name": "Validate or Seed Cases",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        220,
        110
      ],
      "parameters": {
        "jsCode": "const input = $input.all();\nconst allowed = ['success', 'lost_response', 'unknown'];\nif (input.length === 1 && Object.keys(input[0].json).length === 0) {\n  return allowed.map(scenario => ({ json: { operation_id: 'E09-' + scenario.replace('_', '-'), scenario } }));\n}\nreturn input.map(({ json }) => {\n  const { operation_id, scenario } = json;\n  if (typeof operation_id !== 'string' || !/^E09-[a-zA-Z0-9-]{1,32}$/.test(operation_id) || !allowed.includes(scenario)) {\n    throw new Error('Invalid fixture request');\n  }\n  return { json: { operation_id, scenario } };\n});"
      }
    },
    {
      "id": "8afb95f7-b025-4f43-99d6-b0a085e80fec",
      "name": "Execute Browser Action",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        440,
        110
      ],
      "parameters": {
        "method": "POST",
        "url": "http://127.0.0.1:3219/execute",
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ operation_id: $json.operation_id, scenario: $json.scenario }) }}",
        "options": {
          "timeout": 30000,
          "response": {
            "response": {
              "fullResponse": true,
              "neverError": true,
              "responseFormat": "json"
            }
          }
        }
      },
      "onError": "continueRegularOutput",
      "retryOnFail": false
    },
    {
      "id": "13a80406-20a2-4031-966a-2ea7dc494834",
      "name": "Direct Response OK",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        660,
        110
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "225016eb-ba8b-4a6c-8ae1-18ef6a2cba24",
              "leftValue": "={{ Number($json.statusCode ?? 0) }}",
              "rightValue": 200,
              "operator": {
                "type": "number",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      }
    },
    {
      "id": "0cbe10dc-0866-4443-a7e0-7f2ab53c3411",
      "name": "Read Back Operation",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        880,
        240
      ],
      "parameters": {
        "url": "={{ 'http://127.0.0.1:3219/status?operation_id=' + encodeURIComponent($('Validate or Seed Cases').item.json.operation_id) }}",
        "options": {
          "timeout": 30000,
          "response": {
            "response": {
              "fullResponse": true,
              "neverError": true,
              "responseFormat": "json"
            }
          }
        }
      },
      "onError": "continueRegularOutput",
      "retryOnFail": false
    },
    {
      "id": "82221df0-ff76-405a-ac25-13e0f7da91b4",
      "name": "Return Direct Receipt",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        880,
        -30
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\nreturn items.map((item, index) => {\n  const input = $('Validate or Seed Cases').itemMatching(index).json;\n  const { body, statusCode } = item.json;\n  const confirmed = statusCode === 200 && body?.operation_id === input.operation_id &&\n    body.status === 'confirmed' && body.fixture_id === 'E09-FIXTURE' &&\n    body.initial === 'OFF' && body.state === 'ON' && body.writes === 1;\n  const receipt = {\n    operation_id: input.operation_id,\n    outcome: confirmed ? 'confirmed' : 'needs_review',\n    receipt_source: 'post',\n    http_status: statusCode ?? null,\n    fixture_id: confirmed ? body.fixture_id : null,\n    state: confirmed ? body.state : null,\n    writes: confirmed ? body.writes : null,\n    replay: confirmed && body.replay === true,\n  };\n  return { json: receipt, pairedItem: { item: index } };\n});"
      }
    },
    {
      "id": "9bf7c2f8-f057-4fa8-bba8-4cc5e99b6b33",
      "name": "Return Reconciled Receipt",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1100,
        240
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\nreturn items.map((item, index) => {\n  const input = $('Validate or Seed Cases').itemMatching(index).json;\n  const { body, statusCode } = item.json;\n  const confirmed = statusCode === 200 && body?.operation_id === input.operation_id &&\n    body.status === 'confirmed' && body.fixture_id === 'E09-FIXTURE' &&\n    body.initial === 'OFF' && body.state === 'ON' && body.writes === 1;\n  const receipt = {\n    operation_id: input.operation_id,\n    outcome: confirmed ? 'reconciled' : 'needs_review',\n    receipt_source: 'read_back',\n    http_status: statusCode ?? null,\n    fixture_id: confirmed ? body.fixture_id : null,\n    state: confirmed ? body.state : null,\n    writes: confirmed ? body.writes : null,\n    replay: confirmed && body.replay === true,\n  };\n  return { json: receipt, pairedItem: { item: index } };\n});"
      }
    }
  ],
  "connections": {
    "Manual Test": {
      "main": [
        [
          {
            "node": "Validate or Seed Cases",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Workflow Tool Input": {
      "main": [
        [
          {
            "node": "Validate or Seed Cases",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate or Seed Cases": {
      "main": [
        [
          {
            "node": "Execute Browser Action",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Execute Browser Action": {
      "main": [
        [
          {
            "node": "Direct Response OK",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Direct Response OK": {
      "main": [
        [
          {
            "node": "Return Direct Receipt",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Read Back Operation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Read Back Operation": {
      "main": [
        [
          {
            "node": "Return Reconciled Receipt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "pinData": {},
  "tags": []
}
