diff --git a/package-lock.json b/package-lock.json index 9fbf918..44ae9a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -36,7 +36,7 @@ "passport-hubspot-oauth2": "^1.0.3", "passport-mailchimp": "^1.1.0", "protospack": "2.5.2", - "protospack-v2": "3.6.3", + "protospack-v2": "file:../protospack-v2/protospack-v2-0.0.0.tgz", "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", "rxjs": "^7.5.5", @@ -9015,9 +9015,10 @@ } }, "node_modules/protospack-v2": { - "version": "3.6.3", - "resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/protospack-v2/-/protospack-v2-3.6.3.tgz", - "integrity": "sha512-eGkVCzWs35jWdr3thF/V8d04gaDzO8LfiRpIQZTahW+vGNAMSs/zmVnXpxsSOmabkHJHvtbqHMydt30KpE5hGQ==", + "version": "0.0.0", + "resolved": "file:../protospack-v2/protospack-v2-0.0.0.tgz", + "integrity": "sha512-DEWNteY3ztkho0UH1UtuMmkDyFxSYktgvU+zD5JIgzBr8alQCJ3KfwHWaO0lwC7j+xsniscfv6QsIu6TE51f9g==", + "license": "ISC", "dependencies": { "@grpc/grpc-js": "^1.6.7", "rxjs": "^7.5.5", @@ -17245,9 +17246,8 @@ } }, "protospack-v2": { - "version": "3.6.3", - "resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/protospack-v2/-/protospack-v2-3.6.3.tgz", - "integrity": "sha512-eGkVCzWs35jWdr3thF/V8d04gaDzO8LfiRpIQZTahW+vGNAMSs/zmVnXpxsSOmabkHJHvtbqHMydt30KpE5hGQ==", + "version": "file:../protospack-v2/protospack-v2-0.0.0.tgz", + "integrity": "sha512-DEWNteY3ztkho0UH1UtuMmkDyFxSYktgvU+zD5JIgzBr8alQCJ3KfwHWaO0lwC7j+xsniscfv6QsIu6TE51f9g==", "requires": { "@grpc/grpc-js": "^1.6.7", "rxjs": "^7.5.5", diff --git a/package.json b/package.json index 801720d..51f2316 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "passport-hubspot-oauth2": "^1.0.3", "passport-mailchimp": "^1.1.0", "protospack": "2.5.2", - "protospack-v2": "3.6.3", + "protospack-v2": "3.7.1", "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", "rxjs": "^7.5.5", diff --git a/src/authentication/permissions.enum.ts b/src/authentication/permissions.enum.ts index 3af7776..cc7d4be 100644 --- a/src/authentication/permissions.enum.ts +++ b/src/authentication/permissions.enum.ts @@ -1,13 +1,9 @@ import { Logger } from '@nestjs/common'; import assert from 'assert'; +import { LanguageEnum } from 'src/utils/languages.enum'; const logger = new Logger(); -export enum LanguageEnum { - ptbr = 'pt-br', - enus = 'en-us', -} - export enum PermissionUsages { PUBLIC = 'public', INTERNAL = 'internal', @@ -446,7 +442,6 @@ export const PERMISSIONS = { }, }, }; -export type PermissionsObject = typeof PERMISSIONS; // traverses the object searching for duplicate seqids or claims (executes at runtime) let nextAvailableSeqid = 0; diff --git a/src/modules/permissions/permissions.controller.ts b/src/modules/permissions/permissions.controller.ts index 83c71eb..4b32ec0 100644 --- a/src/modules/permissions/permissions.controller.ts +++ b/src/modules/permissions/permissions.controller.ts @@ -6,11 +6,11 @@ import { RequireAllPermissions, } from 'src/authentication/authentication.decorator'; import { - LanguageEnum, PERMISSIONS, PermissionUsages, } from 'src/authentication/permissions.enum'; import { RequestUser, User } from 'src/authentication/user.decorator'; +import { LanguageEnum } from 'src/utils/languages.enum'; import { GetPublicPermissionsRes } from './dto/entities'; import { PermissionsService } from './permissions.service'; @@ -39,7 +39,7 @@ export class PermissionsController { @RequireAllPermissions(PERMISSIONS.USERS.permissions.ADMIN) getPublicPermissions( @User() user: RequestUser, - @Headers('dadosfera-lang') language: LanguageEnum, + @Headers('dadosfera-lang') language, ) { this.logger.info('getPublicPermissions', { user }); const permissionGroups = this.permissionsService.getPermissionsGrouped( diff --git a/src/modules/permissions/permissions.service.ts b/src/modules/permissions/permissions.service.ts index 1344299..ed8f5e6 100644 --- a/src/modules/permissions/permissions.service.ts +++ b/src/modules/permissions/permissions.service.ts @@ -16,10 +16,10 @@ import { PermissionUsages, PermissionsObjectGroup, PermissionsObjectPermissionTranslated, - LanguageEnum, } from '../../authentication/permissions.enum'; import ErrorBuilder from '../../utils/ErrorBuilder'; import { PermissionGroupPermission, PermissionGroup } from './dto/entities'; +import { LanguageEnum } from 'src/utils/languages.enum'; @Injectable() export class PermissionsService diff --git a/src/modules/roles/roles.controller.ts b/src/modules/roles/roles.controller.ts index 651ea0d..a8f6562 100644 --- a/src/modules/roles/roles.controller.ts +++ b/src/modules/roles/roles.controller.ts @@ -39,11 +39,12 @@ import { SetRoleUsersReq, } from './dto/entities'; import { GrpcToHttpExceptionFilter } from 'src/error/grpc-to-http-exception.filter'; -import { LanguageEnum, PERMISSIONS } from 'src/authentication/permissions.enum'; +import { PERMISSIONS } from 'src/authentication/permissions.enum'; import { Authenticated, RequireAllPermissions, } from 'src/authentication/authentication.decorator'; +import { LanguageEnum } from 'src/utils/languages.enum'; @ApiTags('Roles') @ApiHeader({ diff --git a/src/modules/roles/roles.service.ts b/src/modules/roles/roles.service.ts index 6925715..6d204e7 100644 --- a/src/modules/roles/roles.service.ts +++ b/src/modules/roles/roles.service.ts @@ -15,8 +15,8 @@ import { DadosferaLogger } from 'dadosfera-logs'; import { ClientGrpc } from '@nestjs/microservices'; import { lastValueFrom } from 'rxjs'; import { PermissionsService } from '../permissions/permissions.service'; -import { LanguageEnum } from 'src/authentication/permissions.enum'; -import { Role, UserRole } from 'protospack-v2/dist/lib/Duc/interfaces/entities'; +import { UserRole } from 'protospack-v2/dist/lib/Duc/interfaces/entities'; +import { LanguageEnum } from 'src/utils/languages.enum'; @Injectable() export class RolesService { @@ -32,6 +32,7 @@ export class RolesService { this.logger = dadosferaLogger.logger; } setLanguage(lang: LanguageEnum = LanguageEnum.ptbr) { + if (Object.values(LanguageEnum).includes(lang)) this.language = lang; this.language = lang; } diff --git a/src/modules/users/dtos/entities.ts b/src/modules/users/dtos/entities.ts index 2d778bc..2490fa9 100644 --- a/src/modules/users/dtos/entities.ts +++ b/src/modules/users/dtos/entities.ts @@ -1,8 +1,9 @@ import { ApiProperty, ApiPropertyOptional, OmitType } from '@nestjs/swagger'; import { UserRole } from 'src/modules/roles/dto/entities'; + export class Hierarchy { @ApiProperty() - id: number; + id: string; @ApiProperty() name: string; } @@ -68,7 +69,7 @@ export class CreateUserReq { @ApiPropertyOptional() department?: string; @ApiPropertyOptional() - hierarchy?: number; + hierarchy?: string; } export class CreateUserRes { @ApiProperty() @@ -93,7 +94,7 @@ export class UpdateUserReq { @ApiPropertyOptional() department?: string; @ApiPropertyOptional() - hierarchy?: number; + hierarchy?: string; @ApiPropertyOptional() roleNames?: string[]; } diff --git a/src/modules/users/hierarchies.ts b/src/modules/users/hierarchies.ts new file mode 100644 index 0000000..9f942dd --- /dev/null +++ b/src/modules/users/hierarchies.ts @@ -0,0 +1,79 @@ +import { LanguageEnum } from 'src/utils/languages.enum'; + +interface InternalHierarchyType { + name: Record; +} +export const HIERARCHIES: Record = { + presidence: { + name: { + 'pt-br': 'Presidência', + 'en-us': 'Presidence', + }, + }, + directory: { + name: { + 'pt-br': 'Diretoria', + 'en-us': 'Directory', + }, + }, + management: { + name: { + 'pt-br': 'Gerência', + 'en-us': 'Management', + }, + }, + specialist: { + name: { + 'pt-br': 'Especialista', + 'en-us': 'Specialist', + }, + }, + supervisor: { + name: { + 'pt-br': 'Coordenador ou Supervisor', + 'en-us': 'Supervisor', + }, + }, + trainee: { + name: { + 'pt-br': 'Trainee', + 'en-us': 'Trainee', + }, + }, + 'senior-analyst': { + name: { + 'pt-br': 'Analista Sênior', + 'en-us': 'Senior Analyst', + }, + }, + 'midlevel-analyst': { + name: { + 'pt-br': 'Analista Pleno', + 'en-us': 'Mid-level Analyst', + }, + }, + 'junior-analyst': { + name: { + 'pt-br': 'Analista Júnior', + 'en-us': 'Junior Analyst', + }, + }, + intern: { + name: { + 'pt-br': 'Estagiário', + 'en-us': 'Intern', + }, + }, + 'youth-apprentice': { + name: { + 'pt-br': 'Jovem aprendiz', + 'en-us': 'Youth Apprentice', + }, + }, + other: { + name: { + 'pt-br': 'Outro', + 'en-us': 'Other', + }, + }, +}; diff --git a/src/modules/users/users.controller.ts b/src/modules/users/users.controller.ts index 3365fc9..f34a82b 100644 --- a/src/modules/users/users.controller.ts +++ b/src/modules/users/users.controller.ts @@ -3,6 +3,7 @@ import { Controller, Delete, Get, + Headers, Inject, Param, Patch, @@ -11,12 +12,18 @@ import { Req, UseFilters, } from '@nestjs/common'; -import { ApiCreatedResponse, ApiOkResponse, ApiTags } from '@nestjs/swagger'; +import { + ApiCreatedResponse, + ApiHeader, + ApiOkResponse, + ApiTags, +} from '@nestjs/swagger'; import { DadosferaLogger } from 'dadosfera-logs'; import { RequireAllPermissions } from 'src/authentication/authentication.decorator'; import { PERMISSIONS } from 'src/authentication/permissions.enum'; import { RequestUser, User } from 'src/authentication/user.decorator'; import { GrpcToHttpExceptionFilter } from 'src/error/grpc-to-http-exception.filter'; +import { LanguageEnum } from 'src/utils/languages.enum'; import { AssignRoleToUserReq, BatchCreateUserReq, @@ -38,6 +45,12 @@ import { UsersService } from './users.service'; // TODO GET de hierarquias e do PATCH em usuário @ApiTags('Users') @Controller('users') +@ApiHeader({ + name: 'dadosfera-lang', + enum: LanguageEnum, + required: false, + description: 'Defaults to pt-br', +}) @UseFilters(GrpcToHttpExceptionFilter) export class UsersController { logger: any; @@ -56,16 +69,24 @@ export class UsersController { type: GetAllUsersByCustomerIdRes, description: 'List of users of a customer', }) - async getAllUsersByCustomerId(@User() user: RequestUser) { + async getAllUsersByCustomerId( + @User() user: RequestUser, + @Headers('dadosfera-lang') language, + ) { this.logger.info('getAllUsersByCustomerId', { user }); + this.userService.setLanguage(language); return await this.userService.findAllUsersByCustomerId(user.customer_id); } @Get('hierarchies') @RequireAllPermissions(PERMISSIONS.USERS.permissions.ADMIN) @ApiOkResponse({ type: GetAllHierarchiesRes }) - async getAllHierarchies(@User() user: RequestUser) { + async getAllHierarchies( + @User() user: RequestUser, + @Headers('dadosfera-lang') language, + ) { this.logger.info('getAllHierarchies', { user }); + this.userService.setLanguage(language); return await this.userService.getAllHierarchies(); } @@ -74,16 +95,26 @@ export class UsersController { @ApiOkResponse({ type: UserByCustomer, }) - async findOneById(@User() user: RequestUser, @Param('id') id: string) { + async findOneById( + @User() user: RequestUser, + @Param('id') id: string, + @Headers('dadosfera-lang') language, + ) { this.logger.info('findOneById', { user }); + this.userService.setLanguage(language); return await this.userService.findOneById(id); } @Post() @RequireAllPermissions(PERMISSIONS.USERS.permissions.ADMIN) @ApiCreatedResponse({ type: CreateUserRes }) - async createUser(@User() user: RequestUser, @Body() body: CreateUserReq) { + async createUser( + @User() user: RequestUser, + @Body() body: CreateUserReq, + @Headers('dadosfera-lang') language, + ) { this.logger.info('createUser', { user }); + this.userService.setLanguage(language); return await this.userService.createUser(body); } @@ -93,24 +124,36 @@ export class UsersController { async batchCreateUser( @User() user: RequestUser, @Body() body: BatchCreateUserReq, + @Headers('dadosfera-lang') language, ) { this.logger.info('batchCreateUser', { user }); + this.userService.setLanguage(language); return await this.userService.batchCreateUser(body); } @Delete(':id') @RequireAllPermissions(PERMISSIONS.USERS.permissions.ADMIN) @ApiOkResponse({ type: DeleteUserRes }) - async deleteUser(@User() user: RequestUser, @Param('id') id: string) { + async deleteUser( + @User() user: RequestUser, + @Param('id') id: string, + @Headers('dadosfera-lang') language, + ) { this.logger.info('deleteUser', { user }); + this.userService.setLanguage(language); return await this.userService.deleteUser({ id }); } @Patch('roles') @RequireAllPermissions(PERMISSIONS.USERS.permissions.ADMIN) @ApiOkResponse({ type: SetUserRolesRes }) - async setUserRoles(@User() user: RequestUser, @Body() body: SetUserRolesReq) { + async setUserRoles( + @User() user: RequestUser, + @Body() body: SetUserRolesReq, + @Headers('dadosfera-lang') language, + ) { this.logger.info('createUser', { user }); + this.userService.setLanguage(language); return await this.userService.setRoles(body, user.customer_id); } @@ -119,8 +162,10 @@ export class UsersController { async assignRoleToUser( @User() user: RequestUser, @Body() body: AssignRoleToUserReq, + @Headers('dadosfera-lang') language, ) { this.logger.info('assignRoleToUser', { user }); + this.userService.setLanguage(language); return await this.userService.assignRoleToUser(body); } @@ -129,8 +174,10 @@ export class UsersController { async unassignRoleToUser( @User() user: RequestUser, @Req() request: UnassignRoleToUserReq, + @Headers('dadosfera-lang') language, ) { this.logger.info('unassignRoleToUser', { user }); + this.userService.setLanguage(language); return await this.userService.unassignRoleToUser(request); } @@ -141,8 +188,10 @@ export class UsersController { @User() user: RequestUser, @Body() body: UpdateUserReq, @Param('id') id: string, + @Headers('dadosfera-lang') language, ) { this.logger.info('updateUser', { user }); + this.userService.setLanguage(language); return await this.userService.updateUser(body, id, user.customer_id); } } diff --git a/src/modules/users/users.service.ts b/src/modules/users/users.service.ts index eb8600a..c6f71a3 100644 --- a/src/modules/users/users.service.ts +++ b/src/modules/users/users.service.ts @@ -14,14 +14,20 @@ import { lastValueFrom } from 'rxjs'; import { BatchCreateUserReq, CreateUserReq, + Hierarchy, SetUserRolesReq, UpdateUserReq, + User, } from './dtos/entities'; import { RolesService } from '../roles/roles.service'; +import { HIERARCHIES } from './hierarchies'; +import { LanguageEnum } from 'src/utils/languages.enum'; +import { UserByCustomer } from 'protospack-v2/dist/lib/Duc/interfaces/entities'; @Injectable() export class UsersService implements OnModuleInit { logger: any; + language: LanguageEnum = LanguageEnum.ptbr; private usersClientService: UsersProtoService; constructor( @@ -39,14 +45,16 @@ export class UsersService implements OnModuleInit { ); } + setLanguage(l: LanguageEnum = LanguageEnum.ptbr) { + if (Object.values(LanguageEnum).includes(l)) this.language = l; + this.rolesService.setLanguage(l); + } + async findAllUsersByCustomerId(customerId: string) { const { users } = await lastValueFrom( this.usersClientService.UserFindAllByCustomerId({ customerId }), ); - users?.forEach((u) => { - const roles: any[] = this.rolesService.getRolesPermissionsName(u.roles); - u.roles = roles; - }); + this.adjustUsersPayload(users); return { users }; } @@ -54,12 +62,7 @@ export class UsersService implements OnModuleInit { const { user } = await lastValueFrom( this.usersClientService.UserFindOneById({ id }), ); - if (user) { - const roles: any[] = this.rolesService.getRolesPermissionsName( - user.roles, - ); - user.roles = roles; - } + this.adjustUsersPayload([user]); return { user }; } @@ -76,12 +79,7 @@ export class UsersService implements OnModuleInit { roleNames, }), ); - if (user) { - const roles: any[] = this.rolesService.getRolesPermissionsName( - user.roles, - ); - user.roles = roles; - } + this.adjustUsersPayload([user]); return { user }; } @@ -100,12 +98,7 @@ export class UsersService implements OnModuleInit { jobTitle, }), ); - if (user) { - const roles: any[] = this.rolesService.getRolesPermissionsName( - user.roles, - ); - user.roles = roles; - } + this.adjustUsersPayload([user]); return { user }; } @@ -121,31 +114,27 @@ export class UsersService implements OnModuleInit { customerId, }), ); - if (user) { - const roles: any[] = this.rolesService.getRolesPermissionsName( - user.roles, - ); - user.roles = roles; - } + this.adjustUsersPayload([user]); return { user }; } async batchCreateUser({ users }: BatchCreateUserReq) { - const usersToCreate: UserCreateRequest[] = users.map((u) => ({ - ...u, - roleIds: [], - roleNames: u.roleNames, - name: u.name || '', - hierarchy: u.hierarchy || null, - })); + const usersToCreate: UserCreateRequest[] = users.map( + ({ roleNames, email, department, hierarchy, jobTitle, name }) => ({ + roleNames, + email, + department, + hierarchy, + jobTitle, + name, + roleIds: [], + }), + ); const { errorUsers, usersCreated } = await lastValueFrom( this.usersClientService.UserBatchCreate({ users: usersToCreate, }), ); - usersCreated?.forEach((u) => { - const roles: any[] = this.rolesService.getRolesPermissionsName(u.roles); - u.roles = roles; - }); + this.adjustUsersPayload(usersCreated); return { errorUsers, usersCreated }; } async assignRoleToUser(body: AssignRoleToUserRequest) { @@ -159,7 +148,22 @@ export class UsersService implements OnModuleInit { async deleteUser(id: IdRequest) { return lastValueFrom(this.usersClientService.UserRemove(id)); } - async getAllHierarchies() { - return lastValueFrom(this.usersClientService.UserFindAllHierarchies({})); + + getAllHierarchies(): Hierarchy[] { + return Object.keys(HIERARCHIES).map((key) => ({ + id: key, + name: HIERARCHIES[key]?.name[this.language] || key, + })); + } + + adjustUsersPayload(users: UserByCustomer[]) { + users?.forEach((u) => { + if (!u) return; + const roles: any[] = this.rolesService.getRolesPermissionsName(u.roles); + u.roles = roles; + u.hierarchy = + HIERARCHIES[u.hierarchy]?.name[this.language] || u.hierarchy; + }); + return users; } } diff --git a/src/utils/languages.enum.ts b/src/utils/languages.enum.ts new file mode 100644 index 0000000..1fb3bc1 --- /dev/null +++ b/src/utils/languages.enum.ts @@ -0,0 +1,4 @@ +export enum LanguageEnum { + ptbr = 'pt-br', + enus = 'en-us', +}