Files
tablero-cdc/supabase_rpc_projects_paginated.sql
T

205 lines
7.0 KiB
PL/PgSQL

-- =========================================================
-- 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', '', '', '');