# ETAPA 1 — Fundación de datos (esquema + RLS + seed)

> Prompt versionado (Patrón B.1). Claude Code lo ejecuta tras leer `CLAUDE.md`, `ARCHITECTURE.md`,
> `DATA_MODEL.md`, `docs/adr/ADR-001-*` y `sprints/sprint-1/BRIEF.md`.

## 1. Objetivo
Implementar el modelo de datos completo en Supabase: migraciones, RLS, constraints de privacidad,
función de agregación con k-anonimato, tablas de consentimiento inmutables, y seed de la encuesta de
mapeo de cuidadores. Es la base verificable del producto.

## 2. Contexto previo
Proyecto nuevo. No hay esquema todavía. El contrato de datos está en `DATA_MODEL.md` y la
justificación de cada decisión de privacidad en `ADR-001`. Esta es la primera etapa de código del
proyecto; no hay deuda previa.

## 3. Decisiones ya tomadas (no consultar de nuevo)
- Encuestas anónimas a nivel respondente; `company_id` + cuasi-identificadores SE conservan.
- `respondent_id` reservado pero **NULL** (las 4 encuestas de v1 son anónimas).
- Dedup por `ip_hash`. Cuasi-identificadores en **bucket** (rango etario, no fecha exacta).
- Modo A (`controller_role = 'A'`). Consentimiento granular versionado **inmutable**.
- Umbral de k-anonimato default = 5 (`surveys.k_threshold`).
- Dos ejes de clasificación: `data_sensitivity` (legal) y `security_class` (seguridad), ortogonales.
- Stack: Supabase (Postgres + RLS). Migraciones SQL versionadas.

## 4. Tareas
1. Crear migraciones para todas las tablas de `DATA_MODEL.md` (`organizations`, `surveys`,
   `questions`, `responses`, `answers`, `consent_versions`, `consent_records`) con tipos, FKs e
   índices razonables.
2. Trigger/constraint: rechazar `INSERT`/`UPDATE` en `responses` con `respondent_id` no nulo cuando
   la `survey` referida tiene `is_anonymous = true`.
3. Inmutabilidad de consentimiento: revocar/denegar `UPDATE` y `DELETE` sobre `consent_records` y
   `consent_versions` (vía RLS o trigger).
4. Función `agg_segment(p_survey_id uuid, p_dimensions text[])`: agrega por las dimensiones pedidas y
   **suprime** (devuelve marcador de "n insuficiente") toda celda con `count < k_threshold`.
5. Policies de RLS según "Intención de RLS" de `DATA_MODEL.md`: ninguna policy devuelve filas crudas
   de `responses`/`answers` a un rol de organización; el acceso de organización es solo vía agregados
   por encima del umbral.
6. Seed: cargar la encuesta de mapeo de cuidadores como `survey` (anónima, sensible, confidencial,
   Modo A) + sus `questions` con códigos del mockup (B1/B2/B4/B5, C1, D1, G4, H1 con `max_select=3`,
   H3 texto libre) + `conditional_rules` (B1/C1/D1 despliegan sus sub-preguntas). Cargar 1
   `organization` de prueba y 1 `consent_version` v1 con scopes `["operativo","macro_n1"]`.

## 5. Entregables / Definition of Done
- [ ] Migraciones aplican limpio desde cero (`supabase db reset` o equivalente).
- [ ] Esquema coincide 1:1 con `DATA_MODEL.md`.
- [ ] Tests (ver sección 6) verdes.
- [ ] Seed cargado y consultable.
- [ ] `git diff --name-only HEAD` contiene solo archivos de migración/seed/test autorizados.

## 6. Validaciones automatizadas mandatorias (antes de entregar)
Correr y reportar resultado de cada una:
- `supabase db reset` (o migración desde cero) sin errores.
- Test RLS: como rol de `organization`, un `SELECT *` sobre `responses` de otra org devuelve 0 filas;
  sobre la propia org también 0 filas crudas (solo agregados permitidos).
- Test constraint: `INSERT` en `responses` con `respondent_id` no nulo en encuesta anónima → ERROR.
- Test k-anonimato: `agg_segment` sobre un segmento sembrado con 3 respuestas → "n insuficiente";
  con ≥5 → valor real.
- Test inmutabilidad: `UPDATE` y `DELETE` sobre `consent_records` → ERROR.
- Verificación de seed: la encuesta tiene todas las preguntas esperadas y las reglas condicionales
  enlazan a las preguntas correctas (conteo concreto, no "se cargó bien").
- Si CUALQUIERA falla: **NO entregar**. Reportar el fallo y esperar instrucciones.

## 7. Qué reportar (formato)
- **Verificado:** resultado concreto de cada validación (nº de tablas, nº de tests, salida de
  `agg_segment` para n=3 y n=5, conteo de preguntas y de reglas del seed).
- **Asumido:** cualquier supuesto tomado (ej. tipos de columna no especificados, nombres de roles).
- **Hallazgos no esperados:** lo que descubriste y merece decisión, aunque no esté en el DoD.
- **Decisiones por iniciativa:** clasificadas por nivel (ver política en `CLAUDE.md`).
- **`git diff --name-only HEAD`:** pegá la salida.

## 8. Qué NO hacer
- NO construir frontend, formulario ni dashboard (otras etapas).
- NO usar `respondent_id` (va NULL).
- NO implementar Modo B ni lógica dual de `controller_role`.
- NO exponer texto libre crudo en ninguna vista/función analítica.
- NO tocar nada de privacidad/anonimato/consentimiento de forma distinta a ADR-001 sin consultar
  (es Nivel 3 siempre).
- Ante colisión entre una restricción y "build/tests limpios": **DETENERSE y reportar el conflicto**,
  no resolver unilateralmente.
