Monalisa
Modelo de dados

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)

TabelaPara quê
permissionsProjeçã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_casesQuais use cases exigem cada permissão; sincronizado no deploy.
permission_changesAuditoria prevista de mudanças no catálogo de permissões (commit, autor, aprovador, quem fez o deploy).
access_profilesPerfil de acesso do tenant (broker_id nulo) ou de um corretor.
access_profile_permissionsPermissões de um perfil.
access_profile_templatesTemplate de perfil do tenant, versionado: perfis ligados herdam as permissões ao vivo.
access_profile_template_permissionsPermissões da versão atual de um template de tenant.
access_profile_template_changesCada edição confirmada de um template: versões de origem e destino, permissões adicionadas e removidas, motivo e autor.
access_profile_template_change_decisionsPara cada perfil afetado por uma edição de template: acompanhou (followed) ou desvinculou (detached), e quantos usuários foram afetados.
platform_tenant_blueprintsFormato de tenant mantido pela plataforma; criar um tenant é escolher um blueprint.
platform_access_profile_templatesTemplates de perfil de um blueprint, copiados para access_profile_templates quando o tenant é criado.
platform_access_profile_template_permissionsPermissões de um template de plataforma.
platform_access_profilesPerfis acima dos tenants (por exemplo, suporte ou administração da plataforma).
platform_access_profile_permissionsPermissões de um perfil de plataforma; só permissões de escopo platform.
platform_grantsOperador de plataforma: usuário, perfil de plataforma, quem concedeu e por quê.
platform_invitationsConvite para operar a plataforma.
platform_invitation_deliveriesCada tentativa de envio de um convite de plataforma; reenvio é uma linha nova.
platform_invitation_delivery_eventsLinha do tempo bruta do provedor de envio; um webhook repetido não duplica (dedup_key).
session_contextsOperador 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.

ColunaTipoNuloObservação
idbigintnãoidentity (GENERATED ALWAYS)
codetextnão<domain>.<resource>.<action>
scopetextnãoplatform | tenant | broker
descriptiontextnão
replaces_codetextsimrename explícito
introduced_attimestamptznãopadrão clock_timestamp()
deprecated_attimestamptzsimsaiu 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

TipoNomeDefinição
CHECKpermissions_scope_checkCHECK ((scope IN ('platform', 'tenant', 'broker')))
PKpermissions_pkeyPRIMARY KEY (id)
UNIQUEpermissions_code_uniqueUNIQUE (code)
Triggerpermissions_scope_ceilingteto de escopo das permissões (detalhes)

Fora do banco

  • O seeder de permissões faz upsert por code e atualiza description e scope. Marcar deprecated_at, tratar replaces_code e registrar permission_changes ficam para a sincronização de deploy (NOVA-37).

permission_use_cases

Quais use cases exigem cada permissão; sincronizado no deploy.

ColunaTipoNuloObservação
permission_idbigintnão
use_casetextnão

Chaves estrangeiras

  • permission_id → permissions.id

Garantido pelo banco

TipoNomeDefinição
PKpermission_use_cases_pkeyPRIMARY 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).

ColunaTipoNuloObservação
idbigintnãoidentity (GENERATED ALWAYS)
permission_codetextnão
changetextnãoadded | modified | deprecated | renamed
beforejsonbsim
afterjsonbsim
commit_shatextnão
commit_authortextnãodo git: declarativo
approved_bytextsimaprovador do PR
deployed_bytextnãoidentidade do CI: a confiável
recorded_attimestamptznãopadrão clock_timestamp()

Chaves estrangeiras

  • nenhuma

Garantido pelo banco

TipoNomeDefinição
CHECKpermission_changes_change_checkCHECK ((change IN ('added', 'modified', 'deprecated', 'renamed')))
PKpermission_changes_pkeyPRIMARY 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).

ColunaTipoNuloObservação
idbigintnãoidentity (GENERATED ALWAYS)
tenant_idbigintnão
broker_idbigintsimnulo = perfil do tenant
scopetextnãogerada: CASE WHEN (broker_id IS NULL) THEN 'tenant' ELSE 'broker' END
nametextnãorótulo de tela; não tem efeito
disabled_attimestamptzsim
created_attimestamptznãopadrão clock_timestamp()
updated_attimestamptznãopadrão clock_timestamp()
template_idbigintsimligado ao template (herda ao vivo)
template_versionintegersimversão que segue
detached_attimestamptzsimfork: passa a usar permissões próprias
detached_by_user_idbigintsim

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.id
  • tenant_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

