Files
2026-06-11 16:56:17 -03:00

4.8 KiB

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:

-- 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 <a> 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.