-- Recommendation observability (#796 phase 4). Per-source play outcomes so the
-- operator can see whether each recommendation surface is landing and tune the
-- taste weights. Source is stamped on play_events when a play is launched from
-- a recommendation surface; NULL means the user picked the track manually —
-- those rows are INCLUDED here as the baseline control group the surfaces are
-- judged against (milestone #127: delta-vs-baseline is what makes the numbers
-- actionable). Raw source strings are bucketed into stable surface families in
-- the Go handler; completion_n is carried so family merges can weight
-- avg_completion correctly.

-- name: RecommendationSourceMetricsForUser :many
-- $1 user_id, $2 window_days. plays/skips are counts; avg_completion is the
-- mean completion ratio over the completion_n plays that recorded one.
SELECT
    pe.source,
    count(*)::bigint AS plays,
    count(*) FILTER (WHERE pe.was_skipped)::bigint AS skips,
    count(pe.completion_ratio)::bigint AS completion_n,
    COALESCE(avg(pe.completion_ratio), 0)::float8 AS avg_completion
FROM play_events pe
WHERE pe.user_id = $1
  AND pe.started_at > now() - ($2::float8 * INTERVAL '1 day')
GROUP BY pe.source
ORDER BY plays DESC;
