-- ========================================================= -- TABLERO CDC - RPC PAGINADO + FILTROS AVANZADOS -- Ejecutar en Supabase SQL Editor antes de desplegar esta versión. -- -- La app usa esta función para cargar solo la página actual de: -- - Todos -- - Activos -- - Cerrados -- -- También filtra desde Supabase por: -- - País / BU -- - Marca -- - Cliente -- - CM / Country Manager -- -- No borra datos, no cambia tablas y no toca crear/editar/eliminar. -- ========================================================= -- Evita conflictos con la versión anterior de 4 parámetros. drop function if exists public.tablero_cdc_get_projects_paginated(text, text, integer, integer); drop function if exists public.tablero_cdc_get_projects_paginated(text, text, integer, integer, text, text, text, text); create or replace function public.tablero_cdc_get_projects_paginated( p_tab text default 'todos', p_search text default '', p_page integer default 1, p_page_size integer default 24, 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 params as ( select lower(coalesce(nullif(trim(p_tab), ''), 'todos')) as tab, trim(coalesce(p_search, '')) as search_text, greatest(coalesce(p_page, 1), 1) as page_number, least(greatest(coalesce(p_page_size, 24), 1), 100) as page_size, 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 || '%') ), total as ( select count(*)::integer as total_count from filtered ), paged as ( select f.* from filtered f cross join params prm order by f.created_at desc nulls last, f.id desc limit (select page_size from params) offset ((select page_number - 1 from params) * (select page_size from params)) ), option_values as ( select coalesce( ( select jsonb_agg(value order by value) from ( select distinct trim(country) as value from base_filtered where nullif(trim(coalesce(country, '')), '') is not null ) countries ), '[]'::jsonb ) as countries, coalesce( ( select jsonb_agg(value order by value) from ( select distinct trim(brand) as value from base_filtered where nullif(trim(coalesce(brand, '')), '') is not null ) brands ), '[]'::jsonb ) as brands, coalesce( ( select jsonb_agg(value order by value) from ( select distinct trim(client) as value from base_filtered where nullif(trim(coalesce(client, '')), '') is not null ) clients ), '[]'::jsonb ) as clients, coalesce( ( select jsonb_agg(value order by value) from ( select distinct trim(country_manager) as value from base_filtered where nullif(trim(coalesce(country_manager, '')), '') is not null ) cms ), '[]'::jsonb ) as cms ) select jsonb_build_object( 'total_count', (select total_count from total), 'filter_options', jsonb_build_object( 'countries', (select countries from option_values), 'brands', (select brands from option_values), 'clients', (select clients from option_values), 'cms', (select cms from option_values) ), 'projects', coalesce( ( select jsonb_agg( jsonb_build_object( 'id', p.id, 'title', p.title, 'client', p.client, 'brand', p.brand, 'country', p.country, 'requested_by', p.requested_by, 'country_manager', p.country_manager, 'description', p.description, 'status', p.status, 'internal_amount', case when lower(coalesce(auth.jwt() ->> 'email', '')) = 'gmarrero@gomezleemarketing.com' then to_jsonb(p.internal_amount) else 'null'::jsonb end, 'brief_link', p.brief_link, 'created_at', p.created_at, 'extra_data', p.extra_data, 'project_links', coalesce( ( select jsonb_agg( jsonb_build_object( 'id', l.id, 'link_type', l.link_type, 'url', l.url, 'label', l.label ) order by l.label asc nulls last, l.id asc ) from public.tablero_cdc_project_links l where l.project_id = p.id ), '[]'::jsonb ) ) order by p.created_at desc nulls last, p.id desc ) from paged p ), '[]'::jsonb ) ); $$; grant execute on function public.tablero_cdc_get_projects_paginated(text, text, integer, integer, text, text, text, text) to authenticated; -- Validación rápida opcional después de crear la función: -- select public.tablero_cdc_get_projects_paginated('todos', '', 1, 24, '', '', '', ''); -- select public.tablero_cdc_get_projects_paginated('abiertos', '', 1, 24, '', '', '', ''); -- select public.tablero_cdc_get_projects_paginated('cerrados', '', 1, 24, '', '', '', ''); -- select public.tablero_cdc_get_projects_paginated('todos', '', 1, 24, 'Republica Dominicana', '', '', '');