Módulo Users

Gestão de usuários

CRUD administrativo via REST e GraphQL, persistência dual-ready e autorização com o enum Role.

Visão geral

O módulo users gerencia o ciclo de vida administrativo dos usuários. Registro público, verificação de e-mail e reset de senha ficam no módulo Auth.

Persistência

  • • Entity TypeORM (PostgreSQL) — store ativo usado pelo UsersService
  • • Schema Mongoose (MongoDB) — dual-ready; repositório registrado mas não injetado no service
  • • Cache com invalidação nos padrões typeorm:users:user:* / mongoose:users:user:* em escritas

Superfícies

  • • REST sob o prefixo da API /users — JWT + roles exigidas pela rota
  • • GraphQL — mesmas operações, JWT + roles exigidas pela operação
  • • Sem endpoints @Public() neste módulo

Enum Role

O campo roles é opcional. Quando informado, cada valor deve ser um membro do enum Role. Personalize o enum em src/modules/auth/enums/role.enum.ts conforme o seu projeto.

Valores do enum Role

Estes são os valores definidos em src/modules/auth/enums/role.enum.ts. Para novos papéis, estenda o enum — não use strings livres.

super

Super Administrador - Acesso total ao sistema

admin

Administrador - Gestão de usuários e recursos

manager

Gerente - Gestão de recursos específicos

user

Usuário - Acesso às funcionalidades básicas

TypeScriptrole.enum.ts
export enum Role {
  SUPER = 'super',
  ADMIN = 'admin',
  MANAGER = 'manager',
  USER = 'user',
}

Autorização

REST e GraphQL exigem JWT válido. Proteja as operações com @Roles(...) usando os membros do seu enum Role. O RolesGuard e o JwtAuthGuard resolvem o request em HTTP e GraphQL.

  • • REST: @UseGuards(JwtAuthGuard, RolesGuard) + @Roles(Role.YOUR_ROLE) em cada rota
  • • GraphQL: guards no resolver + @Roles(Role.YOUR_ROLE) em queries e mutations

Modelo de dados

Campos principais do usuário (interface IUser / entity / schema):

  • • id — UUID
  • • username — único
  • • firstName, lastName
  • • email — único
  • • password — hash Argon2id (não exposto no GraphQL)
  • • isActive — default true (registro Auth cria inativo)
  • • roles — Role[] (Postgres default []; Mongo default conforme o enum do projeto)
  • • passwordResetToken / passwordResetExpires
  • • emailVerificationToken / emailVerificationExpires

DTOs

CreateUserDto

Campos obrigatórios: firstName, lastName, username, email, password (@StrongPassword). Opcionais: isActive, roles (Role[]).

UpdateUserDto

Todos os campos opcionais. roles valida @IsEnum(Role, { each: true }). Tokens de verificação de e-mail existem no DTO mas não são fields GraphQL.

Senha forte

@StrongPassword exige maiúscula, minúscula, dígito, caractere especial e bloqueia sequências óbvias (ex.: abc, 123).

JSONCreateUserDto
{
  "firstName": "Jane",
  "lastName": "Doe",
  "username": "janedoe",
  "email": "[email protected]",
  "password": "Str0ng!Pass",  Senha forte obrigatória
  "isActive": true,
  "roles": ["admin", "manager"]  roles opcional — só valores do enum Role
}

API REST

Prefixo global da API: use o Bearer JWT de um usuário que possua as roles exigidas pelas rotas.

Criar usuário

Cria usuário. Conflito (409) se email ou username já existirem.

HTTP RequestPOST
POST /api/v1/users
Content-Type: application/json
Authorization: Bearer <access_token>

{
  "firstName": "Jane",
  "lastName": "Doe",
  "username": "janedoe",
  "email": "[email protected]",
  "password": "Str0ng!Pass",
  "roles": ["admin"]
}

Listar usuários

Retorna todos os usuários.

HTTP RequestGET
GET /api/v1/users
Authorization: Bearer <access_token>

Buscar por ID

Retorna um usuário pelo UUID.

HTTP RequestGET :id
GET /api/v1/users/:id
Authorization: Bearer <access_token>

Atualizar

Atualização parcial. Re-hash de senha se enviada e ainda não for Argon2.

HTTP RequestPATCH
PATCH /api/v1/users/:id
Content-Type: application/json
Authorization: Bearer <access_token>

{
  "isActive": false,
  "roles": ["user"]
}

Remover

Remove o usuário e retorna o snapshot.

HTTP RequestDELETE
DELETE /api/v1/users/:id
Authorization: Bearer <access_token>

GraphQL

Operações no path GraphQL da aplicação. Envie Authorization: Bearer <token>. O schema expõe o enum Role. Campos retornados: id, username, firstName, lastName, email, isActive, roles (password não é exposto).

Queries

users — listar todos

GraphQLquery users
query {
  users {
    id
    username
    firstName
    lastName
    email
    isActive
    roles
  }
}

user — buscar por ID

GraphQLquery user
query {
  user(id: "00000000-0000-0000-0000-000000000001") {
    id
    username
    firstName
    lastName
    email
    isActive
    roles
  }
}

userByEmail — buscar por e-mail

GraphQLquery userByEmail
query {
  userByEmail(email: "[email protected]") {
    id
    username
    firstName
    lastName
    email
    isActive
    roles
  }
}

Mutations

createUser — criar usuário

GraphQLmutation createUser
mutation {
  createUser(userData: {
    firstName: "Jane"
    lastName: "Doe"
    username: "janedoe"
    email: "[email protected]"
    password: "Str0ng!Pass"
    isActive: true
    roles: [ADMIN, MANAGER]
  }) {
    id
    username
    firstName
    lastName
    email
    isActive
    roles
  }
}

updateUser — atualizar usuário

GraphQLmutation updateUser
mutation {
  updateUser(
    id: "00000000-0000-0000-0000-000000000001"
    userData: {
      isActive: false
      roles: [USER]
    }
  ) {
    id
    username
    email
    isActive
    roles
  }
}

removeUser — remover usuário

GraphQLmutation removeUser
mutation {
  removeUser(id: "00000000-0000-0000-0000-000000000001") {
    id
    username
    email
  }
}

Regras de negócio

  • • Email e username únicos (ConflictException)
  • • Argon2id com ARGON2_*; não re-hash se o valor já for Argon2
  • • Helpers: updateRoles, addRole, removeRole, replaceRole (tipados com Role)
  • • Cache @EnableCache / @CacheTTL(1800) em create, findAll, update, remove; @NoCache em finders pontuais

Auth vs Users

Auth

  • • Registro público, verificação de e-mail, login, forgot/reset password
  • • Envia e-mails via EmailModule
  • • Cria usuário inativo com roles: []

Users

  • • CRUD administrativo (REST + GraphQL)
  • • Atribuição de roles do enum
  • • Não envia e-mail

Atenção

Password nas respostas

GET REST e GraphQL não expõem password. O hash só é carregado internamente no Auth quando necessário (login e troca de senha).

Personalizar roles

Ajuste o enum Role e os decorators @Roles(...) nas rotas/resolvers. Não envie strings fora do enum.

Explorar