{
  "license": "CC BY 4.0",
  "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
  "recipe": {
    "slug": "event-schema-field-coverage",
    "title": "Catch event-field renames that hide rows from averages",
    "testedWith": "Apache DataFusion 45.2.0",
    "lastReviewed": "2026-09-30"
  },
  "contract": {
    "tableName": "job_finished",
    "schema": [
      {
        "name": "timestamp_utc",
        "type": "Timestamp",
        "description": "UTC finish-event time; use a fixed analysis window in production."
      },
      {
        "name": "job_id",
        "type": "Utf8",
        "description": "One fictional completed logical job per row."
      },
      {
        "name": "schema_version",
        "type": "Int64",
        "description": "Version of the event contract; 1 uses duration_ms and 2 uses latency_ms."
      },
      {
        "name": "duration_ms",
        "type": "Int64",
        "description": "Release-1 duration, null on release 2."
      },
      {
        "name": "latency_ms",
        "type": "Int64",
        "description": "Release-2 duration, null on release 1."
      }
    ]
  },
  "query": "WITH normalized AS (\n  SELECT\n    job_id,\n    schema_version,\n    duration_ms,\n    CASE schema_version\n      WHEN 1 THEN duration_ms\n      WHEN 2 THEN latency_ms\n    END AS measured_ms\n  FROM job_finished\n)\nSELECT\n  COUNT(*) AS completed_jobs,\n  COUNT(duration_ms) AS jobs_in_old_average,\n  ROUND(AVG(duration_ms), 1) AS old_average_ms,\n  COUNT(measured_ms) AS jobs_with_duration,\n  SUM(CASE WHEN measured_ms IS NULL THEN 1 ELSE 0 END) AS unmeasured_jobs,\n  ROUND(100.0 * COUNT(measured_ms) / NULLIF(COUNT(*), 0), 1)\n    AS duration_coverage_pct,\n  ROUND(AVG(measured_ms), 1) AS schema_aware_average_ms\nFROM normalized;",
  "fixtureKind": "reproducible",
  "inputRows": [
    {
      "timestamp_utc": "2026-09-28T09:00:00Z",
      "job_id": "toy-01",
      "schema_version": 1,
      "duration_ms": 420,
      "latency_ms": null
    },
    {
      "timestamp_utc": "2026-09-28T09:02:00Z",
      "job_id": "toy-02",
      "schema_version": 1,
      "duration_ms": 530,
      "latency_ms": null
    },
    {
      "timestamp_utc": "2026-09-29T09:00:00Z",
      "job_id": "toy-03",
      "schema_version": 2,
      "duration_ms": null,
      "latency_ms": 610
    },
    {
      "timestamp_utc": "2026-09-29T09:02:00Z",
      "job_id": "toy-04",
      "schema_version": 2,
      "duration_ms": null,
      "latency_ms": 760
    }
  ],
  "illustrativeInputRows": [
    {
      "timestamp_utc": "2026-09-28T09:00:00Z",
      "job_id": "toy-01",
      "schema_version": 1,
      "duration_ms": 420,
      "latency_ms": null
    },
    {
      "timestamp_utc": "2026-09-28T09:02:00Z",
      "job_id": "toy-02",
      "schema_version": 1,
      "duration_ms": 530,
      "latency_ms": null
    },
    {
      "timestamp_utc": "2026-09-29T09:00:00Z",
      "job_id": "toy-03",
      "schema_version": 2,
      "duration_ms": null,
      "latency_ms": 610
    },
    {
      "timestamp_utc": "2026-09-29T09:02:00Z",
      "job_id": "toy-04",
      "schema_version": 2,
      "duration_ms": null,
      "latency_ms": 760
    }
  ],
  "expectedOutput": {
    "columns": [
      "completed_jobs",
      "jobs_in_old_average",
      "old_average_ms",
      "jobs_with_duration",
      "unmeasured_jobs",
      "duration_coverage_pct",
      "schema_aware_average_ms"
    ],
    "rows": [
      {
        "completed_jobs": 4,
        "jobs_in_old_average": 2,
        "old_average_ms": 475,
        "jobs_with_duration": 4,
        "unmeasured_jobs": 0,
        "duration_coverage_pct": 100,
        "schema_aware_average_ms": 580
      }
    ]
  },
  "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."
  ]
}