-- Sprint 4 (v3.0.0) — Fix puntual: _dash_responses filtraba género/modalidad -- contra códigos v2 ('A6'/'A7') que no existen en el esquema v3. El filtro -- devolvía 0 filas SIN error — silencioso, indistinguible de "no hay nadie -- con ese filtro". Es una trampa: alguien podría leer "ningún hombre es -- cuidador" cuando en realidad el filtro nunca encontró la pregunta. -- -- Mapeo: A6 (género, v2) → 2.5 (género, v3) · A7 (modalidad, v2) → 2.7 (modalidad, v3). -- -- Alcance: SOLO este helper compartido. Las 9 RPCs viejas de v2 (migración -- 20260605140001_012_dashboard_rpc_v2.sql) NO se tocan — sus propias -- comparaciones de código (1.1, 1.6, 1.13, 4.3, 6.1, 6.2, 6.5, etc.) siguen -- sin migrar (Etapa 4H, pendiente de confirmación aparte, no se resuelve -- acá). Este fix no las rompe: ninguna de esas 9 RPCs compara 'A6'/'A7' -- directamente, solo le pasan arrays de filtro (p_genero/p_modalidad) a esta -- función — que ahora los evalúa contra preguntas que SÍ existen en v3. CREATE OR REPLACE FUNCTION public._dash_responses( p_survey_id uuid, p_depto text DEFAULT NULL, p_genero text[] DEFAULT NULL, p_etario text[] DEFAULT NULL, p_modalidad text[] DEFAULT NULL ) RETURNS TABLE(response_id uuid) LANGUAGE sql STABLE SECURITY DEFINER SET search_path = public AS $$ SELECT r.id FROM public.responses r WHERE (p_survey_id = '00000000-0000-0000-0000-000000000000' OR r.survey_id = p_survey_id) AND (p_depto IS NULL OR r.qi_zone = p_depto) AND (p_genero IS NULL OR cardinality(p_genero) = 0 OR EXISTS ( SELECT 1 FROM public.answers a JOIN public.questions q ON q.id = a.question_id WHERE a.response_id = r.id AND q.code = '2.5' AND a.value #>> '{}' = ANY(p_genero) )) AND (p_etario IS NULL OR cardinality(p_etario) = 0 OR r.qi_age_bucket = ANY(p_etario)) AND (p_modalidad IS NULL OR cardinality(p_modalidad) = 0 OR EXISTS ( SELECT 1 FROM public.answers a JOIN public.questions q ON q.id = a.question_id WHERE a.response_id = r.id AND q.code = '2.7' AND a.value #>> '{}' = ANY(p_modalidad) )); $$;