diff --git a/supabase/migrations/20260626000002_fix_rpc_me_carrera_congelada.sql b/supabase/migrations/20260626000002_fix_rpc_me_carrera_congelada.sql new file mode 100644 index 0000000..e42c713 --- /dev/null +++ b/supabase/migrations/20260626000002_fix_rpc_me_carrera_congelada.sql @@ -0,0 +1,73 @@ +-- BUG-001 — Fix filtro "Ninguna de las anteriores" en rpc_me_carrera_congelada +-- +-- PROBLEMA: la migración anterior (20260626000001) dejó en el subquery interno: +-- AND a.value #>> '{}' != 'Ninguna de las anteriores' +-- El operador `#>> '{}'` aplicado sobre un ARRAY jsonb no extrae elementos; +-- convierte todo el array a su representación textual (ej. '["opcion","Ninguna..."]'), +-- por lo que la comparación nunca descarta el elemento deseado. +-- +-- SOLUCIÓN: mover el filtro al WHERE del subquery expandido, donde `opt` ya existe +-- como elemento individual resultado de jsonb_array_elements_text. + +CREATE OR REPLACE FUNCTION public.rpc_me_carrera_congelada( + p_survey_id uuid, + p_filters jsonb DEFAULT '{}'::jsonb +) +RETURNS jsonb +LANGUAGE plpgsql STABLE SECURITY DEFINER +SET search_path = public +AS $$ +DECLARE + v_f record; + v_n bigint; + v_cong bigint; + v_rows jsonb; +BEGIN + SELECT * INTO v_f FROM public._dash_parse_filters(p_filters); + + SELECT + count(*), + count(*) FILTER ( + WHERE CASE WHEN jsonb_typeof(a.value) = 'array' + THEN jsonb_array_length(a.value - 'Ninguna de las anteriores') > 0 + ELSE false + END + ) + INTO v_n, v_cong + FROM public._dash_responses(p_survey_id, v_f.f_depto, v_f.f_genero, v_f.f_etario, v_f.f_modalidad) dr + JOIN public.answers a ON a.response_id = dr.response_id + JOIN public.questions q ON q.id = a.question_id AND q.code = '7.5' + WHERE public._dash_es_cuidador(dr.response_id); + + IF v_n < 5 THEN + RETURN jsonb_build_object('status','suppressed','min_n',5,'n',v_n); + END IF; + + SELECT jsonb_agg(row ORDER BY cnt DESC) INTO v_rows FROM ( + SELECT jsonb_build_object('opcion', opt, 'n', cnt, 'pct', ROUND(cnt::numeric / v_n * 100, 1)) AS row, + cnt + FROM ( + SELECT opt, count(DISTINCT response_id) AS cnt + FROM ( + SELECT jsonb_array_elements_text(a.value) AS opt, + dr.response_id + FROM public._dash_responses(p_survey_id, v_f.f_depto, v_f.f_genero, v_f.f_etario, v_f.f_modalidad) dr + JOIN public.answers a ON a.response_id = dr.response_id + JOIN public.questions q ON q.id = a.question_id AND q.code = '7.5' + WHERE public._dash_es_cuidador(dr.response_id) + AND jsonb_typeof(a.value) = 'array' + ) expanded + WHERE opt != 'Ninguna de las anteriores' + GROUP BY opt + ) sub + WHERE cnt >= 5 + ) t; + + RETURN jsonb_build_object( + 'status', 'ok', + 'n', v_n, + 'pct_carrera_congelada', ROUND(v_cong::numeric / v_n * 100, 1), + 'top_opciones', COALESCE(v_rows, '[]'::jsonb) + ); +END; +$$;