Files
inq-roi-simulador-web/sprints/sprint-8/ETAPA_1_PROMPT.md
Marcos Benítez de00e3a902
Some checks failed
/ Deploy to Cloudflare Pages (push) Has been cancelled
etapa 3 terminada
2026-07-07 20:19:45 -03:00

6.8 KiB

Sprint 8 — Etapa 1: Migración DB (aditiva)

Tipo: Base de datos — migración aditiva Rama: main Estimación: 1-2 horas Dependencias: Etapa 0 completada


Objetivo

Crear la infraestructura de datos para el modelo organizations → areas → processes sin romper nada de lo que ya funciona. Esta migración es completamente aditiva: crea lo nuevo, no elimina lo viejo. Las columnas client y group_id de processes, y la tabla process_groups, se eliminan en una migration de limpieza posterior (después de que Etapas 3-4 migren la UI).


Contexto del schema actual

Leer las migraciones en supabase/migrations/ antes de escribir cualquier SQL. Schema relevante al momento de esta etapa:

processes — columnas existentes relevantes:

  • client text NOT NULL DEFAULT '' — el campo libre "clientName" (se elimina más adelante)
  • group_id uuid REFERENCES public.process_groups(id) ON DELETE SET NULL — agrupador viejo (se elimina más adelante)
  • org_id uuid REFERENCES public.organizations(id) ON DELETE SET NULL — ← este es el correcto, agregado en migración 014

process_groups — tabla existente:

  • id, name, created_by, created_at, updated_at — no tiene FKs entrantes salvo processes.group_id

organizations — tabla existente desde migración 014:

  • InQuality existe con is_provider = true
  • Otras orgs creadas automáticamente desde processes.client en la migración 014

Funciones SECURITY DEFINER disponibles (migración 015):

  • public.is_inquality() → true si el usuario pertenece a InQuality
  • public.current_org() → org_id del usuario actual
  • public.current_platform_role() → rol del usuario actual
  • public.is_platform_admin() → true si es platform_admin

Alcance estricto — Migration 017

Crear el archivo supabase/migrations/017_create_areas.sql.

Paso 1: Crear tabla areas

-- Nueva tabla areas: reemplazará process_groups como agrupador normalizado por org
CREATE TABLE IF NOT EXISTS public.areas (
  id          uuid        PRIMARY KEY DEFAULT gen_random_uuid(),
  org_id      uuid        NOT NULL REFERENCES public.organizations(id) ON DELETE CASCADE,
  name        text        NOT NULL,
  description text,
  created_at  timestamptz NOT NULL DEFAULT now(),
  updated_at  timestamptz NOT NULL DEFAULT now()
);

ALTER TABLE public.areas ENABLE ROW LEVEL SECURITY;

Paso 2: Agregar area_id a processes

-- area_id reemplazará group_id como agrupador normalizado dentro de una org
-- Nullable: procesos sin área asignada son válidos ("Sin área")
ALTER TABLE public.processes
  ADD COLUMN IF NOT EXISTS area_id uuid REFERENCES public.areas(id) ON DELETE SET NULL;

Paso 3: RLS para areas

-- SELECT: InQuality ve todas las áreas; cliente ve solo las de su org
CREATE POLICY "areas_select" ON public.areas
  FOR SELECT USING (
    public.is_inquality()
    OR org_id = public.current_org()
  );

-- INSERT / UPDATE / DELETE: solo platform_admin
CREATE POLICY "areas_insert" ON public.areas
  FOR INSERT WITH CHECK (
    public.current_platform_role() = 'platform_admin'
  );

CREATE POLICY "areas_update" ON public.areas
  FOR UPDATE USING (
    public.current_platform_role() = 'platform_admin'
  );

CREATE POLICY "areas_delete" ON public.areas
  FOR DELETE USING (
    public.current_platform_role() = 'platform_admin'
  );

Paso 4: Migración de datos — asignar procesos sin org a InQuality

-- Procesos sin org_id son datos de prueba de InQuality.
-- Asignarlos a la org de InQuality (is_provider = true) para limpiar los NULLs.
UPDATE public.processes
SET org_id = (
  SELECT id FROM public.organizations WHERE is_provider = true LIMIT 1
)
WHERE org_id IS NULL;

Lo que esta migración NO hace (intencional)

❌ NO dropea la columna `client` de processes
❌ NO dropea la columna `group_id` de processes
❌ NO dropea la tabla `process_groups`
❌ NO modifica ninguna política RLS existente

Estas eliminaciones ocurren en una migration posterior, después de que la UI deje de usar esas columnas.


Verificación post-migración

Después de aplicar la migración en Supabase (SQL Editor o supabase db push), verificar con estas queries:

-- 1. Verificar que la tabla areas existe con RLS activa
SELECT schemaname, tablename, rowsecurity
FROM pg_tables
WHERE schemaname = 'public' AND tablename = 'areas';
-- Esperado: rowsecurity = true

-- 2. Verificar columna area_id en processes
SELECT column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_schema = 'public'
  AND table_name = 'processes'
  AND column_name = 'area_id';
-- Esperado: una fila, data_type = 'uuid', is_nullable = 'YES'

-- 3. Verificar que no quedan procesos sin org_id
SELECT COUNT(*) as sin_org FROM public.processes WHERE org_id IS NULL;
-- Esperado: 0

-- 4. Verificar políticas de areas
SELECT policyname, cmd FROM pg_policies
WHERE schemaname = 'public' AND tablename = 'areas';
-- Esperado: 4 políticas (areas_select, areas_insert, areas_update, areas_delete)

-- 5. Verificar que process_groups sigue existiendo (no se eliminó)
SELECT table_name FROM information_schema.tables
WHERE table_schema = 'public' AND table_name = 'process_groups';
-- Esperado: 1 fila (la tabla sigue ahí — se elimina más adelante)

Criterios de validación

  • Archivo supabase/migrations/017_create_areas.sql creado
  • Migración aplicada en Supabase (reportar resultado del SQL Editor o supabase db push)
  • Las 5 queries de verificación retornan los valores esperados
  • npm run build sin errores (no hay cambios en TypeScript — build debe ser idéntico al de Etapa 0)
  • npm run test sin regresiones (592 tests, sin cambios)
  • process_groups sigue existiendo en la DB (verificar con query 5)

Restricciones explícitas

  • NO modificar ningún archivo TypeScript en esta etapa — solo SQL
  • NO dropear process_groups, client, ni group_id — eso viene después
  • NO tocar las políticas RLS existentes en processes, organizations, ni otras tablas
  • NO crear datos de prueba en areas — la tabla arranca vacía

Archivos autorizados a modificar/crear

simulador-web/
└── supabase/
    └── migrations/
        └── 017_create_areas.sql   ← único archivo a crear

Ningún archivo TypeScript debe cambiar en esta etapa.


Commit esperado

feat(db): migración 017 — tabla areas, area_id en processes, RLS, bulk-assign org

Reporte esperado

Al finalizar, reportar:

  1. Contenido exacto del archivo 017_create_areas.sql
  2. Resultado de aplicar la migración (output de Supabase)
  3. Resultado de las 5 queries de verificación (con los valores reales)
  4. Resultado de npm run build y npm run test
  5. Confirmar que process_groups sigue existiendo (query 5)