-- ============================================================= -- TABLERO CDC — PERMISO PARA CREAR PROYECTOS / CUADROS -- Fecha: 2026-09-01 -- ============================================================= -- Objetivo: -- • Administrar desde Supabase quién puede crear proyectos manualmente. -- • Mantener lectura, edición, Tiempo, Tarifario, Listas, Briefs y demás permisos intactos. -- • Aplicar seguridad real en PostgreSQL, no solamente ocultar el botón "+ Nuevo". -- -- Usuarios autorizados inicialmente: -- • boliva@gomezleemarketing.com -- • areyes@gomezleemarketing.com -- • iaracena@gomezleemarketing.com -- • jgomez@gomezleemarketing.com -- • mgomez@gomezleemarketing.com -- ============================================================= begin; -- 1) Nuevo permiso, independiente de los demás. alter table public.tablero_cdc_allowed_users add column if not exists can_create_projects boolean not null default false; comment on column public.tablero_cdc_allowed_users.can_create_projects is 'Permite crear manualmente nuevos proyectos/cuadros desde Tablero CDC.'; -- 2) Dejar exactamente a los cinco usuarios solicitados con acceso inicial. -- No cambia role, is_active ni ningún otro permiso existente. update public.tablero_cdc_allowed_users set can_create_projects = case when lower(trim(email)) in ( 'boliva@gomezleemarketing.com', 'areyes@gomezleemarketing.com', 'iaracena@gomezleemarketing.com', 'jgomez@gomezleemarketing.com', 'mgomez@gomezleemarketing.com' ) then true else false end, updated_at = now(); -- 3) Función central de permiso, reutilizable por app/RLS. create or replace function public.tablero_cdc_current_user_can_create_projects() returns boolean language sql stable security definer set search_path = public as $$ select exists ( select 1 from public.tablero_cdc_allowed_users u where lower(trim(u.email)) = lower(trim(coalesce(auth.jwt() ->> 'email', ''))) and u.is_active = true and u.can_create_projects = true ); $$; revoke all on function public.tablero_cdc_current_user_can_create_projects() from public; grant execute on function public.tablero_cdc_current_user_can_create_projects() to authenticated; -- 4) Candado de seguridad antes de tocar políticas de proyectos. -- No habilitamos/deshabilitamos RLS ni reemplazamos políticas existentes. -- Si la tabla no tiene la configuración esperada, toda esta transacción se revierte. do $$ declare v_rls_enabled boolean; v_has_permissive_insert boolean; begin select c.relrowsecurity into v_rls_enabled from pg_class c join pg_namespace n on n.oid = c.relnamespace where n.nspname = 'public' and c.relname = 'tablero_cdc_projects' and c.relkind in ('r', 'p'); if coalesce(v_rls_enabled, false) = false then raise exception 'SEGURIDAD: tablero_cdc_projects no tiene RLS habilitado. No se aplicó ningún cambio.'; end if; select exists ( select 1 from pg_policies p where p.schemaname = 'public' and p.tablename = 'tablero_cdc_projects' and upper(p.permissive) = 'PERMISSIVE' and upper(p.cmd) in ('INSERT', 'ALL') ) into v_has_permissive_insert; if not v_has_permissive_insert then raise exception 'SEGURIDAD: no se encontró la política permisiva de INSERT existente para tablero_cdc_projects. No se aplicó ningún cambio.'; end if; end $$; -- 5) Política RESTRICTIVA: se suma a las políticas existentes en vez de reemplazarlas. -- Para los usuarios autenticados, un INSERT manual requiere can_create_projects=true. -- Las operaciones realizadas con service_role continúan usando el comportamiento -- normal de Supabase (service_role omite RLS). drop policy if exists "tablero_cdc_projects_insert_requires_create_permission" on public.tablero_cdc_projects; create policy "tablero_cdc_projects_insert_requires_create_permission" on public.tablero_cdc_projects as restrictive for insert to authenticated with check (public.tablero_cdc_current_user_can_create_projects()); commit; -- ============================================================= -- VERIFICACIÓN (solo lectura) -- ============================================================= select email, full_name, role, is_active, can_create_projects from public.tablero_cdc_allowed_users order by full_name nulls last, email; select policyname, permissive, roles, cmd, with_check from pg_policies where schemaname = 'public' and tablename = 'tablero_cdc_projects' order by policyname; -- ============================================================= -- ADMINISTRACIÓN FUTURA -- ============================================================= -- Dar acceso: -- update public.tablero_cdc_allowed_users -- set can_create_projects = true, updated_at = now() -- where lower(email) = lower('correo@gomezleemarketing.com'); -- -- Quitar acceso: -- update public.tablero_cdc_allowed_users -- set can_create_projects = false, updated_at = now() -- where lower(email) = lower('correo@gomezleemarketing.com');