# ETAPA 3ALL — Flag p_all en el dashboard (vista agregada de todos los surveys) ## 1. Objetivo Permitir que el dashboard muestre datos de TODOS los surveys mezclados, usando un UUID especial como flag. Cambio mínimo — solo toca `_dash_responses` y el frontend. Las 11 RPCs no se modifican. --- ## 2. Contexto previo - `_dash_responses(p_survey_id uuid, ...)` es la función base que usan las 11 RPCs. - Todas las RPCs pasan `p_survey_id` a `_dash_responses`. - El dashboard lee `?survey_id=UUID` de la URL y lo pasa a `/api/dashboard/[widget]`. - `route.ts` requiere `survey_id` en la query string (400 si falta). ## 3. DECISIONES YA TOMADAS — no consultar de nuevo - UUID especial para "todos": `00000000-0000-0000-0000-000000000000` (UUID cero). No puede existir como survey real. Es el flag `p_all`. - Implementación en `_dash_responses`: una sola línea cambia. - Las 11 RPCs NO se tocan — el cambio es transparente para ellas. - El cambio va en una NUEVA migración, no modifica las existentes. - El k-anonimato sigue aplicando — el pool más grande solo beneficia la protección. --- ## 4. Cambios requeridos ### 4.1 Nueva migración SQL Crear `supabase/migrations/20260611000001_dash_responses_all.sql`: ```sql -- Migración: agregar flag p_all a _dash_responses -- UUID especial '00000000-0000-0000-0000-000000000000' = todos los surveys 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 = 'A6' 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 = 'A7' AND a.value #>> '{}' = ANY(p_modalidad) )); $$; ``` ### 4.2 route.ts — permitir el UUID especial En `app/api/dashboard/[widget]/route.ts`, donde se valida `survey_id`: El UUID cero debe pasar la validación existente — verificar si hay algún check adicional que lo rechazaría (ej. validación de formato UUID o lookup en DB). Si `route.ts` solo verifica presencia del parámetro (400 si falta), no hay nada que cambiar. Reportar cuál es el caso. ### 4.3 dashboard/page.tsx — agregar link/selector "Todos" Agregar en el header del dashboard un selector o links de navegación mínimo: ``` [ Todos ] [ InQuality ] [ Fundación Solidaridad ] [ Demo ] ``` Implementación sugerida: links `` simples que navegan a: - Todos: `/dashboard?survey_id=00000000-0000-0000-0000-000000000000` - InQuality: `/dashboard?survey_id=30000000-0000-0000-0000-000000000002` - Fundación Solidaridad: `/dashboard?survey_id=30000000-0000-0000-0000-000000000003` - Demo: `/dashboard?survey_id=30000000-0000-0000-0000-000000000001` El survey activo se destaca visualmente (comparar `surveyId` del searchParam con el UUID de cada link). Estilo `.admin-*` no aplica acá — usar clases `.db-*` o tokens CSS existentes del dashboard. El label de cada opción puede ser hardcodeado por ahora — no hacer fetch a `surveys` para obtener los nombres (Nivel 3, fuera de scope). --- ## 5. Entregables (DoD) - [ ] Nueva migración `20260611000001_dash_responses_all.sql` creada. - [ ] `_dash_responses` actualizada con el flag de UUID cero. - [ ] `route.ts` permite el UUID especial (verificar y reportar). - [ ] Dashboard muestra selector de empresa con "Todos" + las 3 empresas. - [ ] Build exitoso. - [ ] `git diff --name-only HEAD` en scope. ## 6. Qué reportar ``` Verificado: - Migración creada ✓ - route.ts: [necesitó cambio / no necesitó cambio — explicar] - Selector visible en dashboard ✓ - Build exitoso ✓ - Diff en scope ✓ URL de validación: - Todos: /dashboard?survey_id=00000000-0000-0000-0000-000000000000 - InQuality: /dashboard?survey_id=30000000-0000-0000-0000-000000000002 ``` ## 7. Qué NO hacer - ❌ No modificar las migraciones existentes — solo agregar una nueva. - ❌ No tocar las 11 RPCs directamente. - ❌ No hacer fetch a `surveys` para obtener nombres de empresa. - ❌ No agregar dependencias npm. - ❌ No tocar el formulario ni `/admin/responses`.