5.1 KiB
ETAPA 1C — Cierre de la fundación: REVOKE del GRANT peligroso + documentación
Prompt versionado (Patrón B.1). Cierra la auditoría de la Etapa 1B con el único cambio bloqueante que encontró y documenta tres decisiones que el agente tomó por iniciativa. Claude Code lo ejecuta tras leer
CLAUDE.md,DATA_MODEL.mdy este prompt.
1. Objetivo
Quitar el GRANT SELECT ON consent_records TO authenticated (puerta apoyada-sin-llave: hoy inerte,
peligrosa si alguien suma una policy SELECT a futuro), confirmar en ejecución que no rompe el flujo
de envío de la encuesta (la FK responses.consent_record_id), y documentar en DATA_MODEL.md tres
decisiones tomadas en la 1B.
2. Contexto previo
La 1B aplicó las migraciones 001-006 a Supabase Cloud y la auditoría aprobó la fundación de datos salvo este punto. La migración 006 ya está aplicada en Cloud → NO se edita (rompería el historial de migraciones). El cambio va en una migración nueva, 007.
3. Decisiones ya tomadas (no consultar de nuevo)
- El cambio es un
REVOKE, en migración nueva 007. NO editar 001-006. - El
GRANT INSERT ON consent_records TO anon, authenticatedse mantiene (el envío del formulario lo necesita). Solo se revoca el SELECT. - NO se agrega ninguna policy SELECT a
consent_records. El analyst lee víaservice_role(que bypassa RLS y no necesita GRANTs). - No se toca el resto del esquema, ni las policies, ni
service_role.
4. Tareas
- Crear la migración con
supabase migration new revoke_consent_selecty poner como contenido:-- 007: Revoca el SELECT sobre consent_records a authenticated. -- Auditoría 1B: GRANT inerte hoy (no hay policy SELECT) pero peligroso si a futuro alguien -- agrega una policy SELECT para org_admin → expondría quién consintió qué, vector de -- correlación con respuestas en encuesta anónima. El analyst lee vía service_role. REVOKE SELECT ON public.consent_records FROM authenticated; - Aplicar a Cloud:
supabase db push(usarnpx supabase ...si el CLI no es global). - Correr las validaciones de la sección 6 contra la base real.
- Documentar en
DATA_MODEL.mdlas tres decisiones (texto exacto en la sección 5 de este prompt).
5. Texto EXACTO a agregar al final de DATA_MODEL.md (sección nueva)
## Decisiones ratificadas en ejecución (Sprint 1)
- **`options` en preguntas `rating` (F3, G4):** se guarda como objeto
`{"min":1,"max":5,"min_label":"...","max_label":"..."}`, NO como array. El frontend (Sprint 2)
debe manejar dos formas de `options`: array para `single_choice`/`multiple_choice`, objeto para
`rating`.
- **`required = false` en todas las preguntas seeded:** la obligatoriedad real se define en Sprint 2
(validación del formulario). Nota: B1 estaba marcada obligatoria en el mockup; revisar al construir
el formulario.
- **Policies de `org_admin` presentes pero inertes en v1:** las policies RLS para `org_admin`
(acceso multi-tenant por empresa) existen en migración 003, pero v1 NO tiene login de cliente
("nosotros presentamos a cada empresa"). El acceso real lo hace el analyst vía `service_role`. El
camino `org_admin` queda reservado para un futuro de auto-servicio, no operado en v1.
6. Validaciones automatizadas mandatorias (contra la base Cloud)
La central es la #1 — confirma que revocar el SELECT NO rompe el envío:
- FK intacta: simulando rol
anon(SET ROLE anon + claims, o vía anon key),INSERTenconsent_records→ obtener su id →INSERTenresponsesreferenciando eseconsent_record_id(consurvey_idde una encuestastatus='live'yrespondent_idNULL) → debe insertar sin error. Esto prueba que la verificación de FK no requiere SELECT sobreconsent_records. - REVOKE efectivo: como
authenticated,SELECT FROM consent_records→ ahora "permission denied" (ya no "0 filas"). Confirma que el revoke aplicó. - Sin regresión: re-correr las claves de la 1B → RLS sobre
responses/answers= 0 filas para org_admin;agg_segmentn=3 → suprimido, n=5 → valor; inmutabilidad deconsent_records(UPDATE/ DELETE → error) sigue vigente. - Si CUALQUIERA falla: NO declarar lista la etapa. Reportar y esperar. En especial, si la #1 fallara (la FK SÍ necesitaba el SELECT), detenerse y reportar — sería el caso que invalida el cambio.
7. Qué reportar
- Verificado: salida concreta de cada validación (el INSERT anónimo que efectivamente insertó, el "permission denied" del SELECT como authenticated, y las 3 de no-regresión).
- Asumido / Hallazgos / Decisiones por iniciativa (clasificadas por nivel).
git diff --name-only HEAD: debe contener solo la migración 007 nueva +DATA_MODEL.md.
8. Qué NO hacer
- NO editar las migraciones 001-006 (006 ya está en Cloud).
- NO agregar policy SELECT a
consent_records. - NO tocar
service_role, ni las policies de org_admin, ni el resto del esquema. - NO usar
respondent_idni exponer texto libre. - Ante conflicto entre una restricción y "que aplique limpio": detenerse y reportar, no resolver unilateralmente.