{
  "name": "Ratifia: send customer email (protected, community node)",
  "nodes": [
    {
      "parameters": {
        "content": "## The protected action\n\nThe only workflow that sends customer email, so the one that enforces approval.\n\nIt is handed a **receiptId**, a **decisionId** and the approved **body** \u2014 and nothing else. It looks the refund up in the system of record itself and binds **what it reads there**.\n\nThat is the point. Rebuilding the facts from arguments only proves the email has not changed since approval; a caller that claims $100 when the receipt says $1,000, at both ends, passes every check. The amount is never an argument here, so it cannot be lied about.\n\nThe body is not bound: the reviewer rewrote it, and it *is* the approved artifact.\n\nKeep the mail credential **only** here, and point **Look up the receipt** at your own system.",
        "height": 360,
        "width": 580
      },
      "id": "9606f720-f23d-42ab-affb-06e2cb0efd2b",
      "name": "Note 1a67ac",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        0,
        -140
      ]
    },
    {
      "parameters": {
        "inputSource": "passthrough"
      },
      "id": "4322c7f0-5f48-4665-b25c-22adfb33c932",
      "name": "Called by another workflow",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "typeVersion": 1.1,
      "position": [
        0,
        300
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "6e291a05-eb19-4e72-a731-1231c4d0911e",
              "leftValue": "={{ $json.decisionId }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "c5eca1cf-f1fb-4c3c-a505-6926cfcd0b8e",
      "name": "Has a decision?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        220,
        300
      ]
    },
    {
      "parameters": {
        "errorMessage": "Not sent: no decision was passed in"
      },
      "id": "90ecc3ca-eba7-4c26-9bf8-eb06069b860a",
      "name": "Refuse: no approval",
      "type": "n8n-nodes-base.stopAndError",
      "typeVersion": 1,
      "position": [
        440,
        460
      ]
    },
    {
      "parameters": {
        "url": "=https://your-system.example/receipts/{{ $(\"Called by another workflow\").item.json.receiptId }}",
        "options": {
          "timeout": 30000
        }
      },
      "id": "40ff4d17-d54d-4639-be5a-b1e96e52acfd",
      "name": "Look up the receipt",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        660,
        200
      ]
    },
    {
      "parameters": {
        "url": "=https://your-system.example/receipts/{{ $(\"Called by another workflow\").item.json.receiptId }}",
        "options": {
          "timeout": 30000
        }
      },
      "id": "6b9ad5fb-6926-4756-9c67-8ec81eb33319",
      "name": "Re-read the receipt",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1320,
        200
      ]
    },
    {
      "parameters": {
        "operation": "verify",
        "decisionId": "={{ $(\"Called by another workflow\").item.json.decisionId }}",
        "actionFactsTable": {
          "fact": [
            {
              "name": "receiptId",
              "type": "string",
              "value": "={{ $(\"Called by another workflow\").item.json.receiptId }}"
            },
            {
              "name": "recipient",
              "type": "string",
              "value": "={{ $(\"Look up the receipt\").item.json.recipient }}"
            },
            {
              "name": "amount",
              "type": "number",
              "value": "={{ $(\"Look up the receipt\").item.json.amount }}"
            }
          ]
        }
      },
      "id": "9ff4f957-6f25-46ef-89f3-9bd780842510",
      "name": "Verify approval",
      "type": "n8n-nodes-ratifia.ratifia",
      "typeVersion": 1,
      "position": [
        880,
        200
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "99c28329-f759-4d07-b3c1-abd7cb7993df",
              "leftValue": "={{ $json.valid }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            },
            {
              "id": "7e4010cd-de82-4f1f-b016-7c01217dfe7b",
              "leftValue": "={{ $json.reason }}",
              "rightValue": "consumed",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ],
          "combinator": "or"
        },
        "options": {}
      },
      "id": "cc958982-4677-401c-a244-d5ce9f5c144c",
      "name": "Covers this email?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1100,
        200
      ]
    },
    {
      "parameters": {
        "operation": "consume",
        "decisionId": "={{ $(\"Called by another workflow\").item.json.decisionId }}",
        "actionFactsTable": {
          "fact": [
            {
              "name": "receiptId",
              "type": "string",
              "value": "={{ $(\"Called by another workflow\").item.json.receiptId }}"
            },
            {
              "name": "recipient",
              "type": "string",
              "value": "={{ $(\"Re-read the receipt\").item.json.recipient }}"
            },
            {
              "name": "amount",
              "type": "number",
              "value": "={{ $(\"Re-read the receipt\").item.json.amount }}"
            }
          ]
        },
        "consumer": "={{ \"send-email:\" + $(\"Verify approval\").item.json.factsHash }}"
      },
      "id": "37357060-f144-4a5e-bd72-a3bb1f7abe73",
      "name": "Consume approval",
      "type": "n8n-nodes-ratifia.ratifia",
      "typeVersion": 1,
      "position": [
        1540,
        300
      ]
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "loose",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "066c7a77-533f-4a48-87cd-264e756d2b9f",
                    "leftValue": "={{ $json.alreadyConsumed }}",
                    "rightValue": "",
                    "operator": {
                      "type": "boolean",
                      "operation": "true",
                      "singleValue": true
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Already sent"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "loose",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "c0945511-0b83-489d-907a-1d1e21233111",
                    "leftValue": "={{ $json.consumed }}",
                    "rightValue": "",
                    "operator": {
                      "type": "boolean",
                      "operation": "true",
                      "singleValue": true
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Send"
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra",
          "renameFallbackOutput": "Refused"
        }
      },
      "id": "907bcccf-93f1-4f6e-9dd0-5903115b98e9",
      "name": "Send it?",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.2,
      "position": [
        1540,
        100
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "0894b4a6-efe9-4673-9773-9380d0443c85",
              "name": "sent",
              "value": "={{ true }}",
              "type": "boolean"
            },
            {
              "id": "32231478-347a-4c79-8ff3-239627c75818",
              "name": "to",
              "value": "={{ $(\"Re-read the receipt\").item.json.recipient }}",
              "type": "string"
            },
            {
              "id": "c30dbb09-11ef-4cad-a80d-b10f054f8986",
              "name": "subject",
              "value": "={{ $(\"Re-read the receipt\").item.json.subject }}",
              "type": "string"
            },
            {
              "id": "62e1b94b-e715-4247-bb2f-4a78336945e7",
              "name": "approvedUnder",
              "value": "={{ $json.decision.policyVersion ? \"policy v\" + $json.decision.policyVersion : \"no policy\" }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "cd40b3c7-d043-4390-92d1-41f6ed213c63",
      "name": "Send customer email (stand-in)",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1780,
        -60
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "0560bc0a-1db8-4ff9-979f-bf1a6a38d370",
              "name": "sent",
              "value": "={{ false }}",
              "type": "boolean"
            },
            {
              "id": "1aa47f21-1c46-4ac7-ac33-77ef3dd57514",
              "name": "why",
              "value": "a retry of an email that was already sent",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "4860bae4-24f0-47c7-bcbc-eb5f20eb97a4",
      "name": "Already sent, not sending again",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1780,
        100
      ]
    },
    {
      "parameters": {
        "errorMessage": "=Not sent: {{ $json.reason }}"
      },
      "id": "9b71ec89-c0dd-4be2-8a54-dadd3b9410b4",
      "name": "Refuse: approval already spent",
      "type": "n8n-nodes-base.stopAndError",
      "typeVersion": 1,
      "position": [
        1780,
        260
      ]
    },
    {
      "parameters": {
        "errorMessage": "=Not sent: {{ $json.reason }}"
      },
      "id": "e0eaa400-b35b-4520-b2a7-a1e0ac8a6ed2",
      "name": "Refuse: approval does not cover this email",
      "type": "n8n-nodes-base.stopAndError",
      "typeVersion": 1,
      "position": [
        1320,
        440
      ]
    }
  ],
  "connections": {
    "Called by another workflow": {
      "main": [
        [
          {
            "node": "Has a decision?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Has a decision?": {
      "main": [
        [
          {
            "node": "Look up the receipt",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Refuse: no approval",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Verify approval": {
      "main": [
        [
          {
            "node": "Covers this email?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Covers this email?": {
      "main": [
        [
          {
            "node": "Re-read the receipt",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Refuse: approval does not cover this email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Consume approval": {
      "main": [
        [
          {
            "node": "Send it?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send it?": {
      "main": [
        [
          {
            "node": "Already sent, not sending again",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Send customer email (stand-in)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Refuse: approval already spent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Look up the receipt": {
      "main": [
        [
          {
            "node": "Verify approval",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Re-read the receipt": {
      "main": [
        [
          {
            "node": "Consume approval",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  }
}
