Skip to content

Contrato dos filtros e resumos das listas do admin — papéis e organizações ​

Base URL /api/v1. Erros em application/problem+json, com o código estável em code. Consumido pelo admin-mfe do gryd.ui (US-5.2 do layout Trilho: perfis e organizações).

1. O que mudou ​

ItemRotaMudança
Escopo "empresas com grupo"GET /tenants, GET /admin/tenantsvalor novo hierarchyScope=grouped
Portadores de um papelGET /roles, GET /roles/{id}campo novo userCount, sempre presente
Filtro de papéis de sistemaGET /rolesparâmetro novo isSystemRole
Resumo de papéisGET /roles/summaryrota nova
Resumo de organizaçõesGET /tenants/summary, GET /admin/tenants/summaryrotas novas

Nada foi removido nem mudou de significado: quem não manda os parâmetros novos recebe o que recebia antes. summary é um segmento literal e tem precedência sobre /{id} nas três rotas.

2. Organizações ​

2.1 hierarchyScope ​

ValorListaparentTenantId
all (default)tudoproibido
rootsem pai: os grupos e as empresas fora de grupoproibido
groupedas empresas de qualquer grupo (parentTenantId preenchido)proibido
childrenas empresas de um grupoobrigatório

A regra de combinação não mudou e tem o mesmo código: children sem parentTenantId, ou parentTenantId com qualquer outro escopo (inclusive grouped), é 400TENANT_FILTER_COMBINATION_INVALID.

Vale nos dois trilhos da listagem e combina com search, type, isActive, ordenação e paginação. No trilho escopado (/tenants), grouped continua dentro do alcance de quem chama: um GroupAdmin vê as empresas ativas do seu grupo, não as de outros grupos. grouped + type=group é sempre vazio (grupo não tem pai).

Os lookups (/tenants/lookup, /admin/tenants/lookup) usam o mesmo filtro e também aceitam grouped.

2.2 Resumo — GET /tenants/summary e GET /admin/tenants/summary ​

GET /api/v1/admin/tenants/summary?search=acme&hierarchyScope=grouped&type=company&isActive=true
ParâmetroRegras
searcho da listagem: nome, domínio ou descrição
isActivetrue, false ou ausente (ambos)
typecompany, group ou ausente (ambos)
hierarchyScopeall, root, grouped ou children (§2.1)
parentTenantIdsó com children (§2.1)
jsonc
{ "groups": 2, "companies": 6, "inactive": 2, "activeUserLinks": 41 }
CampoSignificadoIgual a
groupsorganizações do tipo grupo que casam com os filtrostotalCount da listagem com type=group
companiesorganizações do tipo empresa que casam com os filtrostotalCount da listagem com type=company
inactiveas que casam e estão desativadas, dos dois tipostotalCount da listagem com isActive=false
activeUserLinksvínculos ativos de usuários com essas organizaçõessoma do activeUserCount das linhas da listagem
  • groups + companies é o total (aba "Todas"): toda organização é grupo ou empresa.
  • Cada vínculo pertence a uma organização, então é contado uma vez só. Conta o vínculo ativo e não excluído, com o mesmo critério da coluna activeUserCount da listagem, sem olhar se o usuário está ativo.
  • Organização excluída nunca entra.
  • Tudo sai de uma única consulta agregada.

Qual rota usar. A mesma regra da listagem, pelo capabilities.tenants.default da sessão:

capabilities.tenants.defaultRotaAlcancePermissão
globalGET /admin/tenants/summarya plataforma inteiraadmin:system ou manage:all-tenants
tenantGET /tenants/summaryos vínculos ativos de quem chama + as empresas ativas dos grupos que administraread:tenants

Um admin:system recebe números diferentes nas duas rotas quando só tem vínculo com parte das organizações (decisão D9). É o esperado: cada resumo bate com a lista do seu trilho.

3. Papéis ​

3.1 userCount — GET /roles e GET /roles/{id} ​

Cada papel passa a trazer userCount: number, sempre presente:

jsonc
{ "id": "…", "name": "Gerente", "isSystemRole": false, "permissions": [ … ], "userCount": 3 }
  • Conta os usuários ativos que têm o papel no tenant do token. São os usuários ativos de GET /roles/{roleId}/users: vínculo ativo com o tenant, usuário ativo e não excluído.
  • 0 quando ninguém tem o papel.
  • Uma pessoa com vínculo em dois tenants conta só pelo vínculo com o tenant do token.
  • A listagem conta a página inteira numa consulta agrupada. O detalhe mostra o mesmo número da linha.

GET /admin/tenants/{tenantId}/roles (trilho admin) traz o mesmo campo, contado no tenant da rota. O RoleDto embutido em outras respostas (usuário, /users/{id}/roles, create/update de papel) não ganhou o campo.

3.2 isSystemRole — GET /roles ​

isSystemRoleLista
truesó papéis de sistema
falsesó papéis personalizados
ausentetodos

includeSystemRoles continua aceito para os clientes que ainda o mandam (false esconde os papéis de sistema). Precedência:

includeSystemRolesisSystemRoleResultado
ausente/truequalquerisSystemRole decide
falseausente ou falsesó personalizados
falsetrue400 ROLE_FILTER_COMBINATION_INVALID (mensagem localizada)

O mesmo vale em GET /admin/tenants/{tenantId}/roles.

3.3 Resumo — GET /roles/summary ​

GET /api/v1/roles/summary?search=gest
jsonc
{ "total": 5, "systemRoles": 2, "customRoles": 3, "assignedPermissions": 18 }
CampoSignificadoIgual a
totalpapéis do tenant do token que casam com searchtotalCount de GET /roles?search=
systemRolesdesses, os de sistematotalCount com isSystemRole=true
customRolesdesses, os personalizadostotalCount com isSystemRole=false
assignedPermissionspermissões distintas atribuídas a pelo menos um desses papéis—

search é o da listagem (nome ou descrição). Permissão: read:roles, a mesma de GET /roles. Tudo sai de uma única consulta agregada.

4. Códigos de erro ​

CódigoStatusQuando
TENANT_FILTER_COMBINATION_INVALID400children sem parentTenantId; parentTenantId com outro escopo
ROLE_FILTER_COMBINATION_INVALID400includeSystemRoles=false com isSystemRole=true

Released under the MIT License.