Files
agenciapsilmno/DBS/2026-03-11/src-sql-arquivos/supabase_patient_index_page.sql
2026-03-12 08:58:36 -03:00

148 lines
4.1 KiB
PL/PgSQL

-- =========================================================
-- pacientesIndexPage.sql
-- Views + índices para a tela PatientsListPage
-- =========================================================
-- 0) Extensões úteis
create extension if not exists pg_trgm;
-- 1) updated_at automático (se você quiser manter updated_at sempre correto)
create or replace function public.set_updated_at()
returns trigger
language plpgsql
as $$
begin
new.updated_at = now();
return new;
end;
$$;
drop trigger if exists trg_patients_set_updated_at on public.patients;
create trigger trg_patients_set_updated_at
before update on public.patients
for each row execute function public.set_updated_at();
-- =========================================================
-- 2) Views de contagem (usadas em KPIs e telas auxiliares)
-- =========================================================
-- 2.1) Grupos com contagem de pacientes
create or replace view public.v_patient_groups_with_counts as
select
g.id,
g.name,
g.color,
coalesce(count(pgp.patient_id), 0)::int as patients_count
from public.patient_groups g
left join public.patient_group_patient pgp
on pgp.patient_group_id = g.id
group by g.id, g.name, g.color;
-- 2.2) Tags com contagem de pacientes
create or replace view public.v_tag_patient_counts as
select
t.id,
t.name,
t.color,
coalesce(count(ppt.patient_id), 0)::int as patients_count
from public.patient_tags t
left join public.patient_patient_tag ppt
on ppt.tag_id = t.id
group by t.id, t.name, t.color;
-- =========================================================
-- 3) View principal da Index (pacientes + grupos/tags agregados)
-- =========================================================
create or replace view public.v_patients_index as
select
p.*,
-- array JSON com os grupos do paciente
coalesce(gx.groups, '[]'::jsonb) as groups,
-- array JSON com as tags do paciente
coalesce(tx.tags, '[]'::jsonb) as tags,
-- contagens para UI/KPIs
coalesce(gx.groups_count, 0)::int as groups_count,
coalesce(tx.tags_count, 0)::int as tags_count
from public.patients p
left join lateral (
select
jsonb_agg(
distinct jsonb_build_object(
'id', g.id,
'name', g.name,
'color', g.color
)
) filter (where g.id is not null) as groups,
count(distinct g.id) as groups_count
from public.patient_group_patient pgp
join public.patient_groups g
on g.id = pgp.patient_group_id
where pgp.patient_id = p.id
) gx on true
left join lateral (
select
jsonb_agg(
distinct jsonb_build_object(
'id', t.id,
'name', t.name,
'color', t.color
)
) filter (where t.id is not null) as tags,
count(distinct t.id) as tags_count
from public.patient_patient_tag ppt
join public.patient_tags t
on t.id = ppt.tag_id
where ppt.patient_id = p.id
) tx on true;
-- =========================================================
-- 4) Índices recomendados (performance real na listagem/filtros)
-- =========================================================
-- Patients
create index if not exists idx_patients_owner_id
on public.patients (owner_id);
create index if not exists idx_patients_created_at
on public.patients (created_at desc);
create index if not exists idx_patients_status
on public.patients (status);
create index if not exists idx_patients_last_attended_at
on public.patients (last_attended_at desc);
-- Busca rápida (name/email/phone)
create index if not exists idx_patients_name_trgm
on public.patients using gin (name gin_trgm_ops);
create index if not exists idx_patients_email_trgm
on public.patients using gin (email gin_trgm_ops);
create index if not exists idx_patients_phone_trgm
on public.patients using gin (phone gin_trgm_ops);
-- Pivot: grupos
create index if not exists idx_pgp_patient_id
on public.patient_group_patient (patient_id);
create index if not exists idx_pgp_group_id
on public.patient_group_patient (patient_group_id);
-- Pivot: tags
create index if not exists idx_ppt_patient_id
on public.patient_patient_tag (patient_id);
create index if not exists idx_ppt_tag_id
on public.patient_patient_tag (tag_id);