148 lines
4.1 KiB
PL/PgSQL
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);
|