{
  "license": "CC BY 4.0",
  "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
  "recipe": {
    "slug": "funnel-conversion-by-source",
    "title": "Compare Funnel Conversion by Acquisition Source",
    "testedWith": "Apache DataFusion 45.2.0",
    "lastReviewed": "2026-07-27"
  },
  "contract": {
    "tableName": "product_events",
    "schema": [
      {
        "name": "timestamp_utc",
        "type": "Timestamp",
        "description": "Event time."
      },
      {
        "name": "user_id",
        "type": "Utf8",
        "description": "Stable user identifier."
      },
      {
        "name": "event_name",
        "type": "Utf8",
        "description": "signup_completed or first_meaningful_action_completed."
      },
      {
        "name": "acquisition_source",
        "type": "Utf8",
        "description": "First-touch or agreed attribution source."
      }
    ]
  },
  "query": "WITH users AS (\n  SELECT\n    user_id,\n    MIN(acquisition_source) AS acquisition_source,\n    MAX(CASE WHEN event_name = 'signup_completed' THEN 1 ELSE 0 END) AS signed_up,\n    MAX(CASE WHEN event_name = 'first_meaningful_action_completed' THEN 1 ELSE 0 END) AS activated\n  FROM product_events\n  WHERE timestamp_utc >= now() - INTERVAL '30 days'\n  GROUP BY user_id\n)\nSELECT\n  acquisition_source,\n  SUM(signed_up) AS signups,\n  SUM(activated) AS activated_users,\n  100.0 * SUM(activated) / NULLIF(SUM(signed_up), 0) AS activation_rate_pct\nFROM users\nWHERE signed_up = 1\nGROUP BY acquisition_source\nHAVING SUM(signed_up) >= 20\nORDER BY activation_rate_pct DESC;",
  "fixtureKind": "schema-example",
  "inputRows": [
    {
      "timestamp_utc": "2026-07-28T10:00:00Z",
      "user_id": "user_1",
      "event_name": "workflow_completed",
      "acquisition_source": "acquisition_source_example_1"
    },
    {
      "timestamp_utc": "2026-07-28T11:00:00Z",
      "user_id": "user_2",
      "event_name": "workflow_completed",
      "acquisition_source": "acquisition_source_example_2"
    },
    {
      "timestamp_utc": "2026-07-28T12:00:00Z",
      "user_id": "user_3",
      "event_name": "workflow_completed",
      "acquisition_source": "acquisition_source_example_3"
    }
  ],
  "illustrativeInputRows": [
    {
      "timestamp_utc": "2026-07-28T10:00:00Z",
      "user_id": "user_1",
      "event_name": "workflow_completed",
      "acquisition_source": "acquisition_source_example_1"
    },
    {
      "timestamp_utc": "2026-07-28T11:00:00Z",
      "user_id": "user_2",
      "event_name": "workflow_completed",
      "acquisition_source": "acquisition_source_example_2"
    },
    {
      "timestamp_utc": "2026-07-28T12:00:00Z",
      "user_id": "user_3",
      "event_name": "workflow_completed",
      "acquisition_source": "acquisition_source_example_3"
    }
  ],
  "expectedOutput": {
    "columns": [
      "acquisition_source",
      "signups",
      "activated_users",
      "activation_rate_pct"
    ],
    "rows": [
      {
        "acquisition_source": "documentation",
        "signups": 420,
        "activated_users": 218,
        "activation_rate_pct": 51.9
      },
      {
        "acquisition_source": "organic_search",
        "signups": 980,
        "activated_users": 392,
        "activation_rate_pct": 40
      },
      {
        "acquisition_source": "paid_social",
        "signups": 610,
        "activated_users": 128,
        "activation_rate_pct": 20.98
      }
    ]
  },
  "notes": [
    "The compact input rows demonstrate field names and JSON types; they are not claimed to generate the displayed aggregate by themselves.",
    "The expected output is deterministic synthetic review data for the documented output shape.",
    "Adapt time windows, thresholds, identities, and business definitions before operational use."
  ]
}