-- ========================================================= -- TABLERO CDC - Visibilidad del Total Tarifado -- Ejecutar en Supabase SQL Editor antes de desplegar esta versión. -- -- Objetivo: -- - Por defecto, el Total Tarifado solo lo ven: -- * gmarrero@gomezleemarketing.com -- * jgomez@gomezleemarketing.com -- * iaracena@gomezleemarketing.com -- - Ellos pueden activar/desactivar un botón para mostrarlo temporalmente a todos. -- - No expone montos internos por proyecto; solo habilita/oculta el resumen global/filtrado. -- ========================================================= create table if not exists public.tablero_cdc_app_settings ( key text primary key, value jsonb not null default '{}'::jsonb, updated_by uuid references auth.users(id), updated_at timestamptz not null default now() ); insert into public.tablero_cdc_app_settings (key, value) values ('pricing_summary_public', jsonb_build_object('enabled', false)) on conflict (key) do nothing; alter table public.tablero_cdc_app_settings enable row level security; drop policy if exists "tablero_cdc_app_settings_select_authenticated" on public.tablero_cdc_app_settings; drop policy if exists "tablero_cdc_app_settings_insert_summary_controllers" on public.tablero_cdc_app_settings; drop policy if exists "tablero_cdc_app_settings_update_summary_controllers" on public.tablero_cdc_app_settings; drop policy if exists "tablero_cdc_app_settings_delete_none" on public.tablero_cdc_app_settings; create policy "tablero_cdc_app_settings_select_authenticated" on public.tablero_cdc_app_settings for select to authenticated using (true); create policy "tablero_cdc_app_settings_insert_summary_controllers" on public.tablero_cdc_app_settings for insert to authenticated with check ( key = 'pricing_summary_public' and lower(coalesce(auth.jwt() ->> 'email', '')) in ( 'gmarrero@gomezleemarketing.com', 'jgomez@gomezleemarketing.com', 'iaracena@gomezleemarketing.com' ) ); create policy "tablero_cdc_app_settings_update_summary_controllers" on public.tablero_cdc_app_settings for update to authenticated using ( key = 'pricing_summary_public' and lower(coalesce(auth.jwt() ->> 'email', '')) in ( 'gmarrero@gomezleemarketing.com', 'jgomez@gomezleemarketing.com', 'iaracena@gomezleemarketing.com' ) ) with check ( key = 'pricing_summary_public' and lower(coalesce(auth.jwt() ->> 'email', '')) in ( 'gmarrero@gomezleemarketing.com', 'jgomez@gomezleemarketing.com', 'iaracena@gomezleemarketing.com' ) ); create policy "tablero_cdc_app_settings_delete_none" on public.tablero_cdc_app_settings for delete to authenticated using (false); create or replace function public.set_tablero_cdc_app_settings_updated_at() returns trigger language plpgsql as $$ begin new.updated_at = now(); new.updated_by = auth.uid(); return new; end; $$; drop trigger if exists trg_tablero_cdc_app_settings_updated_at on public.tablero_cdc_app_settings; create trigger trg_tablero_cdc_app_settings_updated_at before insert or update on public.tablero_cdc_app_settings for each row execute function public.set_tablero_cdc_app_settings_updated_at(); create or replace function public.tablero_cdc_set_pricing_summary_public(p_enabled boolean) returns jsonb language plpgsql security definer set search_path = public as $$ declare v_email text := lower(coalesce(auth.jwt() ->> 'email', '')); v_enabled boolean := coalesce(p_enabled, false); begin if v_email not in ( 'gmarrero@gomezleemarketing.com', 'jgomez@gomezleemarketing.com', 'iaracena@gomezleemarketing.com' ) then raise exception 'No tienes permiso para cambiar la visibilidad del total tarifado.'; end if; insert into public.tablero_cdc_app_settings (key, value, updated_by, updated_at) values ( 'pricing_summary_public', jsonb_build_object('enabled', v_enabled), auth.uid(), now() ) on conflict (key) do update set value = excluded.value, updated_by = auth.uid(), updated_at = now(); return jsonb_build_object('enabled', v_enabled); end; $$; grant select on public.tablero_cdc_app_settings to authenticated; grant execute on function public.tablero_cdc_set_pricing_summary_public(boolean) to authenticated; -- Reemplaza la RPC de resumen para respetar visibilidad pública temporal. create or replace function public.tablero_cdc_get_pricing_summary( p_tab text default 'todos', p_search text default '', p_country text default '', p_brand text default '', p_client text default '', p_cm text default '' ) returns jsonb language sql stable security invoker set search_path = public as $$ with visibility as ( select coalesce((value ->> 'enabled')::boolean, false) as is_public from public.tablero_cdc_app_settings where key = 'pricing_summary_public' ), allowed as ( select lower(coalesce(auth.jwt() ->> 'email', '')) in ( 'gmarrero@gomezleemarketing.com', 'jgomez@gomezleemarketing.com', 'iaracena@gomezleemarketing.com' ) or coalesce((select is_public from visibility), false) as can_view_pricing ), params as ( select lower(coalesce(nullif(trim(p_tab), ''), 'todos')) as tab, trim(coalesce(p_search, '')) as search_text, trim(coalesce(p_country, '')) as country_filter, trim(coalesce(p_brand, '')) as brand_filter, trim(coalesce(p_client, '')) as client_filter, trim(coalesce(p_cm, '')) as cm_filter ), base_filtered as ( select p.* from public.tablero_cdc_projects p cross join params prm where case when prm.tab in ('abiertos', 'activos', 'active', 'open') then coalesce(nullif(trim(p.status), ''), 'Activo') = 'Activo' when prm.tab in ('cerrados', 'closed') then coalesce(nullif(trim(p.status), ''), 'Activo') <> 'Activo' else true end and ( prm.search_text = '' or coalesce(p.title, '') ilike '%' || prm.search_text || '%' or coalesce(p.client, '') ilike '%' || prm.search_text || '%' or coalesce(p.brand, '') ilike '%' || prm.search_text || '%' or coalesce(p.country, '') ilike '%' || prm.search_text || '%' or coalesce(p.requested_by, '') ilike '%' || prm.search_text || '%' or coalesce(p.country_manager, '') ilike '%' || prm.search_text || '%' or coalesce(p.description, '') ilike '%' || prm.search_text || '%' ) ), filtered as ( select bf.* from base_filtered bf cross join params prm where (prm.country_filter = '' or coalesce(bf.country, '') ilike '%' || prm.country_filter || '%') and (prm.brand_filter = '' or coalesce(bf.brand, '') ilike '%' || prm.brand_filter || '%') and (prm.client_filter = '' or coalesce(bf.client, '') ilike '%' || prm.client_filter || '%') and (prm.cm_filter = '' or coalesce(bf.country_manager, '') ilike '%' || prm.cm_filter || '%') ), totals as ( select count(*)::integer as project_count, coalesce( sum( greatest( coalesce(nullif(trim(internal_amount::text), '')::numeric, 0), 0 ) ), 0 )::numeric as total_amount from filtered ) select case when (select can_view_pricing from allowed) then jsonb_build_object( 'total_amount', (select total_amount from totals), 'project_count', (select project_count from totals) ) else jsonb_build_object( 'total_amount', 0, 'project_count', 0 ) end; $$; grant execute on function public.tablero_cdc_get_pricing_summary(text, text, text, text, text, text) to authenticated; -- Intenta habilitar realtime para que el cambio de visible/oculto se refleje sin recargar. -- Si la publicación ya existe o la tabla ya está agregada, no hace nada. do $$ begin alter publication supabase_realtime add table public.tablero_cdc_app_settings; exception when duplicate_object then null; when undefined_object then null; end $$; select 'Visibilidad del Total Tarifado lista' as status, (select value from public.tablero_cdc_app_settings where key = 'pricing_summary_public') as pricing_summary_public;