TipoNomeDefinição
PKaccess_profiles_pkeyPRIMARY KEY (id)
UNIQUEaccess_profiles_id_tenant_broker_keyUNIQUE (id, tenant_id, broker_id)
UNIQUEaccess_profiles_id_tenant_keyUNIQUE (id, tenant_id)
UNIQUEaccess_profiles_id_tenant_scope_keyUNIQUE (id, tenant_id, scope)
UNIQUE (índice)access_profiles_name_key(tenant_id, broker_id, name) NULLS NOT DISTINCT
Triggeraccess_profiles_scope_ceilingteto de escopo das permissões (detalhes)
Coluna geradascopeSTORED

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.

ColunaTipoNuloObservação
access_profile_idbigintnão
permission_idbigintnão

Chaves estrangeiras

  • access_profile_id → access_profiles.id
  • permission_id → permissions.id

Garantido pelo banco

TipoNomeDefinição
PKaccess_profile_permissions_pkeyPRIMARY KEY (access_profile_id, permission_id)
Triggeraccess_profile_permissions_scope_ceilingteto 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.

ColunaTipoNuloObservação
idbigintnãoidentity (GENERATED ALWAYS)
tenant_idbigintnão
scopetextnãotenant | broker
nametextnão
descriptiontextnão
auto_assigntextsimtenant_admin | broker_master | broker_member
versionintegernãosobe a cada edição confirmada
source_platform_template_idbigintsimorigem histórica
disabled_attimestamptzsim
created_attimestamptznãopadrão clock_timestamp()
updated_attimestamptznãopadrão clock_timestamp()

Chaves estrangeiras

  • source_platform_template_id → platform_access_profile_templates.id
  • tenant_id → tenants.id

Referenciada por: access_profile_template_changes, access_profile_template_permissions, access_profiles.

Garantido pelo banco

TipoNomeDefinição
CHECKaccess_profile_templates_auto_assign_checkCHECK ((auto_assign IN ('tenant_admin', 'broker_master', 'broker_member')))
CHECKaccess_profile_templates_scope_checkCHECK ((scope IN ('tenant', 'broker')))
PKaccess_profile_templates_pkeyPRIMARY KEY (id)
UNIQUEaccess_profile_templates_id_tenant_keyUNIQUE (id, tenant_id)
UNIQUEaccess_profile_templates_id_tenant_scope_keyUNIQUE (id, tenant_id, scope)
Triggeraccess_profile_templates_scope_ceilingteto 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.

ColunaTipoNuloObservação
template_idbigintnão
permission_idbigintnão

Chaves estrangeiras

  • permission_id → permissions.id
  • template_id → access_profile_templates.id

Garantido pelo banco

TipoNomeDefinição
PKaccess_profile_template_permissions_pkeyPRIMARY KEY (template_id, permission_id)
Triggeraccess_profile_template_permissions_scope_ceilingteto 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.

ColunaTipoNuloObservação
idbigintnãoidentity (GENERATED ALWAYS)
tenant_idbigintnão
template_idbigintnão
from_versionintegernão
to_versionintegernão
added_permission_idsbigint[]não
removed_permission_idsbigint[]não
reasontextnão
changed_by_user_idbigintnão
changed_attimestamptznãopadrã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

TipoNomeDefinição
PKaccess_profile_template_changes_pkeyPRIMARY 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.

ColunaTipoNuloObservação
change_idbigintnão
access_profile_idbigintnão
decisiontextnãofollowed | detached
affected_usersintegernão

Chaves estrangeiras

  • access_profile_id → access_profiles.id
  • change_id → access_profile_template_changes.id

Garantido pelo banco

TipoNomeDefinição
CHECKaccess_profile_template_change_decisions_decision_checkCHECK ((decision IN ('followed', 'detached')))
PKaccess_profile_template_change_decisions_pkeyPRIMARY 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.

