267 lines
8.9 KiB
SQL
267 lines
8.9 KiB
SQL
-- =========================================================
|
|
-- PATCH — Completar cadastro para bater com PatientsCadastroPage.vue
|
|
-- (rode DEPOIS do seu supabase_cadastro_pacientes.sql)
|
|
-- =========================================================
|
|
|
|
create extension if not exists pgcrypto;
|
|
|
|
-- ---------------------------------------------------------
|
|
-- 1) Completar colunas que o front usa e hoje faltam em patients
|
|
-- ---------------------------------------------------------
|
|
do $$
|
|
begin
|
|
if not exists (
|
|
select 1 from information_schema.columns
|
|
where table_schema='public' and table_name='patients' and column_name='email_alt'
|
|
) then
|
|
alter table public.patients add column email_alt text;
|
|
end if;
|
|
|
|
if not exists (
|
|
select 1 from information_schema.columns
|
|
where table_schema='public' and table_name='patients' and column_name='phones'
|
|
) then
|
|
-- array de textos (Postgres). No JS você manda ["...","..."] normalmente.
|
|
alter table public.patients add column phones text[];
|
|
end if;
|
|
|
|
if not exists (
|
|
select 1 from information_schema.columns
|
|
where table_schema='public' and table_name='patients' and column_name='gender'
|
|
) then
|
|
alter table public.patients add column gender text;
|
|
end if;
|
|
|
|
if not exists (
|
|
select 1 from information_schema.columns
|
|
where table_schema='public' and table_name='patients' and column_name='marital_status'
|
|
) then
|
|
alter table public.patients add column marital_status text;
|
|
end if;
|
|
end $$;
|
|
|
|
-- (opcional) índices úteis pra busca/filtro por nome/email
|
|
create index if not exists idx_patients_owner_name on public.patients(owner_id, name);
|
|
create index if not exists idx_patients_owner_email on public.patients(owner_id, email);
|
|
|
|
-- ---------------------------------------------------------
|
|
-- 2) patient_groups
|
|
-- ---------------------------------------------------------
|
|
create table if not exists public.patient_groups (
|
|
id uuid primary key default gen_random_uuid(),
|
|
owner_id uuid not null references auth.users(id) on delete cascade,
|
|
name text not null,
|
|
color text,
|
|
is_system boolean not null default false,
|
|
created_at timestamptz not null default now(),
|
|
updated_at timestamptz not null default now()
|
|
);
|
|
|
|
-- nome único por owner
|
|
do $$
|
|
begin
|
|
if not exists (
|
|
select 1 from pg_constraint
|
|
where conname = 'patient_groups_owner_name_uniq'
|
|
and conrelid = 'public.patient_groups'::regclass
|
|
) then
|
|
alter table public.patient_groups
|
|
add constraint patient_groups_owner_name_uniq unique(owner_id, name);
|
|
end if;
|
|
end $$;
|
|
|
|
drop trigger if exists trg_patient_groups_set_updated_at on public.patient_groups;
|
|
create trigger trg_patient_groups_set_updated_at
|
|
before update on public.patient_groups
|
|
for each row execute function public.set_updated_at();
|
|
|
|
create index if not exists idx_patient_groups_owner on public.patient_groups(owner_id);
|
|
|
|
alter table public.patient_groups enable row level security;
|
|
|
|
drop policy if exists "patient_groups_select_own" on public.patient_groups;
|
|
create policy "patient_groups_select_own"
|
|
on public.patient_groups for select
|
|
to authenticated
|
|
using (owner_id = auth.uid());
|
|
|
|
drop policy if exists "patient_groups_insert_own" on public.patient_groups;
|
|
create policy "patient_groups_insert_own"
|
|
on public.patient_groups for insert
|
|
to authenticated
|
|
with check (owner_id = auth.uid());
|
|
|
|
drop policy if exists "patient_groups_update_own" on public.patient_groups;
|
|
create policy "patient_groups_update_own"
|
|
on public.patient_groups for update
|
|
to authenticated
|
|
using (owner_id = auth.uid())
|
|
with check (owner_id = auth.uid());
|
|
|
|
drop policy if exists "patient_groups_delete_own" on public.patient_groups;
|
|
create policy "patient_groups_delete_own"
|
|
on public.patient_groups for delete
|
|
to authenticated
|
|
using (owner_id = auth.uid());
|
|
|
|
grant select, insert, update, delete on public.patient_groups to authenticated;
|
|
|
|
-- ---------------------------------------------------------
|
|
-- 3) patient_tags
|
|
-- ---------------------------------------------------------
|
|
create table if not exists public.patient_tags (
|
|
id uuid primary key default gen_random_uuid(),
|
|
owner_id uuid not null references auth.users(id) on delete cascade,
|
|
name text not null,
|
|
color text,
|
|
created_at timestamptz not null default now(),
|
|
updated_at timestamptz not null default now()
|
|
);
|
|
|
|
do $$
|
|
begin
|
|
if not exists (
|
|
select 1 from pg_constraint
|
|
where conname = 'patient_tags_owner_name_uniq'
|
|
and conrelid = 'public.patient_tags'::regclass
|
|
) then
|
|
alter table public.patient_tags
|
|
add constraint patient_tags_owner_name_uniq unique(owner_id, name);
|
|
end if;
|
|
end $$;
|
|
|
|
drop trigger if exists trg_patient_tags_set_updated_at on public.patient_tags;
|
|
create trigger trg_patient_tags_set_updated_at
|
|
before update on public.patient_tags
|
|
for each row execute function public.set_updated_at();
|
|
|
|
create index if not exists idx_patient_tags_owner on public.patient_tags(owner_id);
|
|
|
|
alter table public.patient_tags enable row level security;
|
|
|
|
drop policy if exists "patient_tags_select_own" on public.patient_tags;
|
|
create policy "patient_tags_select_own"
|
|
on public.patient_tags for select
|
|
to authenticated
|
|
using (owner_id = auth.uid());
|
|
|
|
drop policy if exists "patient_tags_insert_own" on public.patient_tags;
|
|
create policy "patient_tags_insert_own"
|
|
on public.patient_tags for insert
|
|
to authenticated
|
|
with check (owner_id = auth.uid());
|
|
|
|
drop policy if exists "patient_tags_update_own" on public.patient_tags;
|
|
create policy "patient_tags_update_own"
|
|
on public.patient_tags for update
|
|
to authenticated
|
|
using (owner_id = auth.uid())
|
|
with check (owner_id = auth.uid());
|
|
|
|
drop policy if exists "patient_tags_delete_own" on public.patient_tags;
|
|
create policy "patient_tags_delete_own"
|
|
on public.patient_tags for delete
|
|
to authenticated
|
|
using (owner_id = auth.uid());
|
|
|
|
grant select, insert, update, delete on public.patient_tags to authenticated;
|
|
|
|
-- ---------------------------------------------------------
|
|
-- 4) pivôs (patient_group_patient / patient_patient_tag)
|
|
-- ---------------------------------------------------------
|
|
create table if not exists public.patient_group_patient (
|
|
patient_id uuid not null references public.patients(id) on delete cascade,
|
|
patient_group_id uuid not null references public.patient_groups(id) on delete cascade,
|
|
created_at timestamptz not null default now(),
|
|
primary key (patient_id, patient_group_id)
|
|
);
|
|
|
|
create index if not exists idx_pgp_patient on public.patient_group_patient(patient_id);
|
|
create index if not exists idx_pgp_group on public.patient_group_patient(patient_group_id);
|
|
|
|
alter table public.patient_group_patient enable row level security;
|
|
|
|
-- a pivot “herda” tenant via join; policy usando exists pra validar owner do patient
|
|
drop policy if exists "pgp_select_own" on public.patient_group_patient;
|
|
create policy "pgp_select_own"
|
|
on public.patient_group_patient for select
|
|
to authenticated
|
|
using (
|
|
exists (
|
|
select 1 from public.patients p
|
|
where p.id = patient_group_patient.patient_id
|
|
and p.owner_id = auth.uid()
|
|
)
|
|
);
|
|
|
|
drop policy if exists "pgp_write_own" on public.patient_group_patient;
|
|
create policy "pgp_write_own"
|
|
on public.patient_group_patient for all
|
|
to authenticated
|
|
using (
|
|
exists (
|
|
select 1 from public.patients p
|
|
where p.id = patient_group_patient.patient_id
|
|
and p.owner_id = auth.uid()
|
|
)
|
|
)
|
|
with check (
|
|
exists (
|
|
select 1 from public.patients p
|
|
where p.id = patient_group_patient.patient_id
|
|
and p.owner_id = auth.uid()
|
|
)
|
|
);
|
|
|
|
grant select, insert, update, delete on public.patient_group_patient to authenticated;
|
|
|
|
-- tags pivot (ATENÇÃO: coluna é tag_id, como teu Vue usa!)
|
|
create table if not exists public.patient_patient_tag (
|
|
patient_id uuid not null references public.patients(id) on delete cascade,
|
|
tag_id uuid not null references public.patient_tags(id) on delete cascade,
|
|
created_at timestamptz not null default now(),
|
|
primary key (patient_id, tag_id)
|
|
);
|
|
|
|
create index if not exists idx_ppt_patient on public.patient_patient_tag(patient_id);
|
|
create index if not exists idx_ppt_tag on public.patient_patient_tag(tag_id);
|
|
|
|
alter table public.patient_patient_tag enable row level security;
|
|
|
|
drop policy if exists "ppt_select_own" on public.patient_patient_tag;
|
|
create policy "ppt_select_own"
|
|
on public.patient_patient_tag for select
|
|
to authenticated
|
|
using (
|
|
exists (
|
|
select 1 from public.patients p
|
|
where p.id = patient_patient_tag.patient_id
|
|
and p.owner_id = auth.uid()
|
|
)
|
|
);
|
|
|
|
drop policy if exists "ppt_write_own" on public.patient_patient_tag;
|
|
create policy "ppt_write_own"
|
|
on public.patient_patient_tag for all
|
|
to authenticated
|
|
using (
|
|
exists (
|
|
select 1 from public.patients p
|
|
where p.id = patient_patient_tag.patient_id
|
|
and p.owner_id = auth.uid()
|
|
)
|
|
)
|
|
with check (
|
|
exists (
|
|
select 1 from public.patients p
|
|
where p.id = patient_patient_tag.patient_id
|
|
and p.owner_id = auth.uid()
|
|
)
|
|
);
|
|
|
|
grant select, insert, update, delete on public.patient_patient_tag to authenticated;
|
|
|
|
-- =========================================================
|
|
-- FIM PATCH
|
|
-- =========================================================
|