Skip to content

GrydAuth CRUD Endpoints (V1)

Referencia oficial dos endpoints de gestao do modulo Auth (V1).

Escopo

Este documento cobre:

  • UsersController (/api/v1/users/*)
  • AdminUsersController (/api/v1/admin/users/*)
  • RolesController (/api/v1/roles/*)
  • PermissionsController (/api/v1/permissions/*)
  • TenantsController (/api/v1/tenants/*)
  • AdminTenantsController (/api/v1/admin/tenants/*)

De/Para frontend (migracao)

Endpoints removidos

  • GET /api/v1/users/{id}/tenant-access
  • PUT /api/v1/users/{id}/tenant-access
  • PUT /api/v1/admin/users/{id}/tenant-access (nao existe no contrato final)

Endpoints alterados

  • GET /api/v1/admin/users/{id}
    • Agora retorna UserDto com matriz completa em tenants.
  • PUT /api/v1/admin/users/{id}
    • Contrato unico de atualizacao admin com blocos opcionais.
    • tenants (quando enviado) executa full replace da matriz tenant/roles do usuario.

Endpoints principais para tela admin de usuarios

  • POST /api/v1/admin/users
  • GET /api/v1/admin/users
  • GET /api/v1/admin/users/{id}
  • PUT /api/v1/admin/users/{id}
  • GET /api/v1/admin/tenants/{tenantId}/roles (apoio para montar selecao de roles por tenant)

Contrato HTTP

  • Base path: /api/v1
  • Sucesso: payload direto (sem envelope Result<T> no body)
  • Erro: ProblemDetails (application/problem+json)

Shape de erro

json
{
  "type": "https://gryd.io/errors/not-found",
  "title": "Not Found",
  "status": 404,
  "detail": "User not found",
  "instance": "/api/v1/admin/users/550e8400-e29b-41d4-a716-446655440000",
  "traceId": "00-...",
  "code": "USER_NOT_FOUND",
  "errors": ["User not found"]
}

Query params comuns (QueryParameters)

  • page (default 1)
  • pageSize (default 20, max 100)
  • sortBy (opcional)
  • sortDirection (Ascending | Descending)
  • search (opcional)
  • includeDeleted (default false)

DTOs principais

CreateUserDto

json
{
  "email": "novo@empresa.com",
  "password": "SenhaForte123!",
  "isPasswordEncrypted": false,
  "firstName": "Novo",
  "lastName": "Usuario",
  "phoneNumber": "+5511999999999",
  "tenants": [
    {
      "tenantId": "11111111-1111-1111-1111-111111111111",
      "roleIds": [
        "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
      ],
      "isDefault": true
    }
  ],
  "appIds": ["APP_WEB"],
  "isActive": true
}

UpdateUserDto (tenant-scoped)

json
{
  "firstName": "Nome",
  "lastName": "Sobrenome",
  "phoneNumber": "+5511999999999",
  "appIds": ["APP_WEB"],
  "isActive": true
}

AdminUpdateUserDto (contrato unico de update admin)

json
{
  "firstName": "Nome",
  "lastName": "Sobrenome",
  "phoneNumber": "+5511999999999",
  "appIds": ["APP_WEB"],
  "isActive": true,
  "tenants": [
    {
      "tenantId": "11111111-1111-1111-1111-111111111111",
      "roleIds": [
        "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
      ],
      "isDefault": true
    },
    {
      "tenantId": "22222222-2222-2222-2222-222222222222",
      "roleIds": [],
      "isDefault": false
    }
  ]
}

Regra de tenants no PUT /api/v1/admin/users/{id}:

  • tenants = null (ou omitido): nao altera matriz tenant/roles.
  • tenants = []: remove todos os vinculos tenant/roles do usuario.
  • tenants preenchido: substitui a matriz inteira (full replace).

AdminUserEditDto (retorno de edicao admin)

Shape usado por:

  • GET /api/v1/admin/users
  • GET /api/v1/admin/users/{id}
  • PUT /api/v1/admin/users/{id}

Campos:

  • id, email, firstName, lastName, phoneNumber, isActive
  • createdAt, updatedAt
  • appIds
  • tenants:
    • tenantId, roleIds, isDefault

Obs:

  • POST /api/v1/admin/users ainda retorna UserDto.
  • Fluxo recomendado para front: apos criar, chamar GET /api/v1/admin/users/{id} para hidratar a tela de edicao no contrato unificado.

Admin Users

Base route: /api/v1/admin/users

Permissao padrao: admin:system

Regras de autorizacao para rotas cross-tenant (/api/v1/admin/users*):

  • Requer claim/permissao admin:system.
  • Requer User.AllowCrossTenantAccess = true (controle de seguranca para bypass de tenant filter).
  • Falha nessas regras retorna 403 com code = CROSS_TENANT_FORBIDDEN.
MetodoRotaRequestResponse sucesso
GET/api/v1/admin/usersQuery UsersQueryParameters + tenantId opcional200 PagedResult<AdminUserEditDto>
POST/api/v1/admin/usersBody CreateUserDto201 UserDto + Location
GET/api/v1/admin/users/{id}Path id200 AdminUserEditDto
PUT/api/v1/admin/users/{id}Path id + Body AdminUpdateUserDto200 AdminUserEditDto
DELETE/api/v1/admin/users/{id}Path id200 vazio
GET/api/v1/admin/users/{id}/tenantsPath id200 UserTenantDto[]

Users (tenant-scoped)

Base route: /api/v1/users

MetodoRotaPermissaoRequestResponse sucesso
GET/api/v1/usersread:usersQuery UsersQueryParameters200 PagedResult<UserDto>
GET/api/v1/users/{id}read:usersPath id200 UserDto
GET/api/v1/users/by-email/{email}read:usersPath email200 UserDto
POST/api/v1/userscreate:usersBody CreateUserDto201 UserDto + Location
PUT/api/v1/users/{id}update:usersPath id + Body UpdateUserDto200 UserDto
DELETE/api/v1/users/{id}delete:usersPath id200 vazio
GET/api/v1/users/{userId}/permissionsread:usersPath userId200 string[]
GET/api/v1/users/{userId}/rolesread:usersPath userId200 RoleDto[]
GET/api/v1/users/{userId}/tenantsread:usersPath userId200 UserTenantDto[]
POST/api/v1/users/{id}/activateupdate:usersPath id200 vazio
POST/api/v1/users/{id}/deactivateupdate:usersPath id200 vazio

Admin Tenants

Base route: /api/v1/admin/tenants

Permissao: admin:system

MetodoRotaRequestResponse sucesso
GET/api/v1/admin/tenants/{tenantId}/rolesPath tenantId + Query RolesQueryParameters200 PagedResult<RoleDto>

Roles

Base route: /api/v1/roles

MetodoRotaPermissaoRequestResponse sucesso
GET/api/v1/rolesread:rolesQuery RolesQueryParameters200 PagedResult<RoleDto>
GET/api/v1/roles/{id}read:rolesPath id200 RoleDto
POST/api/v1/rolescreate:rolesBody CreateRoleDto201 RoleDto + Location
PUT/api/v1/roles/{id}update:rolesPath id + Body UpdateRoleDto200 RoleDto
DELETE/api/v1/roles/{id}delete:rolesPath id200 vazio

UpdateRoleDto agora suporta sincronizacao da lista de permissoes (permissionIds) no proprio PUT /api/v1/roles/{id}:

  • permissionIds = null (ou omitido): nao altera permissoes do role.
  • permissionIds = []: remove todas as permissoes do role.
  • permissionIds preenchido: substitui integralmente a lista (full replace).

Permissions

Base route: /api/v1/permissions

MetodoRotaPermissaoRequestResponse sucesso
GET/api/v1/permissionsread:permissionsQuery PermissionsQueryParameters200 PagedResult<PermissionDetailsDto>
GET/api/v1/permissions/catalogread:permissionsQuery PermissionCatalogQueryParameters200 PagedResult<PermissionCatalogGroupDto>
GET/api/v1/permissions/catalog/categoriesread:permissionsQuery PermissionCategorySuggestionsQueryParameters200 PermissionCategorySuggestionResultDto
GET/api/v1/permissions/{id}read:permissionsPath id200 PermissionDetailsDto
GET/api/v1/permissions/by-code/{code}read:permissionsPath code200 PermissionDetailsDto
POST/api/v1/permissionscreate:permissionsBody CreatePermissionDto (code, description, category)201 PermissionDetailsDto + Location
GET/api/v1/permissions/import/templatecreate:permissionsQuery format (Csv/Json) + mode (Permissions/Catalog)200 arquivo (text/csv ou application/json)
POST/api/v1/permissions/importcreate:permissionsBody PermissionImportRequestDto + Query mode, upsert, dryRun200 PermissionImportResultDto
POST/api/v1/permissions/import/filecreate:permissionsMultipart (file) + Query mode, upsert, dryRun200 PermissionImportResultDto
PUT/api/v1/permissions/{id}update:permissionsPath id + Body UpdatePermissionDto (description, category)200 PermissionDetailsDto
DELETE/api/v1/permissions/{id}delete:permissionsPath id200 vazio

Tenants

Base route: /api/v1/tenants

MetodoRotaPermissaoRequestResponse sucesso
GET/api/v1/tenantsread:tenantsQuery TenantsQueryParameters200 PagedResult<TenantDto>
GET/api/v1/tenants/{id}read:tenantsPath id200 TenantDto
POST/api/v1/tenantscreate:tenantsBody CreateTenantDto201 TenantDto + Location
PUT/api/v1/tenants/{id}update:tenantsPath id + Body UpdateTenantDto200 TenantDto
DELETE/api/v1/tenants/{id}delete:tenantsPath id200 vazio

Observacoes frontend

  • Guia detalhado de migracao (catalogo de permissoes e breaking changes):
    • docs/modules/auth/frontend-permissions-migration.md
  • Fluxo recomendado de criacao/edicao admin:
    1. POST /api/v1/admin/users para criar.
    2. GET /api/v1/admin/users/{id} para carregar tela de edicao (inclui tenants).
    3. PUT /api/v1/admin/users/{id} para salvar tudo em uma chamada unica.
  • Para montar seletor de roles por tenant em tela admin:
    • use GET /api/v1/admin/tenants/{tenantId}/roles.
  • Para tela de permissao por funcionalidade:
    • use GET /api/v1/permissions/catalog (lista agrupada por categoria).
    • use GET /api/v1/permissions/catalog/categories (autocomplete de categorias).
    • para carga em massa, use POST /api/v1/permissions/import ou POST /api/v1/permissions/import/file.
  • Trate erros sempre por ProblemDetails (detail, code, errors, traceId).

Erros de autenticacao/autorizacao (regra de consumo)

  • 401 (TOKEN_MISSING, TOKEN_INVALID, TOKEN_EXPIRED, TOKEN_REVOKED, SESSION_INVALIDATED): sessao invalida, fluxo de reautenticacao.
  • 403 (FORBIDDEN, MISSING_PERMISSION, TENANT_FORBIDDEN, CROSS_TENANT_FORBIDDEN): usuario autenticado sem permissao/contexto, sem logout automatico.

Released under the MIT License.