ColunaTipoNuloObservação
idbigintnãoidentity (GENERATED ALWAYS)
nametextnão
descriptiontextnão
disabled_attimestamptzsim
created_attimestamptznãopadrão clock_timestamp()
updated_attimestamptznãopadrão clock_timestamp()

Chaves estrangeiras

  • nenhuma

Referenciada por: platform_access_profile_templates, tenants.

Garantido pelo banco

TipoNomeDefinição
PKplatform_tenant_blueprints_pkeyPRIMARY KEY (id)
UNIQUEplatform_tenant_blueprints_name_uniqueUNIQUE (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.

ColunaTipoNuloObservação
idbigintnãoidentity (GENERATED ALWAYS)
blueprint_idbigintnão
scopetextnãotenant | broker
nametextnão
descriptiontextnão
auto_assigntextsimtenant_admin | broker_master | broker_member
disabled_attimestamptzsim
created_attimestamptznãopadrão clock_timestamp()
updated_attimestamptznãopadrão clock_timestamp()

Chaves estrangeiras

  • blueprint_id → platform_tenant_blueprints.id

Referenciada por: access_profile_templates, platform_access_profile_template_permissions.

Garantido pelo banco

TipoNomeDefinição
CHECKplatform_access_profile_templates_auto_assign_checkCHECK ((auto_assign IN ('tenant_admin', 'broker_master', 'broker_member')))
CHECKplatform_access_profile_templates_scope_checkCHECK ((scope IN ('tenant', 'broker')))
PKplatform_access_profile_templates_pkeyPRIMARY KEY (id)
Triggerplatform_access_profile_templates_scope_ceilingteto 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.

ColunaTipoNuloObservação
template_idbigintnão
permission_idbigintnão

Chaves estrangeiras

  • permission_id → permissions.id
  • template_id → platform_access_profile_templates.id

Garantido pelo banco

TipoNomeDefinição
PKplatform_access_profile_template_permissions_pkeyPRIMARY KEY (template_id, permission_id)
Triggerplatform_access_profile_template_permissions_scope_ceilingteto 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).

ColunaTipoNuloObservação
idbigintnãoidentity (GENERATED ALWAYS)
nametextnão
disabled_attimestamptzsim
created_attimestamptznãopadrão clock_timestamp()
updated_attimestamptznãopadrão clock_timestamp()

Chaves estrangeiras

  • nenhuma

Referenciada por: platform_access_profile_permissions, platform_grants, platform_invitations.

Garantido pelo banco

