{
  "license": "CC BY 4.0",
  "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
  "recipe": {
    "slug": "feature-adoption-before-upgrade",
    "title": "Find Features Used Before Upgrade",
    "testedWith": "Apache DataFusion 45.2.0",
    "lastReviewed": "2026-07-27"
  },
  "contract": {
    "tableName": "product_events",
    "schema": [
      {
        "name": "timestamp_utc",
        "type": "Timestamp",
        "description": "When the event occurred."
      },
      {
        "name": "team_id",
        "type": "Utf8",
        "description": "Stable account or workspace identifier."
      },
      {
        "name": "event_name",
        "type": "Utf8",
        "description": "Product event name."
      },
      {
        "name": "feature_name",
        "type": "Utf8",
        "description": "Stable feature identifier for feature_used events."
      }
    ]
  },
  "query": "WITH upgrades AS (\n  SELECT\n    team_id,\n    MIN(timestamp_utc) AS upgraded_at\n  FROM product_events\n  WHERE event_name = 'plan_upgraded'\n  GROUP BY team_id\n),\npre_upgrade_features AS (\n  SELECT DISTINCT\n    e.team_id,\n    e.feature_name\n  FROM product_events e\n  JOIN upgrades u ON e.team_id = u.team_id\n  WHERE e.event_name = 'feature_used'\n    AND e.timestamp_utc < u.upgraded_at\n    AND e.timestamp_utc >= u.upgraded_at - INTERVAL '30 days'\n)\nSELECT\n  feature_name,\n  COUNT(DISTINCT team_id) AS upgraded_teams_using_feature\nFROM pre_upgrade_features\nGROUP BY feature_name\nORDER BY upgraded_teams_using_feature DESC;",
  "fixtureKind": "schema-example",
  "inputRows": [
    {
      "timestamp_utc": "2026-07-28T10:00:00Z",
      "team_id": "team_id_example_1",
      "event_name": "workflow_completed",
      "feature_name": "feature_name_example_1"
    },
    {
      "timestamp_utc": "2026-07-28T11:00:00Z",
      "team_id": "team_id_example_2",
      "event_name": "workflow_completed",
      "feature_name": "feature_name_example_2"
    },
    {
      "timestamp_utc": "2026-07-28T12:00:00Z",
      "team_id": "team_id_example_3",
      "event_name": "workflow_completed",
      "feature_name": "feature_name_example_3"
    }
  ],
  "illustrativeInputRows": [
    {
      "timestamp_utc": "2026-07-28T10:00:00Z",
      "team_id": "team_id_example_1",
      "event_name": "workflow_completed",
      "feature_name": "feature_name_example_1"
    },
    {
      "timestamp_utc": "2026-07-28T11:00:00Z",
      "team_id": "team_id_example_2",
      "event_name": "workflow_completed",
      "feature_name": "feature_name_example_2"
    },
    {
      "timestamp_utc": "2026-07-28T12:00:00Z",
      "team_id": "team_id_example_3",
      "event_name": "workflow_completed",
      "feature_name": "feature_name_example_3"
    }
  ],
  "expectedOutput": {
    "columns": [
      "feature_name",
      "upgraded_teams_using_feature"
    ],
    "rows": [
      {
        "feature_name": "shared_dashboard",
        "upgraded_teams_using_feature": 184
      },
      {
        "feature_name": "alert_created",
        "upgraded_teams_using_feature": 151
      },
      {
        "feature_name": "scheduled_export",
        "upgraded_teams_using_feature": 112
      },
      {
        "feature_name": "ai_query",
        "upgraded_teams_using_feature": 97
      }
    ]
  },
  "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."
  ]
}