6.6 KiB
CHANGELOG — Banco de Dados AgênciaPsi
Registro histórico de todas as migrations aplicadas no banco. Formato: data | arquivo | o que mudou | por quê
[001] — 2026-03-03
Arquivo: migration_001.sql
Seed: seed_001.sql
Contexto
O schema original foi construído de forma incremental e acumulou inconsistências no modelo de identidade. Usuários não tinham um tipo de conta definido formalmente, tenants não distinguiam terapeuta de clínica, e não existia suporte a paciente como tipo de conta de plataforma.
O que mudou
profiles
- ✅ Adicionada coluna
account_type text NOT NULL DEFAULT 'free'- Valores:
free | patient | therapist | clinic - Imutável após sair de
free(triggertrg_account_type_immutable) - Usuários com role=
patientmigrados paraaccount_type='patient' - Usuários com tenant
saasativo migrados paraaccount_type='therapist'
- Valores:
tenants
- ✅ Novos valores aceitos em
kind:therapist→ terapeuta individual (substituisaas)clinic_coworking→ clínica tipo 1: gestão de salasclinic_reception→ clínica tipo 2: secretaria + múltiplas agendasclinic_full→ clínica tipo 3: coworking + secretaria
- ✅
kindagora é imutável após criação (triggertrg_tenant_kind_immutable) - ✅ 10 tenants
saasórfãos (sem admin, sem subscriptions) deletados - ✅ Tenants
saascom admin ativo migrados parakind='therapist' - ⚠️
saaseclinic(legados) mantidos no CHECK por compatibilidade. Não criar novos tenants com esses kinds.
plans
- ✅ Adicionado
patientcomo valor válido emtarget - ✅ Inserido plano
patient_free(gratuito, target=patient)
Novas funções
| Função | Descrição |
|---|---|
provision_account_tenant(user_id, kind, name?) |
Cria tenant + membership + atualiza account_type. Chamar no onboarding. |
is_therapist_tenant(tenant_id) |
Retorna true se tenant é do tipo therapist |
is_clinic_tenant(tenant_id) |
Atualizada: inclui todos os subtipos de clínica |
guard_tenant_kind_immutable() |
Trigger: bloqueia alteração de tenants.kind |
guard_account_type_immutable() |
Trigger: bloqueia alteração de account_type após escolha |
guard_patient_cannot_own_tenant() |
Trigger: bloqueia paciente de ser tenant_admin/therapist |
Funções atualizadas
| Função | O que mudou |
|---|---|
handle_new_user() |
Agora insere account_type='free' |
handle_new_user_create_personal_tenant() |
Desabilitada — tenant criado no onboarding |
ensure_personal_tenant() |
Busca por kind IN ('therapist','saas') e delega para provision_account_tenant |
Regras de negócio agora garantidas no banco
- Paciente é para sempre paciente —
account_typeimutável após escolha - Terapeuta nunca vira clínica e vice-versa —
tenants.kindimutável - Paciente não pode ter tenant — trigger bloqueia na inserção
- Cada tipo de conta tem seu tipo de tenant —
provision_account_tenantgarante
Usuários de seed (apenas dev/staging)
| Tipo | Tenant | |
|---|---|---|
| paciente@agenciapsi.com.br | patient | nenhum |
| terapeuta@agenciapsi.com.br | therapist | tenant próprio (therapist) + vinculado à Clínica 3 |
| clinica1@agenciapsi.com.br | clinic | clinic_coworking |
| clinica2@agenciapsi.com.br | clinic | clinic_reception |
| clinica3@agenciapsi.com.br | clinic | clinic_full |
| saas@agenciapsi.com.br | saas_admin | nenhum |
Senha de todos:
Teste@123
[002] — seed_002.sql
Arquivo: Novo-DB/seed_002.sql
O que cria
Migration embutida
- ✅
profiles.platform_roles text[] NOT NULL DEFAULT '{}'— adicionada viaADD COLUMN IF NOT EXISTS(idempotente)
Usuários de teste
| Senha | Papel | Tenant | |
|---|---|---|---|
supervisor@agenciapsi.com.br |
Teste@123 |
supervisor em tenant_members |
Clínica Bem Estar (Full) |
editor@agenciapsi.com.br |
Teste@123 |
therapist em tenant_members + platform_roles = '{editor}' |
Clínica Bem Estar (Full) |
UUIDs reservados:
- Supervisor:
aaaaaaaa-0007-0007-0007-000000000007 - Editor:
aaaaaaaa-0008-0008-0008-000000000008
[PENDENTE] — Migration necessária: platform_roles em profiles
Contexto:
Implementação das áreas de Supervisor (papel de tenant) e Editor (papel de plataforma).
O papel de Editor é atribuído pelo saas_admin e armazenado diretamente no perfil do usuário,
independente de qual tenant ele pertence.
O que precisa ser aplicado no banco
profiles
- ⚠️ Adicionar coluna
platform_roles text[] NOT NULL DEFAULT '{}'- Armazena papéis globais de plataforma. Ex.:
'{editor}' - Quem pode escrever: somente
saas_admin(via RLS ou função privilegiada) - Quem pode ter: qualquer usuário autenticado, exceto
account_type = 'patient' - Valores previstos:
editor(mais podem ser adicionados futuramente)
- Armazena papéis globais de plataforma. Ex.:
SQL sugerido
ALTER TABLE public.profiles
ADD COLUMN IF NOT EXISTS platform_roles text[] NOT NULL DEFAULT '{}';
-- Comentário descritivo
COMMENT ON COLUMN public.profiles.platform_roles IS
'Papéis globais de plataforma, independentes de tenant. Ex: editor de microlearning. Atribuído pelo saas_admin.';
-- RLS: somente saas_admin pode atualizar platform_roles (exemplo)
-- CREATE POLICY "saas_admin pode atualizar platform_roles"
-- ON public.profiles FOR UPDATE
-- USING (auth.uid() IN (SELECT id FROM public.profiles WHERE role = 'saas_admin'))
-- WITH CHECK (true);
tenant_members (sem alteração necessária)
- O papel
supervisorjá é suportado como valor text emtenant_members.role. - Nenhuma alteração de schema é necessária — basta inserir memberships com
role = 'supervisor'.
Impacto se não aplicado
- Área do Editor (
/editor) fica inacessível a todos (coluna ausente →platform_rolesvemnull→ acesso negado). - Área do Supervisor (
/supervisor) funciona normalmente — não depende desta migration.
Futuro — registrado mas não implementado
Vínculo Terapeuta ↔ Clínica (a implementar)
- Terapeuta autoriza explicitamente que secretaria gerencie suas sessões
- Permissão só válida se clínica tiver
kind IN ('clinic_reception', 'clinic_full') - Secretaria acessa apenas sessões — não prontuário nem anotações
- Dissociação bloqueada se houver
agenda_eventosfuturos (inicio_em > now()) - Após dissociação: cada parte fica com seus próprios pacientes
- Requer: coluna de permissão no vínculo + função de dissociação com validação
Última atualização: 2026-03-03