{
  "name": "REVOPS-LI-006 | 06 | Attribution operations",
  "nodes": [
    {
      "parameters": {},
      "id": "21719435-d069-4d61-8ec9-4eaa97ec2c0a",
      "name": "Attribution Error",
      "type": "n8n-nodes-base.errorTrigger",
      "typeVersion": 1,
      "position": [
        0,
        0
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForAllItems",
        "jsCode": "const e=$input.first().json;return [{json:{execution_id:String(e.execution?.id||''),node:String(e.execution?.lastNodeExecuted||'unknown'),message:String(e.execution?.error?.message||'Workflow failed').replace(/Bearer\\s+\\S+/gi,'Bearer [REDACTED]').slice(0,1000)}}];"
      },
      "id": "cd8535bb-3742-4689-a6f8-737c256ca456",
      "name": "Failure Context",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        270,
        0
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT attribution.fail_execution($1::text,$2::jsonb) AS result;",
        "options": {
          "queryReplacement": "={{ [$json.execution_id,JSON.stringify({node:$json.node,message:$json.message})] }}"
        }
      },
      "id": "5b982f55-faa8-4a24-8c98-c582a4f2f144",
      "name": "Record Attribution Failure",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "position": [
        540,
        0
      ],
      "credentials": {
        "postgres": {
          "id": "REPLACE_POSTGRES_CREDENTIAL",
          "name": "ATTRIBUTION Postgres"
        }
      }
    },
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 15
            }
          ]
        }
      },
      "id": "2c0e1dd0-b8c2-491e-8f68-94aa048307b1",
      "name": "Inspect Operational Health",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        810,
        0
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT status,count(*) AS event_count,min(received_at) AS oldest_event FROM attribution.events WHERE tenant=$1 AND (status IN ('review','awaiting_match','awaiting_contact') OR (status='processing' AND updated_at<now()-interval '10 minutes')) GROUP BY status;",
        "options": {
          "queryReplacement": "={{ ['REVOPS-LI-006'] }}"
        }
      },
      "id": "dbd6cb74-2835-4dbf-9ba8-e0725b57a311",
      "name": "Return Stalled and Review Counts",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2.6,
      "position": [
        1080,
        0
      ],
      "credentials": {
        "postgres": {
          "id": "REPLACE_POSTGRES_CREDENTIAL",
          "name": "ATTRIBUTION Postgres"
        }
      }
    },
    {
      "parameters": {
        "content": "## Operations\nSelect this as Error Workflow for workflows 01, 02 and 04 after import.\nAutomatic failures are persisted; an ended worker releases its queue lease.\nStalled leases are NOT silently reclaimed while an old execution might still write.\nUse the report quality section / this scheduled output to inspect review and backlog counts.",
        "width": 700,
        "height": 220
      },
      "id": "78002c12-c47d-4e84-b043-4449b5285d9c",
      "name": "Workflow Guide",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        0,
        -270
      ]
    }
  ],
  "connections": {
    "Attribution Error": {
      "main": [
        [
          {
            "node": "Failure Context",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Failure Context": {
      "main": [
        [
          {
            "node": "Record Attribution Failure",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Inspect Operational Health": {
      "main": [
        [
          {
            "node": "Return Stalled and Review Counts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1",
    "timezone": "Asia/Tbilisi",
    "saveExecutionProgress": true
  },
  "active": false,
  "pinData": {},
  "tags": []
}

