Agenda, Agendador, Configurações
This commit is contained in:
110
DBS/2026-03-11/src-sql-arquivos/01_profiles.sql
Normal file
110
DBS/2026-03-11/src-sql-arquivos/01_profiles.sql
Normal file
@@ -0,0 +1,110 @@
|
||||
-- =========================================================
|
||||
-- Agência PSI — Profiles (v2) + Trigger + RLS
|
||||
-- - 1 profile por auth.users.id
|
||||
-- - role base (admin|therapist|patient)
|
||||
-- - pronto para evoluir p/ multi-tenant depois
|
||||
-- =========================================================
|
||||
|
||||
-- 0) Função padrão updated_at (se já existir, mantém)
|
||||
create or replace function public.set_updated_at()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
as $$
|
||||
begin
|
||||
new.updated_at = now();
|
||||
return new;
|
||||
end;
|
||||
$$;
|
||||
|
||||
-- 1) Tabela profiles
|
||||
create table if not exists public.profiles (
|
||||
id uuid primary key, -- = auth.users.id
|
||||
email text,
|
||||
full_name text,
|
||||
avatar_url text,
|
||||
|
||||
role text not null default 'patient',
|
||||
status text not null default 'active',
|
||||
|
||||
created_at timestamptz not null default now(),
|
||||
updated_at timestamptz not null default now(),
|
||||
|
||||
constraint profiles_role_check check (role in ('admin','therapist','patient')),
|
||||
constraint profiles_status_check check (status in ('active','inactive','invited'))
|
||||
);
|
||||
|
||||
-- FK opcional (em Supabase costuma ser ok)
|
||||
do $$
|
||||
begin
|
||||
if not exists (
|
||||
select 1
|
||||
from pg_constraint
|
||||
where conname = 'profiles_id_fkey'
|
||||
) then
|
||||
alter table public.profiles
|
||||
add constraint profiles_id_fkey
|
||||
foreign key (id) references auth.users(id)
|
||||
on delete cascade;
|
||||
end if;
|
||||
end $$;
|
||||
|
||||
-- Índices úteis
|
||||
create index if not exists profiles_role_idx on public.profiles(role);
|
||||
create index if not exists profiles_status_idx on public.profiles(status);
|
||||
|
||||
-- 2) Trigger updated_at
|
||||
drop trigger if exists t_profiles_set_updated_at on public.profiles;
|
||||
create trigger t_profiles_set_updated_at
|
||||
before update on public.profiles
|
||||
for each row execute function public.set_updated_at();
|
||||
|
||||
-- 3) Trigger pós-signup: cria profile automático
|
||||
-- Observação: roda como SECURITY DEFINER
|
||||
create or replace function public.handle_new_user()
|
||||
returns trigger
|
||||
language plpgsql
|
||||
security definer
|
||||
set search_path = public
|
||||
as $$
|
||||
begin
|
||||
insert into public.profiles (id, email, role, status)
|
||||
values (new.id, new.email, 'patient', 'active')
|
||||
on conflict (id) do update
|
||||
set email = excluded.email;
|
||||
|
||||
return new;
|
||||
end;
|
||||
$$;
|
||||
|
||||
drop trigger if exists on_auth_user_created on auth.users;
|
||||
create trigger on_auth_user_created
|
||||
after insert on auth.users
|
||||
for each row execute function public.handle_new_user();
|
||||
|
||||
-- 4) RLS
|
||||
alter table public.profiles enable row level security;
|
||||
|
||||
-- Leitura do próprio profile
|
||||
drop policy if exists "profiles_select_own" on public.profiles;
|
||||
create policy "profiles_select_own"
|
||||
on public.profiles
|
||||
for select
|
||||
to authenticated
|
||||
using (id = auth.uid());
|
||||
|
||||
-- Update do próprio profile (campos não-sensíveis)
|
||||
drop policy if exists "profiles_update_own" on public.profiles;
|
||||
create policy "profiles_update_own"
|
||||
on public.profiles
|
||||
for update
|
||||
to authenticated
|
||||
using (id = auth.uid())
|
||||
with check (id = auth.uid());
|
||||
|
||||
-- Insert só do próprio (na prática quem insere é trigger, mas deixa coerente)
|
||||
drop policy if exists "profiles_insert_own" on public.profiles;
|
||||
create policy "profiles_insert_own"
|
||||
on public.profiles
|
||||
for insert
|
||||
to authenticated
|
||||
with check (id = auth.uid());
|
||||
Reference in New Issue
Block a user