-- ============================================================= -- Attendance statistics view for GM analytics -- Returns per-player aggregated metrics for a given game group. -- NOTE: waitlist count reflects CURRENT registration_status only. -- Full historical waitlist tracking will come with #15. -- ============================================================= CREATE OR REPLACE FUNCTION get_group_attendance_stats(p_group_id UUID) RETURNS TABLE ( player_id UUID, display_name VARCHAR, telegram_username VARCHAR, total_sessions BIGINT, confirmed_count BIGINT, declined_count BIGINT, no_response_count BIGINT, waitlisted_count BIGINT, cancellation_affected_count BIGINT, attendance_rate NUMERIC ) AS $$ BEGIN RETURN QUERY WITH player_sessions AS ( SELECT sp.player_id, s.id AS session_id, sp.rsvp_status, sp.registration_status, s.status AS session_status, s.scheduled_at FROM session_participants sp JOIN sessions s ON s.id = sp.session_id WHERE s.group_id = p_group_id ), player_totals AS ( SELECT ps.player_id, COUNT(*) FILTER (WHERE ps.session_status <> 'Cancelled') AS total_sessions, COUNT(*) FILTER (WHERE ps.rsvp_status = 'Confirmed' AND ps.session_status <> 'Cancelled') AS confirmed_count, COUNT(*) FILTER (WHERE ps.rsvp_status = 'Declined' AND ps.session_status <> 'Cancelled') AS declined_count, COUNT(*) FILTER (WHERE ps.rsvp_status = 'Pending' AND ps.scheduled_at < NOW() AND ps.session_status <> 'Cancelled') AS no_response_count, COUNT(*) FILTER (WHERE ps.registration_status = 'Waitlisted' AND ps.session_status <> 'Cancelled') AS waitlisted_count, COUNT(*) FILTER (WHERE ps.session_status = 'Cancelled') AS cancellation_affected_count FROM player_sessions ps GROUP BY ps.player_id ) SELECT pt.player_id, p.display_name, p.telegram_username, pt.total_sessions, pt.confirmed_count, pt.declined_count, pt.no_response_count, pt.waitlisted_count, pt.cancellation_affected_count, ROUND( 100.0 * pt.confirmed_count / NULLIF(pt.total_sessions, 0), 1 ) AS attendance_rate FROM player_totals pt JOIN players p ON p.id = pt.player_id ORDER BY pt.confirmed_count DESC, pt.total_sessions DESC; END; $$ LANGUAGE plpgsql STABLE;