{
  "license": "CC BY 4.0",
  "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
  "recipe": {
    "slug": "webhook-retry-recovery",
    "title": "Measure Webhook Retry Recovery",
    "testedWith": "Apache DataFusion 45.2.0",
    "lastReviewed": "2026-07-27"
  },
  "contract": {
    "tableName": "webhook_deliveries",
    "schema": [
      {
        "name": "timestamp_utc",
        "type": "Timestamp",
        "description": "When the processing attempt ended."
      },
      {
        "name": "delivery_id",
        "type": "Utf8",
        "description": "Stable identifier shared by retry attempts."
      },
      {
        "name": "provider",
        "type": "Utf8",
        "description": "Webhook provider."
      },
      {
        "name": "event_type",
        "type": "Utf8",
        "description": "Provider event type."
      },
      {
        "name": "attempt",
        "type": "Int64",
        "description": "One-based processing attempt."
      },
      {
        "name": "status",
        "type": "Utf8",
        "description": "success, failed, or deduplicated."
      }
    ]
  },
  "query": "WITH delivery_outcomes AS (\n  SELECT\n    delivery_id,\n    provider,\n    event_type,\n    MAX(attempt) AS attempts,\n    SUM(CASE WHEN status = 'failed' THEN 1 ELSE 0 END) AS failed_attempts,\n    SUM(CASE WHEN status = 'success' THEN 1 ELSE 0 END) AS successful_attempts,\n    SUM(CASE WHEN status = 'deduplicated' THEN 1 ELSE 0 END) AS deduplicated_attempts\n  FROM webhook_deliveries\n  WHERE timestamp_utc >= now() - INTERVAL '7 days'\n  GROUP BY delivery_id, provider, event_type\n)\nSELECT\n  provider,\n  event_type,\n  COUNT(*) AS deliveries,\n  SUM(CASE\n    WHEN failed_attempts > 0 AND successful_attempts > 0 THEN 1 ELSE 0\n  END) AS recovered,\n  SUM(CASE\n    WHEN failed_attempts > 0 AND successful_attempts = 0 THEN 1 ELSE 0\n  END) AS permanent_failures,\n  SUM(deduplicated_attempts) AS duplicates_suppressed\nFROM delivery_outcomes\nGROUP BY provider, event_type\nORDER BY permanent_failures DESC, recovered DESC;",
  "fixtureKind": "reproducible",
  "inputRows": [
    {
      "timestamp_utc": "2026-07-28T18:00:00.000Z",
      "attempt": 1,
      "delivery_id": "stripe-recovered",
      "event_type": "invoice.payment_succeeded",
      "provider": "stripe",
      "status": "failed"
    },
    {
      "timestamp_utc": "2026-07-28T17:59:00.000Z",
      "attempt": 2,
      "delivery_id": "stripe-recovered",
      "event_type": "invoice.payment_succeeded",
      "provider": "stripe",
      "status": "success"
    },
    {
      "timestamp_utc": "2026-07-28T17:58:00.000Z",
      "attempt": 1,
      "delivery_id": "stripe-permanent",
      "event_type": "invoice.payment_succeeded",
      "provider": "stripe",
      "status": "failed"
    },
    {
      "timestamp_utc": "2026-07-28T17:57:00.000Z",
      "attempt": 1,
      "delivery_id": "stripe-success",
      "event_type": "invoice.payment_succeeded",
      "provider": "stripe",
      "status": "success"
    },
    {
      "timestamp_utc": "2026-07-28T17:56:00.000Z",
      "attempt": 1,
      "delivery_id": "stripe-duplicate",
      "event_type": "invoice.payment_succeeded",
      "provider": "stripe",
      "status": "deduplicated"
    },
    {
      "timestamp_utc": "2026-07-28T17:55:00.000Z",
      "attempt": 1,
      "delivery_id": "github-recovered",
      "event_type": "push",
      "provider": "github",
      "status": "failed"
    },
    {
      "timestamp_utc": "2026-07-28T17:54:00.000Z",
      "attempt": 2,
      "delivery_id": "github-recovered",
      "event_type": "push",
      "provider": "github",
      "status": "success"
    },
    {
      "timestamp_utc": "2026-07-28T17:53:00.000Z",
      "attempt": 1,
      "delivery_id": "github-success",
      "event_type": "push",
      "provider": "github",
      "status": "success"
    },
    {
      "timestamp_utc": "2026-07-28T17:52:00.000Z",
      "attempt": 1,
      "delivery_id": "github-duplicate",
      "event_type": "push",
      "provider": "github",
      "status": "deduplicated"
    }
  ],
  "illustrativeInputRows": [
    {
      "timestamp_utc": "2026-07-28T18:00:00.000Z",
      "attempt": 1,
      "delivery_id": "stripe-recovered",
      "event_type": "invoice.payment_succeeded",
      "provider": "stripe",
      "status": "failed"
    },
    {
      "timestamp_utc": "2026-07-28T17:59:00.000Z",
      "attempt": 2,
      "delivery_id": "stripe-recovered",
      "event_type": "invoice.payment_succeeded",
      "provider": "stripe",
      "status": "success"
    },
    {
      "timestamp_utc": "2026-07-28T17:58:00.000Z",
      "attempt": 1,
      "delivery_id": "stripe-permanent",
      "event_type": "invoice.payment_succeeded",
      "provider": "stripe",
      "status": "failed"
    },
    {
      "timestamp_utc": "2026-07-28T17:57:00.000Z",
      "attempt": 1,
      "delivery_id": "stripe-success",
      "event_type": "invoice.payment_succeeded",
      "provider": "stripe",
      "status": "success"
    },
    {
      "timestamp_utc": "2026-07-28T17:56:00.000Z",
      "attempt": 1,
      "delivery_id": "stripe-duplicate",
      "event_type": "invoice.payment_succeeded",
      "provider": "stripe",
      "status": "deduplicated"
    },
    {
      "timestamp_utc": "2026-07-28T17:55:00.000Z",
      "attempt": 1,
      "delivery_id": "github-recovered",
      "event_type": "push",
      "provider": "github",
      "status": "failed"
    },
    {
      "timestamp_utc": "2026-07-28T17:54:00.000Z",
      "attempt": 2,
      "delivery_id": "github-recovered",
      "event_type": "push",
      "provider": "github",
      "status": "success"
    },
    {
      "timestamp_utc": "2026-07-28T17:53:00.000Z",
      "attempt": 1,
      "delivery_id": "github-success",
      "event_type": "push",
      "provider": "github",
      "status": "success"
    },
    {
      "timestamp_utc": "2026-07-28T17:52:00.000Z",
      "attempt": 1,
      "delivery_id": "github-duplicate",
      "event_type": "push",
      "provider": "github",
      "status": "deduplicated"
    }
  ],
  "expectedOutput": {
    "columns": [
      "provider",
      "event_type",
      "deliveries",
      "recovered",
      "permanent_failures",
      "duplicates_suppressed"
    ],
    "rows": [
      {
        "provider": "stripe",
        "event_type": "invoice.payment_succeeded",
        "deliveries": 4,
        "recovered": 1,
        "permanent_failures": 1,
        "duplicates_suppressed": 1
      },
      {
        "provider": "github",
        "event_type": "push",
        "deliveries": 3,
        "recovered": 1,
        "permanent_failures": 0,
        "duplicates_suppressed": 1
      }
    ]
  },
  "notes": [
    "The included synthetic input rows generate the expected output when timestamps are shifted into the documented query window.",
    "Run this fixture in the public browser SQL playground; the selected query executes locally with DuckDB-Wasm.",
    "Adapt time windows, thresholds, identities, and business definitions before operational use."
  ]
}