TipoNomeDefinição
PKplatform_access_profiles_pkeyPRIMARY KEY (id)
UNIQUEplatform_access_profiles_name_uniqueUNIQUE (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.

ColunaTipoNuloObservação
platform_access_profile_idbigintnão
permission_idbigintnão

Chaves estrangeiras

  • permission_id → permissions.id
  • platform_access_profile_id → platform_access_profiles.id

Garantido pelo banco

TipoNomeDefinição
PKplatform_access_profile_permissions_pkeyPRIMARY KEY (platform_access_profile_id, permission_id)
Triggerplatform_access_profile_permissions_scope_ceilingteto 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.

ColunaTipoNuloObservação
idbigintnãoidentity (GENERATED ALWAYS)
user_idbigintnão
platform_access_profile_idbigintnão
granted_by_user_idbigintnão
granted_attimestamptznãopadrão clock_timestamp()
reasontextnão
revoked_by_user_idbigintsim
revoked_attimestamptzsim
origin_platform_invitation_idbigintnãotodo grant nasce de um convite

Chaves estrangeiras

  • granted_by_user_id → users.id
  • origin_platform_invitation_id → platform_invitations.id
  • platform_access_profile_id → platform_access_profiles.id
  • revoked_by_user_id → users.id
  • user_id → users.id

Referenciada por: session_contexts.

Garantido pelo banco

TipoNomeDefinição
PKplatform_grants_pkeyPRIMARY KEY (id)
UNIQUE parcialplatform_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.

ColunaTipoNuloObservação
idbigintnãoidentity (GENERATED ALWAYS)
uidtextnão
channeltextnãoemail | phone
destinationtextnão
destination_normalizedtextnão
token_sha256byteanão
platform_access_profile_idbigintnão
statustextnãopending | accepted | revoked | expired
expires_attimestamptznão
created_by_user_idbigintsimação humana
created_by_processtextsimseed | …
accepted_attimestamptzsim
accepted_by_user_idbigintsim
revoked_attimestamptzsim
revoked_by_user_idbigintsim
created_attimestamptznãopadrão clock_timestamp()

Chaves estrangeiras

  • accepted_by_user_id → users.id
  • created_by_user_id → users.id
  • platform_access_profile_id → platform_access_profiles.id
  • revoked_by_user_id → users.id

Referenciada por: platform_grants, platform_invitation_deliveries.

Garantido pelo banco

TipoNomeDefinição
CHECKplatform_invitations_channel_checkCHECK ((channel IN ('email', 'phone')))
CHECKplatform_invitations_creator_checkCHECK ((num_nonnulls(created_by_user_id, created_by_process) = 1))
CHECKplatform_invitations_status_checkCHECK ((status IN ('pending', 'accepted', 'revoked', 'expired')))
PKplatform_invitations_pkeyPRIMARY KEY (id)
UNIQUEplatform_invitations_token_sha256_uniqueUNIQUE (token_sha256)
UNIQUEplatform_invitations_uid_uniqueUNIQUE (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.

ColunaTipoNuloObservação
idbigintnãoidentity (GENERATED ALWAYS)
uidtextnão
platform_invitation_idbigintnão
channeltextnãoemail | sms | whatsapp
destination_normalizedtextnãofoto no envio
providertextnão
provider_message_idtextsim
statustextnãoqueued | sent | delivered | opened | clicked | bounced | failed | complained
queued_attimestamptznãopadrão clock_timestamp()
sent_attimestamptzsim
delivered_attimestamptzsim
opened_attimestamptzsim
failed_attimestamptzsim
failure_reasontextsim
requested_by_user_idbigintsim
requested_by_processtextsim

Chaves estrangeiras

  • platform_invitation_id → platform_invitations.id
  • requested_by_user_id → users.id

Referenciada por: platform_invitation_delivery_events.

Garantido pelo banco

TipoNomeDefinição
CHECKplatform_invitation_deliveries_channel_checkCHECK ((channel IN ('email', 'sms', 'whatsapp')))
CHECKplatform_invitation_deliveries_requester_checkCHECK ((num_nonnulls(requested_by_user_id, requested_by_process) = 1))
CHECKplatform_invitation_deliveries_status_checkCHECK ((status IN ('queued', 'sent', 'delivered', 'opened', 'clicked', 'bounced', 'failed', 'complained')))
PKplatform_invitation_deliveries_pkeyPRIMARY KEY (id)
UNIQUEplatform_invitation_deliveries_provider_message_keyUNIQUE (provider, provider_message_id)
UNIQUEplatform_invitation_deliveries_uid_uniqueUNIQUE (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).

ColunaTipoNuloObservação
idbigintnãoidentity (GENERATED ALWAYS)
delivery_idbigintnão
statustextnão
occurred_attimestamptznãohorário do provedor, em UTC
received_attimestamptznãopadrão clock_timestamp()
dedup_keytextnãoid do evento ou sha256 do payload
payloadjsonbnãopadrão '{}'::jsonb; webhook como chegou, sem token

Chaves estrangeiras

  • delivery_id → platform_invitation_deliveries.id

Garantido pelo banco

TipoNomeDefinição
CHECKplatform_invitation_delivery_events_payload_size_checkCHECK ((pg_column_size(payload) < 64000))
PKplatform_invitation_delivery_events_pkeyPRIMARY KEY (id)
UNIQUEplatform_invitation_delivery_events_dedup_keyUNIQUE (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.

ColunaTipoNuloObservação
idbigintnãoidentity (GENERATED ALWAYS)
session_idbigintnão
platform_grant_idbigintnão
tenant_idbigintnão
reasontextnão
entered_attimestamptznãopadrão clock_timestamp()
left_attimestamptzsim

Chaves estrangeiras

  • platform_grant_id → platform_grants.id
  • session_id → sessions.id
  • tenant_id → tenants.id

Referenciada por: invitation_session_contexts.

Garantido pelo banco

TipoNomeDefinição
PKsession_contexts_pkeyPRIMARY KEY (id)
UNIQUEsession_contexts_id_tenant_keyUNIQUE (id, tenant_id)
UNIQUE parcialsession_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.

Nesta página