Authorization
Registry de permissões, perfis de acesso, templates, plataforma e convites de plataforma.
A permissão nasce no código, junto do use case que ela protege (@Requires); a tabela permissions é uma
projeção desse registry, sincronizada pelo seeder a cada deploy, e ninguém a edita em tela.
Um perfil de acesso é um conjunto de permissões definido pelo tenant: sem broker_id é do tenant, com broker_id
é de um corretor (scope é uma coluna gerada a partir disso). Templates de tenant e de plataforma descrevem formatos
de perfil que são copiados ou seguidos. Acima dos tenants ficam os perfis e grants de plataforma.
O banco impõe o teto de escopo: um perfil ou template nunca recebe permissão acima do seu escopo (ver Teto de escopo).
Tabelas (19)
| Tabela | Para quê |
|---|---|
permissions | Projeção do registry de permissões gerado pelos @Requires dos use cases: código <domínio>.<recurso>.<ação>, escopo e descrição. |
permission_use_cases | Quais use cases exigem cada permissão; sincronizado no deploy. |
permission_changes | Auditoria prevista de mudanças no catálogo de permissões (commit, autor, aprovador, quem fez o deploy). |
access_profiles | Perfil de acesso do tenant (broker_id nulo) ou de um corretor. |
access_profile_permissions | Permissões de um perfil. |
access_profile_templates | Template de perfil do tenant, versionado: perfis ligados herdam as permissões ao vivo. |
access_profile_template_permissions | Permissões da versão atual de um template de tenant. |
access_profile_template_changes | Cada edição confirmada de um template: versões de origem e destino, permissões adicionadas e removidas, motivo e autor. |
access_profile_template_change_decisions | Para cada perfil afetado por uma edição de template: acompanhou (followed) ou desvinculou (detached), e quantos usuários foram afetados. |
platform_tenant_blueprints | Formato de tenant mantido pela plataforma; criar um tenant é escolher um blueprint. |
platform_access_profile_templates | Templates de perfil de um blueprint, copiados para access_profile_templates quando o tenant é criado. |
platform_access_profile_template_permissions | Permissões de um template de plataforma. |
platform_access_profiles | Perfis acima dos tenants (por exemplo, suporte ou administração da plataforma). |
platform_access_profile_permissions | Permissões de um perfil de plataforma; só permissões de escopo platform. |
platform_grants | Operador de plataforma: usuário, perfil de plataforma, quem concedeu e por quê. |
platform_invitations | Convite para operar a plataforma. |
platform_invitation_deliveries | Cada tentativa de envio de um convite de plataforma; reenvio é uma linha nova. |
platform_invitation_delivery_events | Linha do tempo bruta do provedor de envio; um webhook repetido não duplica (dedup_key). |
session_contexts | Operador de plataforma atuando dentro de um tenant, com motivo. |
Referência
permissions
Projeção do registry de permissões gerado pelos @Requires dos use cases: código <domínio>.<recurso>.<ação>, escopo e descrição. Uma permissão que sai do código recebe deprecated_at; nunca é apagada.
| Coluna | Tipo | Nulo | Observação |
|---|---|---|---|
id | bigint | não | identity (GENERATED ALWAYS) |
code | text | não | <domain>.<resource>.<action> |
scope | text | não | platform | tenant | broker |
description | text | não | |
replaces_code | text | sim | rename explícito |
introduced_at | timestamptz | não | padrão clock_timestamp() |
deprecated_at | timestamptz | sim | saiu do código; nunca DELETE |
Chaves estrangeiras
- nenhuma
Referenciada por: access_profile_permissions, access_profile_template_permissions, permission_use_cases, platform_access_profile_permissions, platform_access_profile_template_permissions.
Garantido pelo banco
| Tipo | Nome | Definição |
|---|---|---|
| CHECK | permissions_scope_check | CHECK ((scope IN ('platform', 'tenant', 'broker'))) |
| PK | permissions_pkey | PRIMARY KEY (id) |
| UNIQUE | permissions_code_unique | UNIQUE (code) |
| Trigger | permissions_scope_ceiling | teto de escopo das permissões (detalhes) |
Fora do banco
- O seeder de permissões faz upsert por
codee atualizadescriptionescope. Marcardeprecated_at, tratarreplaces_codee registrarpermission_changesficam para a sincronização de deploy (NOVA-37).
permission_use_cases
Quais use cases exigem cada permissão; sincronizado no deploy.
| Coluna | Tipo | Nulo | Observação |
|---|---|---|---|
permission_id | bigint | não | |
use_case | text | não |
Chaves estrangeiras
permission_id→permissions.id
Garantido pelo banco
| Tipo | Nome | Definição |
|---|---|---|
| PK | permission_use_cases_pkey | PRIMARY KEY (permission_id, use_case) |
Fora do banco
- Nenhuma regra registrada além das constraints acima.
permission_changes
Auditoria prevista de mudanças no catálogo de permissões (commit, autor, aprovador, quem fez o deploy).
| Coluna | Tipo | Nulo | Observação |
|---|---|---|---|
id | bigint | não | identity (GENERATED ALWAYS) |
permission_code | text | não | |
change | text | não | added | modified | deprecated | renamed |
before | jsonb | sim | |
after | jsonb | sim | |
commit_sha | text | não | |
commit_author | text | não | do git: declarativo |
approved_by | text | sim | aprovador do PR |
deployed_by | text | não | identidade do CI: a confiável |
recorded_at | timestamptz | não | padrão clock_timestamp() |
Chaves estrangeiras
- nenhuma
Garantido pelo banco
| Tipo | Nome | Definição |
|---|---|---|
| CHECK | permission_changes_change_check | CHECK ((change IN ('added', 'modified', 'deprecated', 'renamed'))) |
| PK | permission_changes_pkey | PRIMARY KEY (id) |
Fora do banco
- Nenhum código grava nesta tabela hoje: o registro de mudanças fica para a sincronização de deploy (NOVA-37).
access_profiles
Perfil de acesso do tenant (broker_id nulo) ou de um corretor. name é só rótulo; o que vale é a lista de permissões. Pode seguir um template (template_id, template_version) ou ter sido desvinculado (detached_at).
| Coluna | Tipo | Nulo | Observação |
|---|---|---|---|
id | bigint | não | identity (GENERATED ALWAYS) |
tenant_id | bigint | não | |
broker_id | bigint | sim | nulo = perfil do tenant |
scope | text | não | gerada: CASE WHEN (broker_id IS NULL) THEN 'tenant' ELSE 'broker' END |
name | text | não | rótulo de tela; não tem efeito |
disabled_at | timestamptz | sim | |
created_at | timestamptz | não | padrão clock_timestamp() |
updated_at | timestamptz | não | padrão clock_timestamp() |
template_id | bigint | sim | ligado ao template (herda ao vivo) |
template_version | integer | sim | versão que segue |
detached_at | timestamptz | sim | fork: passa a usar permissões próprias |
detached_by_user_id | bigint | sim |
Chaves estrangeiras
(template_id, tenant_id, scope)→access_profile_templates (id, tenant_id, scope)(mesmo tenant)(tenant_id, broker_id)→tenant_brokers (tenant_id, broker_id)(mesmo tenant)detached_by_user_id→users.idtenant_id→tenants.id
Referenciada por: access_profile_permissions, access_profile_template_change_decisions, invitation_grants, membership_access_profiles, membership_brokers, membership_teams.
Garantido pelo banco
| Tipo | Nome | Definição |
|---|---|---|
| PK | access_profiles_pkey | PRIMARY KEY (id) |
| UNIQUE | access_profiles_id_tenant_broker_key | UNIQUE (id, tenant_id, broker_id) |
| UNIQUE | access_profiles_id_tenant_key | UNIQUE (id, tenant_id) |
| UNIQUE | access_profiles_id_tenant_scope_key | UNIQUE (id, tenant_id, scope) |
| UNIQUE (índice) | access_profiles_name_key | (tenant_id, broker_id, name) NULLS NOT DISTINCT |
| Trigger | access_profiles_scope_ceiling | teto de escopo das permissões (detalhes) |
| Coluna gerada | scope | STORED |
Fora do banco
- Quem concede só concede o que tem, sem autoconcessão: regra das rotas, não do banco.
access_profile_permissions
Permissões de um perfil. Perfil do tenant aceita permissões tenant e broker; perfil de corretor, só broker.
| Coluna | Tipo | Nulo | Observação |
|---|---|---|---|
access_profile_id | bigint | não | |
permission_id | bigint | não |
Chaves estrangeiras
access_profile_id→access_profiles.idpermission_id→permissions.id
Garantido pelo banco
| Tipo | Nome | Definição |
|---|---|---|
| PK | access_profile_permissions_pkey | PRIMARY KEY (access_profile_id, permission_id) |
| Trigger | access_profile_permissions_scope_ceiling | teto de escopo das permissões (detalhes) |
Fora do banco
- Nenhuma regra registrada além das constraints acima.
access_profile_templates
Template de perfil do tenant, versionado: perfis ligados herdam as permissões ao vivo.
| Coluna | Tipo | Nulo | Observação |
|---|---|---|---|
id | bigint | não | identity (GENERATED ALWAYS) |
tenant_id | bigint | não | |
scope | text | não | tenant | broker |
name | text | não | |
description | text | não | |
auto_assign | text | sim | tenant_admin | broker_master | broker_member |
version | integer | não | sobe a cada edição confirmada |
source_platform_template_id | bigint | sim | origem histórica |
disabled_at | timestamptz | sim | |
created_at | timestamptz | não | padrão clock_timestamp() |
updated_at | timestamptz | não | padrão clock_timestamp() |
Chaves estrangeiras
source_platform_template_id→platform_access_profile_templates.idtenant_id→tenants.id
Referenciada por: access_profile_template_changes, access_profile_template_permissions, access_profiles.
Garantido pelo banco
| Tipo | Nome | Definição |
|---|---|---|
| CHECK | access_profile_templates_auto_assign_check | CHECK ((auto_assign IN ('tenant_admin', 'broker_master', 'broker_member'))) |
| CHECK | access_profile_templates_scope_check | CHECK ((scope IN ('tenant', 'broker'))) |
| PK | access_profile_templates_pkey | PRIMARY KEY (id) |
| UNIQUE | access_profile_templates_id_tenant_key | UNIQUE (id, tenant_id) |
| UNIQUE | access_profile_templates_id_tenant_scope_key | UNIQUE (id, tenant_id, scope) |
| Trigger | access_profile_templates_scope_ceiling | teto de escopo das permissões (detalhes) |
Fora do banco
- Nenhuma regra registrada além das constraints acima.
access_profile_template_permissions
Permissões da versão atual de um template de tenant.
| Coluna | Tipo | Nulo | Observação |
|---|---|---|---|
template_id | bigint | não | |
permission_id | bigint | não |
Chaves estrangeiras
permission_id→permissions.idtemplate_id→access_profile_templates.id
Garantido pelo banco
| Tipo | Nome | Definição |
|---|---|---|
| PK | access_profile_template_permissions_pkey | PRIMARY KEY (template_id, permission_id) |
| Trigger | access_profile_template_permissions_scope_ceiling | teto de escopo das permissões (detalhes) |
Fora do banco
- Nenhuma regra registrada além das constraints acima.
access_profile_template_changes
Cada edição confirmada de um template: versões de origem e destino, permissões adicionadas e removidas, motivo e autor.
| Coluna | Tipo | Nulo | Observação |
|---|---|---|---|
id | bigint | não | identity (GENERATED ALWAYS) |
tenant_id | bigint | não | |
template_id | bigint | não | |
from_version | integer | não | |
to_version | integer | não | |
added_permission_ids | bigint[] | não | |
removed_permission_ids | bigint[] | não | |
reason | text | não | |
changed_by_user_id | bigint | não | |
changed_at | timestamptz | não | padrão clock_timestamp() |
Chaves estrangeiras
(template_id, tenant_id)→access_profile_templates (id, tenant_id)(mesmo tenant)changed_by_user_id→users.id
Referenciada por: access_profile_template_change_decisions.
Garantido pelo banco
| Tipo | Nome | Definição |
|---|---|---|
| PK | access_profile_template_changes_pkey | PRIMARY KEY (id) |
Fora do banco
- Nenhuma regra registrada além das constraints acima.
access_profile_template_change_decisions
Para cada perfil afetado por uma edição de template: acompanhou (followed) ou desvinculou (detached), e quantos usuários foram afetados.
| Coluna | Tipo | Nulo | Observação |
|---|---|---|---|
change_id | bigint | não | |
access_profile_id | bigint | não | |
decision | text | não | followed | detached |
affected_users | integer | não |
Chaves estrangeiras
access_profile_id→access_profiles.idchange_id→access_profile_template_changes.id
Garantido pelo banco
| Tipo | Nome | Definição |
|---|---|---|
| CHECK | access_profile_template_change_decisions_decision_check | CHECK ((decision IN ('followed', 'detached'))) |
| PK | access_profile_template_change_decisions_pkey | PRIMARY KEY (change_id, access_profile_id) |
Fora do banco
- Nenhuma regra registrada além das constraints acima.
platform_tenant_blueprints
Formato de tenant mantido pela plataforma; criar um tenant é escolher um blueprint.
| Coluna | Tipo | Nulo | Observação |
|---|---|---|---|
id | bigint | não | identity (GENERATED ALWAYS) |
name | text | não | |
description | text | não | |
disabled_at | timestamptz | sim | |
created_at | timestamptz | não | padrão clock_timestamp() |
updated_at | timestamptz | não | padrão clock_timestamp() |
Chaves estrangeiras
- nenhuma
Referenciada por: platform_access_profile_templates, tenants.
Garantido pelo banco
| Tipo | Nome | Definição |
|---|---|---|
| PK | platform_tenant_blueprints_pkey | PRIMARY KEY (id) |
| UNIQUE | platform_tenant_blueprints_name_unique | UNIQUE (name) |
Fora do banco
- Nenhuma regra registrada além das constraints acima.
platform_access_profile_templates
Templates de perfil de um blueprint, copiados para access_profile_templates quando o tenant é criado. Mudar aqui não afeta tenants existentes.
| Coluna | Tipo | Nulo | Observação |
|---|---|---|---|
id | bigint | não | identity (GENERATED ALWAYS) |
blueprint_id | bigint | não | |
scope | text | não | tenant | broker |
name | text | não | |
description | text | não | |
auto_assign | text | sim | tenant_admin | broker_master | broker_member |
disabled_at | timestamptz | sim | |
created_at | timestamptz | não | padrão clock_timestamp() |
updated_at | timestamptz | não | padrão clock_timestamp() |
Chaves estrangeiras
blueprint_id→platform_tenant_blueprints.id
Referenciada por: access_profile_templates, platform_access_profile_template_permissions.
Garantido pelo banco
| Tipo | Nome | Definição |
|---|---|---|
| CHECK | platform_access_profile_templates_auto_assign_check | CHECK ((auto_assign IN ('tenant_admin', 'broker_master', 'broker_member'))) |
| CHECK | platform_access_profile_templates_scope_check | CHECK ((scope IN ('tenant', 'broker'))) |
| PK | platform_access_profile_templates_pkey | PRIMARY KEY (id) |
| Trigger | platform_access_profile_templates_scope_ceiling | teto de escopo das permissões (detalhes) |
Fora do banco
- Nenhuma regra registrada além das constraints acima.
platform_access_profile_template_permissions
Permissões de um template de plataforma.
| Coluna | Tipo | Nulo | Observação |
|---|---|---|---|
template_id | bigint | não | |
permission_id | bigint | não |
Chaves estrangeiras
permission_id→permissions.idtemplate_id→platform_access_profile_templates.id
Garantido pelo banco
| Tipo | Nome | Definição |
|---|---|---|
| PK | platform_access_profile_template_permissions_pkey | PRIMARY KEY (template_id, permission_id) |
| Trigger | platform_access_profile_template_permissions_scope_ceiling | teto de escopo das permissões (detalhes) |
Fora do banco
- Nenhuma regra registrada além das constraints acima.
platform_access_profiles
Perfis acima dos tenants (por exemplo, suporte ou administração da plataforma).
| Coluna | Tipo | Nulo | Observação |
|---|---|---|---|
id | bigint | não | identity (GENERATED ALWAYS) |
name | text | não | |
disabled_at | timestamptz | sim | |
created_at | timestamptz | não | padrão clock_timestamp() |
updated_at | timestamptz | não | padrão clock_timestamp() |
Chaves estrangeiras
- nenhuma
Referenciada por: platform_access_profile_permissions, platform_grants, platform_invitations.
Garantido pelo banco
| Tipo | Nome | Definição |
|---|---|---|
| PK | platform_access_profiles_pkey | PRIMARY KEY (id) |
| UNIQUE | platform_access_profiles_name_unique | UNIQUE (name) |
Fora do banco
- Nenhuma regra registrada além das constraints acima.
platform_access_profile_permissions
Permissões de um perfil de plataforma; só permissões de escopo platform.
| Coluna | Tipo | Nulo | Observação |
|---|---|---|---|
platform_access_profile_id | bigint | não | |
permission_id | bigint | não |
Chaves estrangeiras
permission_id→permissions.idplatform_access_profile_id→platform_access_profiles.id
Garantido pelo banco
| Tipo | Nome | Definição |
|---|---|---|
| PK | platform_access_profile_permissions_pkey | PRIMARY KEY (platform_access_profile_id, permission_id) |
| Trigger | platform_access_profile_permissions_scope_ceiling | teto de escopo das permissões (detalhes) |
Fora do banco
- Nenhuma regra registrada além das constraints acima.
platform_grants
Operador de plataforma: usuário, perfil de plataforma, quem concedeu e por quê. Todo grant nasce de um convite de plataforma; o primeiro, do bootstrap.
| Coluna | Tipo | Nulo | Observação |
|---|---|---|---|
id | bigint | não | identity (GENERATED ALWAYS) |
user_id | bigint | não | |
platform_access_profile_id | bigint | não | |
granted_by_user_id | bigint | não | |
granted_at | timestamptz | não | padrão clock_timestamp() |
reason | text | não | |
revoked_by_user_id | bigint | sim | |
revoked_at | timestamptz | sim | |
origin_platform_invitation_id | bigint | não | todo grant nasce de um convite |
Chaves estrangeiras
granted_by_user_id→users.idorigin_platform_invitation_id→platform_invitations.idplatform_access_profile_id→platform_access_profiles.idrevoked_by_user_id→users.iduser_id→users.id
Referenciada por: session_contexts.
Garantido pelo banco
| Tipo | Nome | Definição |
|---|---|---|
| PK | platform_grants_pkey | PRIMARY KEY (id) |
| UNIQUE parcial | platform_grants_live_key | (user_id) WHERE (revoked_at IS NULL) |
Fora do banco
- Nenhuma regra registrada além das constraints acima.
platform_invitations
Convite para operar a plataforma. Guarda só o SHA-256 do token; tem exatamente um criador (usuário ou processo) e sempre expira.
| Coluna | Tipo | Nulo | Observação |
|---|---|---|---|
id | bigint | não | identity (GENERATED ALWAYS) |
uid | text | não | |
channel | text | não | email | phone |
destination | text | não | |
destination_normalized | text | não | |
token_sha256 | bytea | não | |
platform_access_profile_id | bigint | não | |
status | text | não | pending | accepted | revoked | expired |
expires_at | timestamptz | não | |
created_by_user_id | bigint | sim | ação humana |
created_by_process | text | sim | seed | … |
accepted_at | timestamptz | sim | |
accepted_by_user_id | bigint | sim | |
revoked_at | timestamptz | sim | |
revoked_by_user_id | bigint | sim | |
created_at | timestamptz | não | padrão clock_timestamp() |
Chaves estrangeiras
accepted_by_user_id→users.idcreated_by_user_id→users.idplatform_access_profile_id→platform_access_profiles.idrevoked_by_user_id→users.id
Referenciada por: platform_grants, platform_invitation_deliveries.
Garantido pelo banco
| Tipo | Nome | Definição |
|---|---|---|
| CHECK | platform_invitations_channel_check | CHECK ((channel IN ('email', 'phone'))) |
| CHECK | platform_invitations_creator_check | CHECK ((num_nonnulls(created_by_user_id, created_by_process) = 1)) |
| CHECK | platform_invitations_status_check | CHECK ((status IN ('pending', 'accepted', 'revoked', 'expired'))) |
| PK | platform_invitations_pkey | PRIMARY KEY (id) |
| UNIQUE | platform_invitations_token_sha256_unique | UNIQUE (token_sha256) |
| UNIQUE | platform_invitations_uid_unique | UNIQUE (uid) |
Fora do banco
- Nenhuma regra registrada além das constraints acima.
platform_invitation_deliveries
Cada tentativa de envio de um convite de plataforma; reenvio é uma linha nova.
| Coluna | Tipo | Nulo | Observação |
|---|---|---|---|
id | bigint | não | identity (GENERATED ALWAYS) |
uid | text | não | |
platform_invitation_id | bigint | não | |
channel | text | não | email | sms | whatsapp |
destination_normalized | text | não | foto no envio |
provider | text | não | |
provider_message_id | text | sim | |
status | text | não | queued | sent | delivered | opened | clicked | bounced | failed | complained |
queued_at | timestamptz | não | padrão clock_timestamp() |
sent_at | timestamptz | sim | |
delivered_at | timestamptz | sim | |
opened_at | timestamptz | sim | |
failed_at | timestamptz | sim | |
failure_reason | text | sim | |
requested_by_user_id | bigint | sim | |
requested_by_process | text | sim |
Chaves estrangeiras
platform_invitation_id→platform_invitations.idrequested_by_user_id→users.id
Referenciada por: platform_invitation_delivery_events.
Garantido pelo banco
| Tipo | Nome | Definição |
|---|---|---|
| CHECK | platform_invitation_deliveries_channel_check | CHECK ((channel IN ('email', 'sms', 'whatsapp'))) |
| CHECK | platform_invitation_deliveries_requester_check | CHECK ((num_nonnulls(requested_by_user_id, requested_by_process) = 1)) |
| CHECK | platform_invitation_deliveries_status_check | CHECK ((status IN ('queued', 'sent', 'delivered', 'opened', 'clicked', 'bounced', 'failed', 'complained'))) |
| PK | platform_invitation_deliveries_pkey | PRIMARY KEY (id) |
| UNIQUE | platform_invitation_deliveries_provider_message_key | UNIQUE (provider, provider_message_id) |
| UNIQUE | platform_invitation_deliveries_uid_unique | UNIQUE (uid) |
Fora do banco
- Nenhuma regra registrada além das constraints acima.
platform_invitation_delivery_events
Linha do tempo bruta do provedor de envio; um webhook repetido não duplica (dedup_key).
| Coluna | Tipo | Nulo | Observação |
|---|---|---|---|
id | bigint | não | identity (GENERATED ALWAYS) |
delivery_id | bigint | não | |
status | text | não | |
occurred_at | timestamptz | não | horário do provedor, em UTC |
received_at | timestamptz | não | padrão clock_timestamp() |
dedup_key | text | não | id do evento ou sha256 do payload |
payload | jsonb | não | padrão '{}'::jsonb; webhook como chegou, sem token |
Chaves estrangeiras
delivery_id→platform_invitation_deliveries.id
Garantido pelo banco
| Tipo | Nome | Definição |
|---|---|---|
| CHECK | platform_invitation_delivery_events_payload_size_check | CHECK ((pg_column_size(payload) < 64000)) |
| PK | platform_invitation_delivery_events_pkey | PRIMARY KEY (id) |
| UNIQUE | platform_invitation_delivery_events_dedup_key | UNIQUE (delivery_id, dedup_key) |
Fora do banco
- Nenhuma regra registrada além das constraints acima.
session_contexts
Operador de plataforma atuando dentro de um tenant, com motivo. Não é impersonação: o ator continua sendo o usuário real.
| Coluna | Tipo | Nulo | Observação |
|---|---|---|---|
id | bigint | não | identity (GENERATED ALWAYS) |
session_id | bigint | não | |
platform_grant_id | bigint | não | |
tenant_id | bigint | não | |
reason | text | não | |
entered_at | timestamptz | não | padrão clock_timestamp() |
left_at | timestamptz | sim |
Chaves estrangeiras
platform_grant_id→platform_grants.idsession_id→sessions.idtenant_id→tenants.id
Referenciada por: invitation_session_contexts.
Garantido pelo banco
| Tipo | Nome | Definição |
|---|---|---|
| PK | session_contexts_pkey | PRIMARY KEY (id) |
| UNIQUE | session_contexts_id_tenant_key | UNIQUE (id, tenant_id) |
| UNIQUE parcial | session_contexts_live_key | (session_id) WHERE (left_at IS NULL) |
Fora do banco
- Hoje nenhuma sessão é criada (autenticação em reconstrução), então a tabela fica vazia.