-- Build one explicitly point-in-time row per episode. All predictors carrying -- history use a window ending at one episode preceding the target. CREATE OR REPLACE TABLE episode_history AS WITH history_windows AS ( SELECT e.*, count(*) OVER prior_all AS prior_episode_count, coalesce(sum(attempt_count) OVER prior_all, 0) AS prior_total_attempt_count, count(first_outcome) OVER prior_all AS prior_labeled_episode_count, lag(attempt_count) OVER by_vehicle AS prior_attempt_count, lag(first_outcome) OVER by_vehicle AS prior_first_outcome, lag(final_outcome) OVER by_vehicle AS prior_final_outcome, lag(episode_start) OVER by_vehicle AS prior_episode_start, max(CASE WHEN first_outcome IN ('fail', 'reject', 'abort') THEN episode_start END) OVER prior_all AS prior_adverse_episode_start, count(*) FILTER (WHERE first_outcome = 'pass') OVER prior_all AS prior_pass_count, count(*) FILTER (WHERE first_outcome = 'fail') OVER prior_all AS prior_fail_count, count(*) FILTER (WHERE first_outcome = 'reject') OVER prior_all AS prior_reject_count, count(*) FILTER (WHERE first_outcome = 'abort') OVER prior_all AS prior_abort_count, count(*) FILTER ( WHERE first_outcome IN ('fail', 'reject', 'abort') ) OVER prior_all AS prior_nonpass_count, count(first_outcome) OVER prior_three AS last3_labeled_episode_count, count(*) FILTER ( WHERE first_outcome IN ('fail', 'reject', 'abort') ) OVER prior_three AS last3_nonpass_count, max(max_events_in_day) OVER prior_all AS prior_max_events_in_day, arg_max(episode_last_observed_make, episode_number) FILTER (WHERE episode_last_observed_make IS NOT NULL) OVER prior_all AS last_observed_make, arg_max(episode_last_observed_model, episode_number) FILTER (WHERE episode_last_observed_model IS NOT NULL) OVER prior_all AS last_observed_model, arg_max(episode_last_observed_model_year, episode_number) FILTER (WHERE episode_last_observed_model_year IS NOT NULL) OVER prior_all AS last_observed_model_year FROM inspection_episodes AS e WINDOW by_vehicle AS ( PARTITION BY vehicle_token ORDER BY episode_number ), prior_all AS ( PARTITION BY vehicle_token ORDER BY episode_number ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ), prior_three AS ( PARTITION BY vehicle_token ORDER BY episode_number ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING ) ) SELECT *, CASE WHEN prior_episode_start IS NULL THEN NULL ELSE extract(epoch FROM (episode_start - prior_episode_start)) / 86400.0 END AS days_since_prior_episode, CASE WHEN prior_adverse_episode_start IS NULL THEN NULL ELSE extract(epoch FROM (episode_start - prior_adverse_episode_start)) / 86400.0 END AS days_since_prior_adverse, prior_nonpass_count::DOUBLE / nullif(prior_labeled_episode_count, 0) AS prior_nonpass_rate, prior_pass_count::DOUBLE / nullif(prior_labeled_episode_count, 0) AS prior_pass_rate, last3_nonpass_count::DOUBLE / nullif(last3_labeled_episode_count, 0) AS last3_nonpass_rate FROM history_windows; CREATE OR REPLACE TABLE feature_mart AS SELECT vehicle_token, vehicle_bucket, vehicle_bucket < 10 AS is_vin_audit, episode_number::BIGINT AS episode_number, episode_start, first_outcome, first_outcome_label_source AS target_outcome_label_source, CASE WHEN first_outcome = 'pass' THEN 0 WHEN first_outcome IN ('fail', 'reject', 'abort') THEN 1 ELSE NULL END::INTEGER AS target_nonpass, episode_start >= TIMESTAMP '2016-01-01' AND first_outcome IS NOT NULL AND prior_episode_count >= 1 AND prior_total_attempt_count <= 50 AND coalesce(prior_max_events_in_day, 0) <= 4 AS eligible_returning_target, CASE WHEN episode_start < TIMESTAMP '2016-01-01' THEN 'historical_context' WHEN episode_start < TIMESTAMP '2023-01-01' THEN 'train' WHEN episode_start < TIMESTAMP '2024-01-01' THEN 'tune' WHEN episode_start < TIMESTAMP '2025-01-01' THEN 'calibrate' WHEN episode_start < TIMESTAMP '2026-01-01' THEN 'test' WHEN episode_start < TIMESTAMP '2027-01-01' THEN 'shadow' ELSE 'out_of_scope' END AS temporal_partition, CASE WHEN episode_start < TIMESTAMP '2016-01-01' THEN 'before_target_period' WHEN first_outcome IS NULL THEN 'unlabeled_first_outcome' WHEN prior_episode_count < 1 THEN 'cold_start' WHEN prior_total_attempt_count > 50 THEN 'prior_event_count_over_50' WHEN coalesce(prior_max_events_in_day, 0) > 4 THEN 'prior_daily_activity_over_4' ELSE NULL END AS eligibility_exclusion_reason, public_county, source_era, CASE WHEN month(episode_start) IN (12, 1, 2) THEN 'winter' WHEN month(episode_start) IN (3, 4, 5) THEN 'spring' WHEN month(episode_start) IN (6, 7, 8) THEN 'summer' ELSE 'fall' END AS target_season, CASE WHEN last_observed_model_year BETWEEN 1886 AND year(episode_start) + 1 THEN greatest(year(episode_start) - last_observed_model_year, 0) ELSE NULL END::INTEGER AS vehicle_age, prior_episode_count, prior_total_attempt_count::BIGINT AS prior_total_attempt_count, prior_attempt_count, days_since_prior_episode, days_since_prior_adverse, prior_nonpass_rate, prior_first_outcome, prior_final_outcome, last_observed_make, last_observed_model, last_observed_model_year, prior_labeled_episode_count, prior_pass_count, prior_fail_count, prior_reject_count, prior_abort_count, prior_nonpass_count, prior_pass_rate, last3_labeled_episode_count, last3_nonpass_count, last3_nonpass_rate, prior_max_events_in_day, prior_first_outcome IS NULL AS prior_first_outcome_missing, last_observed_model_year IS NULL AS prior_model_year_missing, (SELECT source_data_kind FROM build_config) AS source_data_kind, (SELECT population_estimate_allowed FROM build_config) AS population_estimate_allowed FROM episode_history; CREATE OR REPLACE TABLE cohort_flow AS SELECT 'event' AS grain, 'input' AS stage, 'all_rows' AS reason, count(*) AS observation_count, count(DISTINCT try_cast(vehicle_token AS VARCHAR)) AS vehicle_count FROM stg_events UNION ALL SELECT 'event', 'excluded', exclusion_reason, count(*), count(DISTINCT vehicle_token) FROM event_exclusions GROUP BY exclusion_reason UNION ALL SELECT 'event', 'accepted', 'clean_events', count(*), count(DISTINCT vehicle_token) FROM clean_events UNION ALL SELECT 'episode', 'constructed', 'all_episodes', count(*), count(DISTINCT vehicle_token) FROM inspection_episodes UNION ALL SELECT 'episode', 'eligible_returning_target', coalesce(eligibility_exclusion_reason, 'eligible'), count(*), count(DISTINCT vehicle_token) FROM feature_mart GROUP BY coalesce(eligibility_exclusion_reason, 'eligible');