Skip to main content

Módulo User

src/app/modules/user/

Gestión de usuarios internos del CRM (agentes y administradores) y de su perfil (firma y avatar).

Modelo — User​

Colección users. El toJSON elimina siempre el campo password.

CampoTipoDescripción
_idObjectIdID de MongoDB
identifierstring (UUID)ID externo único (se genera con randomUUID)
tenantIdObjectId → TenantTenant al que pertenece
usernamestringNombre de usuario (sin índice único)
emailstringEmail único, en minúsculas
passwordstringHash bcrypt (10 rondas)
roleIdObjectId → RoleRol asignado
isActivebooleanSi puede iniciar sesión (por defecto true)
firstnamestringPrimer nombre
secondFirstnamestringSegundo nombre (por defecto vacío)
lastNamestringApellido paterno
secondLastNamestringApellido materno (por defecto vacío)
userTypestringadmin o agent (USER_TYPE)
externalIdstring | nullID en un sistema externo (indexado)
signaturestringFirma del agente (por defecto vacía)
avatarUrlstringURL pública del avatar
isPlatformAdminbooleanAdministrador de plataforma (por defecto false); lo usa PlatformAdminGuard
createdAt / updatedAtDateTimestamps automáticos

Endpoints​

Base: /api/v1/users. El controlador aplica @UseGuards(PermissionsGuard) y @Auth(), por lo que todas las rutas requieren sesión; las que declaran @RequirePermission exigen además el permiso indicado (ver Guards). Las rutas siguen el patrón CRUD_ROUTES (no REST puro).

MétodoRutaPermisoDescripción
GET/users/get-meSolo sesiónUsuario actual, permisos, feature flags y preferencias del tenant
PATCH/users/me/signatureSolo sesiónActualiza la firma del usuario actual
PATCH/users/me/avatarSolo sesiónSube el avatar del usuario actual (multipart, campo file)
POST/users/createUSER_CREATECrea un usuario en el tenant del solicitante
GET/users/get-allUSER_READLista usuarios; paginada si se envían page y limit
GET/users/get-one/:idUSER_READObtiene un usuario por identifier (UUID)
PATCH/users/update/:idUSER_UPDATEActualiza un usuario por _id
PATCH/users/toggle-active/:idUSER_UPDATEInvierte isActive
DELETE/users/remove/:idUSER_DELETEElimina físicamente el usuario

Detalles por endpoint​

  • get-me: devuelve el usuario sin password, más permissions (acrónimos resueltos por PermissionResolverService), featureFlags (scheduledMessagesEnabled) y tenantPreferences (language, timezone). Solo se exponen esos valores de TenantSettings, nunca el documento completo, porque este endpoint lo consume cualquier rol (ver Settings).
  • me/avatar: solo se acepta image/jpeg y hasta 2 MB (AVATAR_UPLOAD). La imagen se procesa con MediaProcessorService, se guarda como objeto público en avatars/{tenantId}/{userId} y la URL se guarda con un sufijo ?v=timestamp para invalidar caché.
  • get-all: sin page y limit devuelve todos los usuarios del tenant en data.results; con ambos devuelve data.results y data.meta { total, page, limit }.
  • get-one/:id: busca por identifier (UUID) y tenant, no por _id.
  • update/:id, toggle-active/:id, remove/:id: usan el _id de MongoDB filtrado por tenant; un id con formato inválido responde 404.

DTOs​

Validaciones de class-validator (ValidationPipe). "Opcional" indica @IsOptional().

Parámetros de ruta​

ParámetroTipoObligatorioValidaciónUsado en
idstringSíNinguna en el controlador. En update, toggle-active y remove el servicio exige un ObjectId válido (si no, 404)get-one/:id (UUID identifier), update/:id, toggle-active/:id, remove/:id (_id de MongoDB)

CreateUserDto (body de POST /users/create)​

CampoTipoObligatorioValidacionesDescripción
usernamestringSí@IsString, @MinLength(2), @MaxLength(50)Nombre de usuario
emailstringSí@IsEmailEmail (único globalmente)
passwordstringSí@IsString, @MinLength(8)Contraseña en texto plano; se guarda con bcrypt
roleIdstringSí@IsMongoId_id del rol
firstnamestringSí@IsString, @MinLength(1), @MaxLength(80)Primer nombre
secondFirstnamestringNo@IsString, @MaxLength(80)Segundo nombre
lastNamestringSí@IsString, @MinLength(1), @MaxLength(80)Apellido paterno
secondLastNamestringNo@IsString, @MaxLength(80)Apellido materno
userTypestringSí@IsIn: admin, agentTipo de usuario
isActivebooleanNo@IsBooleanPor defecto true (modelo)

tenantId no viaja en el body: el controlador lo toma del usuario autenticado.

UpdateUserDto (body de PATCH /users/update/:id)​

PartialType(CreateUserDto): mismos campos y validaciones, todos opcionales. Si se envía password, se vuelve a hashear.

QueryUserDto (query de GET /users/get-all)​

Combina PaginationDto y FilterUserDto con IntersectionType. Sin page y limit no hay paginación.

CampoTipoObligatorioValidacionesDescripción
pagenumberNo@IsInt, @Min(1), @Type(() => Number)Página
limitnumberNo@IsInt, @Min(1), @Type(() => Number)Tamaño de página
usernamestringNo@IsStringRegex insensible a mayúsculas
emailstringNo@IsStringRegex insensible a mayúsculas
firstnamestringNo@IsStringRegex insensible a mayúsculas
lastNamestringNo@IsStringRegex insensible a mayúsculas
userTypestringNo@IsStringIgualdad exacta
isActivebooleanNo@IsBoolean, @Transform: 'true' o true produce true; cualquier otro valor produce falseFiltro por estado

UpdateSignatureDto (body de PATCH /users/me/signature)​

CampoTipoObligatorioValidacionesDescripción
signaturestringSí@IsString, @MaxLength(1000)Firma del agente

Avatar (PATCH /users/me/avatar)​

No usa DTO: recibe multipart/form-data con el campo de archivo file (FileInterceptor, almacenamiento en memoria). El servicio valida image/jpeg y un tamaño máximo de 2 MB; si no se cumple responde 400.

Servicio​

UserService crea usuarios (rechaza con 409 si el email ya existe), hashea contraseñas con bcrypt, filtra siempre por tenant en actualización, borrado y toggle, y expone findFilterableAgents (campos _id, firstname, lastName, username) para filtros de otros módulos. hasOperationalTenant lo usa AuthGuard para rechazar sesiones de tenants inactivos.

Gotchas​

  • La unicidad de email es global (índice único sobre email), no por tenant.
  • get-one busca por identifier, mientras que update, toggle-active y remove usan _id.
  • remove es un borrado físico (findOneAndDelete).
  • password nunca se devuelve: toJSON lo elimina y get-me y las rutas de perfil lo quitan explícitamente.

Exports​

UserService y UserRepository se exportan para su uso en AuthGuard y ChatGateway.