From 5867be6b668460a6adbbcbd27f7f17dc1f1ecd8b Mon Sep 17 00:00:00 2001 From: YgorPereira Date: Thu, 23 Apr 2026 20:44:33 -0300 Subject: [PATCH 01/11] fix: adjust UserRoles enum in the shared modules and imports --- .gitignore | 7 ++++++- backend/src/modules/auth/auth.controller.ts | 2 +- backend/src/modules/auth/auth.service.ts | 2 +- backend/src/modules/auth/guards/roles.decorator.ts | 2 +- backend/src/modules/auth/guards/roles.guard.ts | 2 +- backend/src/modules/category/category.controller.ts | 2 +- .../modules/chat/application/chat.file-message.spec.ts | 2 +- .../src/modules/chat/application/chat.service.spec.ts | 2 +- backend/src/modules/chat/application/chat.service.ts | 2 +- backend/src/modules/company/company.controller.ts | 2 +- backend/src/modules/file/presentation/file.controller.ts | 2 +- backend/src/modules/shared/enums/user.enum.ts | 5 +++++ .../ticket/presentation/controllers/ticket.controller.ts | 9 +++++++-- .../src/modules/ticket/presentation/dtos/create.dto.ts | 3 ++- backend/src/modules/user/dtos/changeRoleUserDTO.ts | 2 +- backend/src/modules/user/dtos/createUserDTO.ts | 2 +- backend/src/modules/user/dtos/filterUserDTO.ts | 2 +- backend/src/modules/user/user.controller.ts | 2 +- backend/src/modules/user/user.interface.ts | 2 +- backend/src/modules/user/user.schema.ts | 9 ++------- backend/src/modules/user/user.service.spec.ts | 3 ++- backend/src/modules/user/user.service.ts | 3 ++- 22 files changed, 41 insertions(+), 28 deletions(-) create mode 100644 backend/src/modules/shared/enums/user.enum.ts diff --git a/.gitignore b/.gitignore index 5d4b8e9..a004445 100644 --- a/.gitignore +++ b/.gitignore @@ -54,4 +54,9 @@ temp/ # ====================== # Files local storage # ====================== -uploads/ \ No newline at end of file +uploads/ + +# ====================== +# AI fast generated models +# ====================== +backend/model.nlp diff --git a/backend/src/modules/auth/auth.controller.ts b/backend/src/modules/auth/auth.controller.ts index 50cb0f1..5c9fadb 100644 --- a/backend/src/modules/auth/auth.controller.ts +++ b/backend/src/modules/auth/auth.controller.ts @@ -14,7 +14,7 @@ import { } from '../user/dtos/createUserDTO'; import { UserDetails } from '../user/user.interface'; import { ExistingUserDTO } from '../user/dtos/existingUserDTO'; -import { UserRole } from '../user/user.schema'; +import { UserRole } from '../shared/enums/user.enum'; import { Roles } from './guards/roles.decorator'; import { JwtGuard } from './guards/jwt.guard'; import { RolesGuard } from './guards/roles.guard'; diff --git a/backend/src/modules/auth/auth.service.ts b/backend/src/modules/auth/auth.service.ts index 1bce57c..6abe860 100644 --- a/backend/src/modules/auth/auth.service.ts +++ b/backend/src/modules/auth/auth.service.ts @@ -10,7 +10,7 @@ import { CreateUserDTO } from '../user/dtos/createUserDTO'; import { UserDetails } from '../user/user.interface'; import { ExistingUserDTO } from '../user/dtos/existingUserDTO'; import { JwtService } from '@nestjs/jwt'; -import { UserRole } from '../user/user.schema'; +import { UserRole } from '../shared/enums/user.enum'; @Injectable() export class AuthService { diff --git a/backend/src/modules/auth/guards/roles.decorator.ts b/backend/src/modules/auth/guards/roles.decorator.ts index 4745a48..8f13696 100644 --- a/backend/src/modules/auth/guards/roles.decorator.ts +++ b/backend/src/modules/auth/guards/roles.decorator.ts @@ -1,5 +1,5 @@ import { SetMetadata } from '@nestjs/common'; -import { UserRole } from '../../user/user.schema'; +import { UserRole } from '../../shared/enums/user.enum'; export const ROLES_KEY = 'roles'; diff --git a/backend/src/modules/auth/guards/roles.guard.ts b/backend/src/modules/auth/guards/roles.guard.ts index 92f56a8..9537efb 100644 --- a/backend/src/modules/auth/guards/roles.guard.ts +++ b/backend/src/modules/auth/guards/roles.guard.ts @@ -7,7 +7,7 @@ import { import { Reflector } from '@nestjs/core'; import { ROLES_KEY } from './roles.decorator'; -import { UserRole } from '../../user/user.schema'; +import { UserRole } from '../../shared/enums/user.enum'; @Injectable() export class RolesGuard implements CanActivate { diff --git a/backend/src/modules/category/category.controller.ts b/backend/src/modules/category/category.controller.ts index 65d36f9..83e5663 100644 --- a/backend/src/modules/category/category.controller.ts +++ b/backend/src/modules/category/category.controller.ts @@ -13,7 +13,6 @@ import { CategoryDetails } from './category.interface'; import { Roles } from '../auth/guards/roles.decorator'; import { JwtGuard } from '../auth/guards/jwt.guard'; import { RolesGuard } from '../auth/guards/roles.guard'; -import { UserRole } from '../user/user.schema'; import { ApiBearerAuth, ApiBody, @@ -24,6 +23,7 @@ import { } from '@nestjs/swagger'; import { CreateCategoryDTO } from './dtos/createCategoryDTO'; import { UpdateCategoryDTO } from './dtos/updateCategoryDTO'; +import { UserRole } from '../shared/enums/user.enum'; @ApiTags('Category') @ApiBearerAuth() diff --git a/backend/src/modules/chat/application/chat.file-message.spec.ts b/backend/src/modules/chat/application/chat.file-message.spec.ts index 96f2a64..55a5374 100644 --- a/backend/src/modules/chat/application/chat.file-message.spec.ts +++ b/backend/src/modules/chat/application/chat.file-message.spec.ts @@ -1,10 +1,10 @@ import { Test, TestingModule } from '@nestjs/testing'; import { ChatService } from './chat.service'; -import { UserRole } from '../../user/user.schema'; import { NotFoundException } from '@nestjs/common'; import type { IChatRepository } from '../domain/chat.repository'; import type { IMessageRepository } from '../../Messages/domain/message.repository'; +import { UserRole } from '../../shared/enums/user.enum'; /* =========================== MOCKS diff --git a/backend/src/modules/chat/application/chat.service.spec.ts b/backend/src/modules/chat/application/chat.service.spec.ts index 90f6eb9..72ee0e1 100644 --- a/backend/src/modules/chat/application/chat.service.spec.ts +++ b/backend/src/modules/chat/application/chat.service.spec.ts @@ -4,7 +4,7 @@ import { ForbiddenException, NotFoundException } from '@nestjs/common'; import { ChatDetails, ChatStatus } from '../domain/chat.entity'; import { IChatRepository } from '../domain/chat.repository'; import { IMessageRepository } from '../../Messages/domain/message.repository'; -import { UserRole } from '../../user/user.schema'; +import { UserRole } from '../../shared/enums/user.enum'; const mockChatRepository: jest.Mocked = { create: jest.fn(), diff --git a/backend/src/modules/chat/application/chat.service.ts b/backend/src/modules/chat/application/chat.service.ts index c2f2a6f..70aea06 100644 --- a/backend/src/modules/chat/application/chat.service.ts +++ b/backend/src/modules/chat/application/chat.service.ts @@ -8,7 +8,7 @@ import type { IChatRepository } from '../domain/chat.repository'; import type { IMessageRepository } from '../../Messages/domain/message.repository'; import type { ChatDetails } from '../domain/chat.entity'; import { ChatStatus } from '../domain/chat.entity'; -import { UserRole } from '../../user/user.schema'; +import { UserRole } from '../../shared/enums/user.enum'; @Injectable() export class ChatService { diff --git a/backend/src/modules/company/company.controller.ts b/backend/src/modules/company/company.controller.ts index 72d9cac..40a251f 100644 --- a/backend/src/modules/company/company.controller.ts +++ b/backend/src/modules/company/company.controller.ts @@ -16,7 +16,6 @@ import { CompanyDetails } from './company.interface'; import { JwtGuard } from '../auth/guards/jwt.guard'; import { RolesGuard } from '../auth/guards/roles.guard'; import { Roles } from '../auth/guards/roles.decorator'; -import { UserRole } from '../user/user.schema'; import { ApiBearerAuth, ApiBody, @@ -25,6 +24,7 @@ import { ApiResponse, ApiTags, } from '@nestjs/swagger'; +import { UserRole } from '../shared/enums/user.enum'; @ApiTags('Company') @ApiBearerAuth() diff --git a/backend/src/modules/file/presentation/file.controller.ts b/backend/src/modules/file/presentation/file.controller.ts index 87f775d..6a39b7a 100644 --- a/backend/src/modules/file/presentation/file.controller.ts +++ b/backend/src/modules/file/presentation/file.controller.ts @@ -4,12 +4,12 @@ import { FileInterceptor } from '@nestjs/platform-express'; import { JwtGuard } from '../../auth/guards/jwt.guard'; import { RolesGuard } from '../../auth/guards/roles.guard'; import { Roles } from '../../auth/guards/roles.decorator'; -import { UserRole } from '../../user/user.schema'; import { FileService } from '../application/file.service'; import { UploadFileDTO } from './dtos/uploadFileDTO'; import { multerConfig } from '../config/multer.config'; import type { Express, Request } from 'express'; import { UploadChatFileParamsDTO } from './dtos/uploadChatFileParamsDTO'; +import { UserRole } from '../../shared/enums/user.enum'; @ApiTags('Files') @ApiBearerAuth() diff --git a/backend/src/modules/shared/enums/user.enum.ts b/backend/src/modules/shared/enums/user.enum.ts new file mode 100644 index 0000000..898d858 --- /dev/null +++ b/backend/src/modules/shared/enums/user.enum.ts @@ -0,0 +1,5 @@ +export enum UserRole { + CLIENT = 'client', + SUPPORT = 'support', + ADMIN = 'admin', +} diff --git a/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts b/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts index 8556567..1de5518 100644 --- a/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts +++ b/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts @@ -6,6 +6,7 @@ import { Param, Post, Put, + UseGuards, } from '@nestjs/common'; import { CreateTicketUseCase } from '../../application/useCases/create/create.usecase'; import { DeleteTicketUseCase } from '../../application/useCases/delete/delete.usecase'; @@ -22,11 +23,13 @@ import { ApiBody, ApiOperation, ApiParam, - ApiQuery, ApiResponse, ApiTags, } from '@nestjs/swagger'; -import { randomUUID } from 'crypto'; +import { JwtGuard } from '../../../auth/guards/jwt.guard'; +import { RolesGuard } from '../../../auth/guards/roles.guard'; +import { Roles } from '../../../auth/guards/roles.decorator'; +import { UserRole } from '../../../shared/enums/user.enum'; @ApiTags('Ticket') @Controller('tickets') @@ -44,6 +47,8 @@ export class TicketController { @Post() @ApiOperation({ summary: 'Cria um ticket' }) @ApiBody({ type: CreateTicketRequest }) + @UseGuards(JwtGuard, RolesGuard) + @Roles(UserRole.CLIENT) @ApiResponse({ status: 201, description: 'Ticket criado com sucesso.' }) async create(@Body() body: CreateTicketRequest) { const data = TicketMapper.toCreateInput(body); diff --git a/backend/src/modules/ticket/presentation/dtos/create.dto.ts b/backend/src/modules/ticket/presentation/dtos/create.dto.ts index 24f4eca..75fdf46 100644 --- a/backend/src/modules/ticket/presentation/dtos/create.dto.ts +++ b/backend/src/modules/ticket/presentation/dtos/create.dto.ts @@ -1,4 +1,4 @@ -import { IsNotEmpty, IsString } from 'class-validator'; +import { IsNotEmpty, IsString, IsUUID } from 'class-validator'; import { ApiProperty } from '@nestjs/swagger'; export class CreateTicketRequest { @@ -16,5 +16,6 @@ export class CreateTicketRequest { @ApiProperty({ example: 'uuid-do-cliente', description: 'ID do cliente' }) @IsString() @IsNotEmpty() + @IsUUID() clientId!: string; } diff --git a/backend/src/modules/user/dtos/changeRoleUserDTO.ts b/backend/src/modules/user/dtos/changeRoleUserDTO.ts index c21781b..3e9e751 100644 --- a/backend/src/modules/user/dtos/changeRoleUserDTO.ts +++ b/backend/src/modules/user/dtos/changeRoleUserDTO.ts @@ -1,6 +1,6 @@ import { IsEnum } from 'class-validator'; -import { UserRole } from '../user.schema'; import { ApiProperty } from '@nestjs/swagger'; +import { UserRole } from '../../shared/enums/user.enum'; export class ChangeRoleUserDTO { @ApiProperty({ enum: UserRole, example: UserRole.ADMIN }) diff --git a/backend/src/modules/user/dtos/createUserDTO.ts b/backend/src/modules/user/dtos/createUserDTO.ts index 2a7ab94..83e5fdc 100644 --- a/backend/src/modules/user/dtos/createUserDTO.ts +++ b/backend/src/modules/user/dtos/createUserDTO.ts @@ -7,8 +7,8 @@ import { IsArray, IsMongoId, } from 'class-validator'; -import { UserRole } from '../user.schema'; import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import { UserRole } from '../../shared/enums/user.enum'; export class CreateUserDTO { @ApiProperty({ example: 'Gabriel' }) diff --git a/backend/src/modules/user/dtos/filterUserDTO.ts b/backend/src/modules/user/dtos/filterUserDTO.ts index 4cb288a..2cdc11f 100644 --- a/backend/src/modules/user/dtos/filterUserDTO.ts +++ b/backend/src/modules/user/dtos/filterUserDTO.ts @@ -1,6 +1,6 @@ import { ApiPropertyOptional } from '@nestjs/swagger'; import { IsEnum, IsNumberString, IsOptional, IsString } from 'class-validator'; -import { UserRole } from '../user.schema'; +import { UserRole } from '../../shared/enums/user.enum'; export class FilterUserDTO { @ApiPropertyOptional({ example: 'Gabriel' }) diff --git a/backend/src/modules/user/user.controller.ts b/backend/src/modules/user/user.controller.ts index ef41972..0199ad9 100644 --- a/backend/src/modules/user/user.controller.ts +++ b/backend/src/modules/user/user.controller.ts @@ -16,7 +16,6 @@ import { FilterUserDTO } from './dtos/filterUserDTO'; import { Roles } from '../auth/guards/roles.decorator'; import { JwtGuard } from '../auth/guards/jwt.guard'; import { RolesGuard } from '../auth/guards/roles.guard'; -import { UserRole } from './user.schema'; import { ChangeRoleUserDTO } from './dtos/changeRoleUserDTO'; import { ChangeCategoriesUserDTO } from './dtos/changeCategoriesUserDTO'; import { @@ -28,6 +27,7 @@ import { ApiResponse, ApiTags, } from '@nestjs/swagger'; +import { UserRole } from '../shared/enums/user.enum'; @ApiTags('User') @ApiBearerAuth() diff --git a/backend/src/modules/user/user.interface.ts b/backend/src/modules/user/user.interface.ts index 774e0f2..e3bc56f 100644 --- a/backend/src/modules/user/user.interface.ts +++ b/backend/src/modules/user/user.interface.ts @@ -1,6 +1,6 @@ import { CategoryDetails } from '../category/category.interface'; import { CompanyDetails } from '../company/company.interface'; -import { UserRole } from './user.schema'; +import { UserRole } from '../shared/enums/user.enum'; export interface UserDetails { id: string; diff --git a/backend/src/modules/user/user.schema.ts b/backend/src/modules/user/user.schema.ts index eaf937b..601d675 100644 --- a/backend/src/modules/user/user.schema.ts +++ b/backend/src/modules/user/user.schema.ts @@ -2,15 +2,10 @@ import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; import { Document, Types } from 'mongoose'; import { Company } from '../company/company.schema'; import { Category } from '../category/category.schema'; +import { UserRole } from '../shared/enums/user.enum'; export type UserDocument = User & Document; -export enum UserRole { - CLIENT = 'client', - SUPPORT = 'support', - ADMIN = 'admin', -} - @Schema({ timestamps: { createdAt: true, updatedAt: false } }) export class User { @Prop({ required: true }) @@ -46,4 +41,4 @@ export class User { createdAt?: Date; } -export const UserSchema = SchemaFactory.createForClass(User); \ No newline at end of file +export const UserSchema = SchemaFactory.createForClass(User); diff --git a/backend/src/modules/user/user.service.spec.ts b/backend/src/modules/user/user.service.spec.ts index a96fa1e..5abc6a7 100644 --- a/backend/src/modules/user/user.service.spec.ts +++ b/backend/src/modules/user/user.service.spec.ts @@ -4,11 +4,12 @@ import { Connection, Types } from 'mongoose'; import { MongoMemoryServer } from 'mongodb-memory-server'; import { UserService } from './user.service'; -import { UserSchema, UserRole } from './user.schema'; +import { UserSchema } from './user.schema'; import { CompanyService } from '../company/company.service'; import { CategoryService } from '../category/category.service'; import { CompanySchema } from '../company/company.schema'; import { CategorySchema } from '../category/category.schema'; +import { UserRole } from '../shared/enums/user.enum'; describe('UserService (Integration)', () => { let service: UserService; diff --git a/backend/src/modules/user/user.service.ts b/backend/src/modules/user/user.service.ts index ab13383..3aacd96 100644 --- a/backend/src/modules/user/user.service.ts +++ b/backend/src/modules/user/user.service.ts @@ -5,10 +5,11 @@ import { } from '@nestjs/common'; import { InjectModel } from '@nestjs/mongoose'; import { Model } from 'mongoose'; -import { UserDocument, UserRole } from './user.schema'; +import { UserDocument } from './user.schema'; import { UserDetails } from './user.interface'; import { CompanyService } from '../company/company.service'; import { CategoryService } from '../category/category.service'; +import { UserRole } from '../shared/enums/user.enum'; @Injectable() export class UserService { From e72af5121d50f6c258eba81f50e08534818aae12 Mon Sep 17 00:00:00 2001 From: YgorPereira Date: Thu, 23 Apr 2026 20:58:12 -0300 Subject: [PATCH 02/11] feat: add role guard to ticket controller --- backend/model.nlp | 2 +- .../controllers/ticket.controller.spec.ts | 14 +++++++++----- .../presentation/controllers/ticket.controller.ts | 12 ++++++++++++ backend/src/modules/user/user.schema.ts | 1 + 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/backend/model.nlp b/backend/model.nlp index 9ba9f3c..04ecf73 100644 --- a/backend/model.nlp +++ b/backend/model.nlp @@ -1 +1 @@ -{"settings":{"languages":["pt"],"tag":"nlp","threshold":0.5,"autoLoad":true,"autoSave":true,"modelFileName":"model.nlp","executeActionsBeforeAnswers":false,"calculateSentiment":true},"nluManager":{"settings":{"tag":"nlu-manager"},"locales":["pt"],"languageNames":{},"domainManagers":{"pt":{"settings":{"locale":"pt","trainByDomain":false,"tag":"domain-manager-pt","nluByDomain":{"default":{"className":"NeuralNlu","settings":{}}},"useStemDict":true},"stemDict":{"acess,consig,nao,o,sit":{"intent":"web_app","domain":"default"},"a,carreg,nao,naveg,no,pagin":{"intent":"web_app","domain":"default"},"ao,erro,faz,login,no,sistem":{"intent":"web_app","domain":"default"},"abre,aplic,celul,nao,no,o":{"intent":"web_app","domain":"default"},"app,fech,sozinh":{"intent":"web_app","domain":"default"},"do,interfac,na,problem,sistem":{"intent":"web_app","domain":"default"},"a,ao,carreg,erro,inicial,pagin":{"intent":"web_app","domain":"default"},"consig,nao,naveg,no,sistem":{"intent":"web_app","domain":"default"},"a,acess,ao,aplicaca,falh,web":{"intent":"web_app","domain":"default"},"a,ao,api,consum,erro":{"intent":"web_app","domain":"default"},"ar,do,esta,for,o,sistem,web":{"intent":"web_app","domain":"default"},"a,abrir,ao,branc,em,fic,tel":{"intent":"web_app","domain":"default"},"consig,cont,entrar,na,nao":{"intent":"web_app","domain":"default"},"ao,boto,clic,do,nos,problem,sit":{"intent":"web_app","domain":"default"},"ao,app,inic,o,trav":{"intent":"web_app","domain":"default"},"a,artificial,errad,esta,inteligenc,respost,retorn":{"intent":"ai","domain":"default"},"corret,de,esta,funcion,ia,model,nao,o":{"intent":"ai","domain":"default"},"da,do,inesper,model,previsa,result":{"intent":"ai","domain":"default"},"de,erro,linguag,natural,no,process":{"intent":"ai","domain":"default"},"a,corret,intenca,model,nao,o,reconhec":{"intent":"ai","domain":"default"},"automat,classificaca,falh,na":{"intent":"ai","domain":"default"},"do,model,no,problem,treinament":{"intent":"ai","domain":"default"},"a,aprend,corret,esta,ia,nao":{"intent":"ai","domain":"default"},"artificial,da,incoerent,inteligenc,respost":{"intent":"ai","domain":"default"},"do,erro,inferenc,model,na":{"intent":"ai","domain":"default"},"algoritm,do,inconsistent,result":{"intent":"ai","domain":"default"},"com,de,learning,machin,model,o,problem":{"intent":"ai","domain":"default"},"a,esta,incorret,previsa":{"intent":"ai","domain":"default"},"analis,de,erro,ia,na,pel,text":{"intent":"ai","domain":"default"},"com,esper,model,nao,respond":{"intent":"ai","domain":"default"},"carreg,dashboard,esta,nao,o":{"intent":"bi","domain":"default"},"ao,erro,ger,relatori":{"intent":"bi","domain":"default"},"dad,do,esta,incorret,os,painel":{"intent":"bi","domain":"default"},"dos,grafic,na,problem,visualizaca":{"intent":"bi","domain":"default"},"atualiz,com,dad,nao,nov,relatori":{"intent":"bi","domain":"default"},"dashboard,errad,esta,indic,no":{"intent":"bi","domain":"default"},"ao,bi,carreg,de,falh,o,painel":{"intent":"bi","domain":"default"},"dad,inconsistent,no,relatori":{"intent":"bi","domain":"default"},"consig,grafic,nao,os,visualiz":{"intent":"bi","domain":"default"},"atualizaca,dad,dos,erro,na":{"intent":"bi","domain":"default"},"apresent,incorret,painel,valor":{"intent":"bi","domain":"default"},"consult,dad,de,na,problem":{"intent":"bi","domain":"default"},"dashboard,desatualiz,informaco,mostr":{"intent":"bi","domain":"default"},"acess,ao,erro,relatori":{"intent":"bi","domain":"default"},"dad,de,funcion,nao,visualizaca":{"intent":"bi","domain":"default"},"a,execut,nao,o,rob,taref":{"intent":"rpa","domain":"default"},"automaca,do,falh,na,process":{"intent":"rpa","domain":"default"},"bot,de,funcion,par":{"intent":"rpa","domain":"default"},"do,erro,execuca,na,rob":{"intent":"rpa","domain":"default"},"automatiz,inic,nao,process":{"intent":"rpa","domain":"default"},"automaca,durant,execuca,falh":{"intent":"rpa","domain":"default"},"bot,do,mei,no,o,process,trav":{"intent":"rpa","domain":"default"},"automatiz,erro,no,workflow":{"intent":"rpa","domain":"default"},"automat,conclu,foi,nao,taref":{"intent":"rpa","domain":"default"},"do,execuca,na,problem,script":{"intent":"rpa","domain":"default"},"a,ativ,complet,nao,rob":{"intent":"rpa","domain":"default"},"ao,automaca,falh,rod":{"intent":"rpa","domain":"default"},"automatiz,erro,job,no":{"intent":"rpa","domain":"default"},"bot,nao,respond":{"intent":"rpa","domain":"default"},"automaca,esta,funcion,nao":{"intent":"rpa","domain":"default"},"conect,disposit,na,nao,o,red":{"intent":"iot","domain":"default"},"dad,envi,esta,nao,sensor":{"intent":"iot","domain":"default"},"equip,esta,offlin":{"intent":"iot","domain":"default"},"com,comunicaca,disposit,falh,na,o":{"intent":"iot","domain":"default"},"aos,comand,disposit,nao,respond":{"intent":"iot","domain":"default"},"aparec,equip,nao,no,sistem":{"intent":"iot","domain":"default"},"com,disposit,falh,integraca,na,o":{"intent":"iot","domain":"default"},"de,funcion,par,sensor":{"intent":"iot","domain":"default"},"de,disposit,erro,na,red":{"intent":"iot","domain":"default"},"desconect,disposit,frequent":{"intent":"iot","domain":"default"},"cheg,dad,de,nao,telemetr":{"intent":"iot","domain":"default"},"a,conect,impressor,na,nao,red":{"intent":"iot","domain":"default"},"aos,comand,impressor,nao,respond":{"intent":"iot","domain":"default"},"ao,disposit,envi,erro,impressa,o,par":{"intent":"iot","domain":"default"},"a,esta,impressor,no,offlin,sistem":{"intent":"iot","domain":"default"},"consig,imprim,nao,pel,red":{"intent":"iot","domain":"default"},"barr,codig,de,funcion,leitor,nao,o":{"intent":"iot","domain":"default"},"dad,envi,esta,nao,scann":{"intent":"iot","domain":"default"},"cam,conect,de,nao,seguranc":{"intent":"iot","domain":"default"},"a,cam,com,comunicaca,falh,na":{"intent":"iot","domain":"default"},"acess,control,de,disposit,nao,o,respond":{"intent":"iot","domain":"default"},"catrac,eletron,esta,funcion,nao":{"intent":"iot","domain":"default"},"de,detect,moviment,nao,presenc,sensor":{"intent":"iot","domain":"default"},"dad,de,envi,nao,sensor,temperatur":{"intent":"iot","domain":"default"},"ao,conect,de,nao,pont,sistem,terminal":{"intent":"iot","domain":"default"},"de,esta,nao,o,pont,registr,relogi":{"intent":"iot","domain":"default"},"de,equip,esta,monitor,offlin":{"intent":"iot","domain":"default"},"com,conexa,disposit,falh,fisic,na,o":{"intent":"iot","domain":"default"},"aparec,hardwar,nao,no,o,sistem":{"intent":"iot","domain":"default"},"de,desconect,disposit,red,sozinh":{"intent":"iot","domain":"default"},"com,conect,equip,problem":{"intent":"iot","domain":"default"},"abre,nao,sit":{"intent":"web_app","domain":"default"},"erro,login,no":{"intent":"web_app","domain":"default"}},"intentDict":{"web_app":"default","ai":"default","bi":"default","rpa":"default","iot":"default"},"sentences":[{"domain":"default","utterance":"não consigo acessar o site","intent":"web_app"},{"domain":"default","utterance":"a página não carrega no navegador","intent":"web_app"},{"domain":"default","utterance":"erro ao fazer login no sistema","intent":"web_app"},{"domain":"default","utterance":"o aplicativo não abre no celular","intent":"web_app"},{"domain":"default","utterance":"app fecha sozinho","intent":"web_app"},{"domain":"default","utterance":"problema na interface do sistema","intent":"web_app"},{"domain":"default","utterance":"erro ao carregar a página inicial","intent":"web_app"},{"domain":"default","utterance":"não consigo navegar no sistema","intent":"web_app"},{"domain":"default","utterance":"falha ao acessar a aplicação web","intent":"web_app"},{"domain":"default","utterance":"erro ao consumir a api","intent":"web_app"},{"domain":"default","utterance":"o sistema web está fora do ar","intent":"web_app"},{"domain":"default","utterance":"a tela fica em branco ao abrir","intent":"web_app"},{"domain":"default","utterance":"não consigo entrar na conta","intent":"web_app"},{"domain":"default","utterance":"problema ao clicar nos botões do site","intent":"web_app"},{"domain":"default","utterance":"o app trava ao iniciar","intent":"web_app"},{"domain":"default","utterance":"a inteligência artificial está retornando respostas erradas","intent":"ai"},{"domain":"default","utterance":"o modelo de ia não está funcionando corretamente","intent":"ai"},{"domain":"default","utterance":"resultado inesperado da previsão do modelo","intent":"ai"},{"domain":"default","utterance":"erro no processamento de linguagem natural","intent":"ai"},{"domain":"default","utterance":"o modelo não reconhece a intenção corretamente","intent":"ai"},{"domain":"default","utterance":"falha na classificação automática","intent":"ai"},{"domain":"default","utterance":"problema no treinamento do modelo","intent":"ai"},{"domain":"default","utterance":"a ia não está aprendendo corretamente","intent":"ai"},{"domain":"default","utterance":"resposta incoerente da inteligência artificial","intent":"ai"},{"domain":"default","utterance":"erro na inferência do modelo","intent":"ai"},{"domain":"default","utterance":"resultado inconsistente do algoritmo","intent":"ai"},{"domain":"default","utterance":"problema com o modelo de machine learning","intent":"ai"},{"domain":"default","utterance":"a previsão está incorreta","intent":"ai"},{"domain":"default","utterance":"erro na análise de texto pela ia","intent":"ai"},{"domain":"default","utterance":"modelo não responde como esperado","intent":"ai"},{"domain":"default","utterance":"o dashboard não está carregando","intent":"bi"},{"domain":"default","utterance":"erro ao gerar relatório","intent":"bi"},{"domain":"default","utterance":"os dados do painel estão incorretos","intent":"bi"},{"domain":"default","utterance":"problema na visualização dos gráficos","intent":"bi"},{"domain":"default","utterance":"relatório não atualiza com dados novos","intent":"bi"},{"domain":"default","utterance":"indicadores estão errados no dashboard","intent":"bi"},{"domain":"default","utterance":"falha ao carregar o painel de BI","intent":"bi"},{"domain":"default","utterance":"dados inconsistentes no relatório","intent":"bi"},{"domain":"default","utterance":"não consigo visualizar os gráficos","intent":"bi"},{"domain":"default","utterance":"erro na atualização dos dados","intent":"bi"},{"domain":"default","utterance":"painel apresenta valores incorretos","intent":"bi"},{"domain":"default","utterance":"problema na consulta de dados","intent":"bi"},{"domain":"default","utterance":"dashboard mostra informações desatualizadas","intent":"bi"},{"domain":"default","utterance":"erro ao acessar relatórios","intent":"bi"},{"domain":"default","utterance":"visualização de dados não funciona","intent":"bi"},{"domain":"default","utterance":"o robô não executou a tarefa","intent":"rpa"},{"domain":"default","utterance":"falha na automação do processo","intent":"rpa"},{"domain":"default","utterance":"bot parou de funcionar","intent":"rpa"},{"domain":"default","utterance":"erro na execução do robô","intent":"rpa"},{"domain":"default","utterance":"processo automatizado não iniciou","intent":"rpa"},{"domain":"default","utterance":"automação falhou durante execução","intent":"rpa"},{"domain":"default","utterance":"o bot travou no meio do processo","intent":"rpa"},{"domain":"default","utterance":"erro no workflow automatizado","intent":"rpa"},{"domain":"default","utterance":"tarefa automática não foi concluída","intent":"rpa"},{"domain":"default","utterance":"problema na execução do script","intent":"rpa"},{"domain":"default","utterance":"robô não completou a atividade","intent":"rpa"},{"domain":"default","utterance":"falha ao rodar automação","intent":"rpa"},{"domain":"default","utterance":"erro no job automatizado","intent":"rpa"},{"domain":"default","utterance":"bot não responde","intent":"rpa"},{"domain":"default","utterance":"automação não está funcionando","intent":"rpa"},{"domain":"default","utterance":"o dispositivo não conecta na rede","intent":"iot"},{"domain":"default","utterance":"sensor não está enviando dados","intent":"iot"},{"domain":"default","utterance":"equipamento está offline","intent":"iot"},{"domain":"default","utterance":"falha na comunicação com o dispositivo","intent":"iot"},{"domain":"default","utterance":"dispositivo não responde aos comandos","intent":"iot"},{"domain":"default","utterance":"equipamento não aparece no sistema","intent":"iot"},{"domain":"default","utterance":"falha na integração com o dispositivo","intent":"iot"},{"domain":"default","utterance":"sensor parou de funcionar","intent":"iot"},{"domain":"default","utterance":"erro na rede de dispositivos","intent":"iot"},{"domain":"default","utterance":"dispositivo desconectando frequentemente","intent":"iot"},{"domain":"default","utterance":"dados de telemetria não chegam","intent":"iot"},{"domain":"default","utterance":"a impressora não conecta na rede","intent":"iot"},{"domain":"default","utterance":"impressora não responde aos comandos","intent":"iot"},{"domain":"default","utterance":"erro ao enviar impressão para o dispositivo","intent":"iot"},{"domain":"default","utterance":"a impressora está offline no sistema","intent":"iot"},{"domain":"default","utterance":"não consigo imprimir pela rede","intent":"iot"},{"domain":"default","utterance":"o leitor de código de barras não funciona","intent":"iot"},{"domain":"default","utterance":"scanner não está enviando dados","intent":"iot"},{"domain":"default","utterance":"câmera de segurança não conecta","intent":"iot"},{"domain":"default","utterance":"falha na comunicação com a câmera","intent":"iot"},{"domain":"default","utterance":"o dispositivo de controle de acesso não responde","intent":"iot"},{"domain":"default","utterance":"catraca eletrônica não está funcionando","intent":"iot"},{"domain":"default","utterance":"sensor de presença não detecta movimento","intent":"iot"},{"domain":"default","utterance":"sensor de temperatura não envia dados","intent":"iot"},{"domain":"default","utterance":"terminal de ponto não conecta ao sistema","intent":"iot"},{"domain":"default","utterance":"o relógio de ponto não está registrando","intent":"iot"},{"domain":"default","utterance":"equipamento de monitoramento está offline","intent":"iot"},{"domain":"default","utterance":"falha na conexão com o dispositivo físico","intent":"iot"},{"domain":"default","utterance":"o hardware não aparece no sistema","intent":"iot"},{"domain":"default","utterance":"dispositivo de rede desconectando sozinho","intent":"iot"},{"domain":"default","utterance":"problema com equipamento conectado","intent":"iot"},{"domain":"default","utterance":"site não abre","intent":"web_app"},{"domain":"default","utterance":"erro no login","intent":"web_app"}],"domains":{"master_domain":{"settings":{"locale":"pt","tag":"nlu-pt","keepStopwords":true,"nonefeatureValue":1,"nonedeltaMultiplier":1.2,"spellCheck":false,"spellCheckDistance":1,"filterZeros":true,"log":true},"features":{"nao":1,"consig":1,"acess":1,"o":1,"sit":1,"a":1,"pagin":1,"carreg":1,"no":1,"naveg":1,"erro":1,"ao":1,"faz":1,"login":1,"sistem":1,"aplic":1,"abre":1,"celul":1,"app":1,"fech":1,"sozinh":1,"problem":1,"na":1,"interfac":1,"do":1,"inicial":1,"falh":1,"aplicaca":1,"web":1,"consum":1,"api":1,"esta":1,"for":1,"ar":1,"tel":1,"fic":1,"em":1,"branc":1,"abrir":1,"entrar":1,"cont":1,"clic":1,"nos":1,"boto":1,"trav":1,"inic":1,"inteligenc":1,"artificial":1,"retorn":1,"respost":1,"errad":1,"model":1,"de":1,"ia":1,"funcion":1,"corret":1,"result":1,"inesper":1,"da":1,"previsa":1,"process":1,"linguag":1,"natural":1,"reconhec":1,"intenca":1,"classificaca":1,"automat":1,"treinament":1,"aprend":1,"incoerent":1,"inferenc":1,"inconsistent":1,"algoritm":1,"com":1,"machin":1,"learning":1,"incorret":1,"analis":1,"text":1,"pel":1,"respond":1,"esper":1,"dashboard":1,"ger":1,"relatori":1,"os":1,"dad":1,"painel":1,"visualizaca":1,"dos":1,"grafic":1,"atualiz":1,"nov":1,"indic":1,"bi":1,"visualiz":1,"atualizaca":1,"apresent":1,"valor":1,"consult":1,"mostr":1,"informaco":1,"desatualiz":1,"rob":1,"execut":1,"taref":1,"automaca":1,"bot":1,"par":1,"execuca":1,"automatiz":1,"durant":1,"mei":1,"workflow":1,"foi":1,"conclu":1,"script":1,"complet":1,"ativ":1,"rod":1,"job":1,"disposit":1,"conect":1,"red":1,"sensor":1,"envi":1,"equip":1,"offlin":1,"comunicaca":1,"aos":1,"comand":1,"aparec":1,"integraca":1,"desconect":1,"frequent":1,"telemetr":1,"cheg":1,"impressor":1,"impressa":1,"imprim":1,"leitor":1,"codig":1,"barr":1,"scann":1,"cam":1,"seguranc":1,"control":1,"catrac":1,"eletron":1,"presenc":1,"detect":1,"moviment":1,"temperatur":1,"terminal":1,"pont":1,"relogi":1,"registr":1,"monitor":1,"conexa":1,"fisic":1,"hardwar":1},"intents":{"web_app":1,"ai":1,"bi":1,"rpa":1,"iot":1},"intentFeatures":{"web_app":{"nao":1,"consig":1,"acess":1,"o":1,"sit":1,"a":1,"pagin":1,"carreg":1,"no":1,"naveg":1,"erro":1,"ao":1,"faz":1,"login":1,"sistem":1,"aplic":1,"abre":1,"celul":1,"app":1,"fech":1,"sozinh":1,"problem":1,"na":1,"interfac":1,"do":1,"inicial":1,"falh":1,"aplicaca":1,"web":1,"consum":1,"api":1,"esta":1,"for":1,"ar":1,"tel":1,"fic":1,"em":1,"branc":1,"abrir":1,"entrar":1,"cont":1,"clic":1,"nos":1,"boto":1,"trav":1,"inic":1},"ai":{"a":1,"inteligenc":1,"artificial":1,"esta":1,"retorn":1,"respost":1,"errad":1,"o":1,"model":1,"de":1,"ia":1,"nao":1,"funcion":1,"corret":1,"result":1,"inesper":1,"da":1,"previsa":1,"do":1,"erro":1,"no":1,"process":1,"linguag":1,"natural":1,"reconhec":1,"intenca":1,"falh":1,"na":1,"classificaca":1,"automat":1,"problem":1,"treinament":1,"aprend":1,"incoerent":1,"inferenc":1,"inconsistent":1,"algoritm":1,"com":1,"machin":1,"learning":1,"incorret":1,"analis":1,"text":1,"pel":1,"respond":1,"esper":1},"bi":{"o":1,"dashboard":1,"nao":1,"esta":1,"carreg":1,"erro":1,"ao":1,"ger":1,"relatori":1,"os":1,"dad":1,"do":1,"painel":1,"incorret":1,"problem":1,"na":1,"visualizaca":1,"dos":1,"grafic":1,"atualiz":1,"com":1,"nov":1,"indic":1,"errad":1,"no":1,"falh":1,"de":1,"bi":1,"inconsistent":1,"consig":1,"visualiz":1,"atualizaca":1,"apresent":1,"valor":1,"consult":1,"mostr":1,"informaco":1,"desatualiz":1,"acess":1,"funcion":1},"rpa":{"o":1,"rob":1,"nao":1,"execut":1,"a":1,"taref":1,"falh":1,"na":1,"automaca":1,"do":1,"process":1,"bot":1,"par":1,"de":1,"funcion":1,"erro":1,"execuca":1,"automatiz":1,"inic":1,"durant":1,"trav":1,"no":1,"mei":1,"workflow":1,"automat":1,"foi":1,"conclu":1,"problem":1,"script":1,"complet":1,"ativ":1,"ao":1,"rod":1,"job":1,"respond":1,"esta":1},"iot":{"o":1,"disposit":1,"nao":1,"conect":1,"na":1,"red":1,"sensor":1,"esta":1,"envi":1,"dad":1,"equip":1,"offlin":1,"falh":1,"comunicaca":1,"com":1,"respond":1,"aos":1,"comand":1,"aparec":1,"no":1,"sistem":1,"integraca":1,"par":1,"de":1,"funcion":1,"erro":1,"desconect":1,"frequent":1,"telemetr":1,"cheg":1,"a":1,"impressor":1,"ao":1,"impressa":1,"consig":1,"imprim":1,"pel":1,"leitor":1,"codig":1,"barr":1,"scann":1,"cam":1,"seguranc":1,"control":1,"acess":1,"catrac":1,"eletron":1,"presenc":1,"detect":1,"moviment":1,"temperatur":1,"terminal":1,"pont":1,"relogi":1,"registr":1,"monitor":1,"conexa":1,"fisic":1,"hardwar":1,"sozinh":1,"problem":1}},"featuresToIntent":{"nao":["web_app","ai","bi","rpa","iot"],"consig":["web_app","bi","iot"],"acess":["web_app","bi","iot"],"o":["web_app","ai","bi","rpa","iot"],"sit":["web_app"],"a":["web_app","ai","rpa","iot"],"pagin":["web_app"],"carreg":["web_app","bi"],"no":["web_app","ai","bi","rpa","iot"],"naveg":["web_app"],"erro":["web_app","ai","bi","rpa","iot"],"ao":["web_app","bi","rpa","iot"],"faz":["web_app"],"login":["web_app"],"sistem":["web_app","iot"],"aplic":["web_app"],"abre":["web_app"],"celul":["web_app"],"app":["web_app"],"fech":["web_app"],"sozinh":["web_app","iot"],"problem":["web_app","ai","bi","rpa","iot"],"na":["web_app","ai","bi","rpa","iot"],"interfac":["web_app"],"do":["web_app","ai","bi","rpa"],"inicial":["web_app"],"falh":["web_app","ai","bi","rpa","iot"],"aplicaca":["web_app"],"web":["web_app"],"consum":["web_app"],"api":["web_app"],"esta":["web_app","ai","bi","rpa","iot"],"for":["web_app"],"ar":["web_app"],"tel":["web_app"],"fic":["web_app"],"em":["web_app"],"branc":["web_app"],"abrir":["web_app"],"entrar":["web_app"],"cont":["web_app"],"clic":["web_app"],"nos":["web_app"],"boto":["web_app"],"trav":["web_app","rpa"],"inic":["web_app","rpa"],"inteligenc":["ai"],"artificial":["ai"],"retorn":["ai"],"respost":["ai"],"errad":["ai","bi"],"model":["ai"],"de":["ai","bi","rpa","iot"],"ia":["ai"],"funcion":["ai","bi","rpa","iot"],"corret":["ai"],"result":["ai"],"inesper":["ai"],"da":["ai"],"previsa":["ai"],"process":["ai","rpa"],"linguag":["ai"],"natural":["ai"],"reconhec":["ai"],"intenca":["ai"],"classificaca":["ai"],"automat":["ai","rpa"],"treinament":["ai"],"aprend":["ai"],"incoerent":["ai"],"inferenc":["ai"],"inconsistent":["ai","bi"],"algoritm":["ai"],"com":["ai","bi","iot"],"machin":["ai"],"learning":["ai"],"incorret":["ai","bi"],"analis":["ai"],"text":["ai"],"pel":["ai","iot"],"respond":["ai","rpa","iot"],"esper":["ai"],"dashboard":["bi"],"ger":["bi"],"relatori":["bi"],"os":["bi"],"dad":["bi","iot"],"painel":["bi"],"visualizaca":["bi"],"dos":["bi"],"grafic":["bi"],"atualiz":["bi"],"nov":["bi"],"indic":["bi"],"bi":["bi"],"visualiz":["bi"],"atualizaca":["bi"],"apresent":["bi"],"valor":["bi"],"consult":["bi"],"mostr":["bi"],"informaco":["bi"],"desatualiz":["bi"],"rob":["rpa"],"execut":["rpa"],"taref":["rpa"],"automaca":["rpa"],"bot":["rpa"],"par":["rpa","iot"],"execuca":["rpa"],"automatiz":["rpa"],"durant":["rpa"],"mei":["rpa"],"workflow":["rpa"],"foi":["rpa"],"conclu":["rpa"],"script":["rpa"],"complet":["rpa"],"ativ":["rpa"],"rod":["rpa"],"job":["rpa"],"disposit":["iot"],"conect":["iot"],"red":["iot"],"sensor":["iot"],"envi":["iot"],"equip":["iot"],"offlin":["iot"],"comunicaca":["iot"],"aos":["iot"],"comand":["iot"],"aparec":["iot"],"integraca":["iot"],"desconect":["iot"],"frequent":["iot"],"telemetr":["iot"],"cheg":["iot"],"impressor":["iot"],"impressa":["iot"],"imprim":["iot"],"leitor":["iot"],"codig":["iot"],"barr":["iot"],"scann":["iot"],"cam":["iot"],"seguranc":["iot"],"control":["iot"],"catrac":["iot"],"eletron":["iot"],"presenc":["iot"],"detect":["iot"],"moviment":["iot"],"temperatur":["iot"],"terminal":["iot"],"pont":["iot"],"relogi":["iot"],"registr":["iot"],"monitor":["iot"],"conexa":["iot"],"fisic":["iot"],"hardwar":["iot"]},"neuralNetwork":{"settings":{"locale":"pt","tag":"nlu-pt","keepStopwords":true,"nonefeatureValue":1,"nonedeltaMultiplier":1.2,"spellCheck":false,"spellCheckDistance":1,"filterZeros":true,"log":true},"features":["nao","consig","acess","o","sit","a","pagin","carreg","no","naveg","erro","ao","faz","login","sistem","aplic","abre","celul","app","fech","sozinh","problem","na","interfac","do","inicial","falh","aplicaca","web","consum","api","esta","for","ar","tel","fic","em","branc","abrir","entrar","cont","clic","nos","boto","trav","inic","inteligenc","artificial","retorn","respost","errad","model","de","ia","funcion","corret","result","inesper","da","previsa","process","linguag","natural","reconhec","intenca","classificaca","automat","treinament","aprend","incoerent","inferenc","inconsistent","algoritm","com","machin","learning","incorret","analis","text","pel","respond","esper","dashboard","ger","relatori","os","dad","painel","visualizaca","dos","grafic","atualiz","nov","indic","bi","visualiz","atualizaca","apresent","valor","consult","mostr","informaco","desatualiz","rob","execut","taref","automaca","bot","par","execuca","automatiz","durant","mei","workflow","foi","conclu","script","complet","ativ","rod","job","disposit","conect","red","sensor","envi","equip","offlin","comunicaca","aos","comand","aparec","integraca","desconect","frequent","telemetr","cheg","impressor","impressa","imprim","leitor","codig","barr","scann","cam","seguranc","control","catrac","eletron","presenc","detect","moviment","temperatur","terminal","pont","relogi","registr","monitor","conexa","fisic","hardwar"],"intents":["web_app","ai","bi","rpa","iot"],"perceptrons":[[-0.4472750425338745,4.700691223144531,1.4703303575515747,0.14899492263793945,6.464483737945557,2.479010581970215,3.7813284397125244,1.126084327697754,1.430760145187378,4.108088970184326,1.3241140842437744,1.3261648416519165,-2.4820456504821777,8.86706829071045,2.24042010307312,2.5081520080566406,6.167013168334961,2.5081520080566406,6.200490951538086,3.0650737285614014,3.0650737285614014,1.5853519439697266,0.954293429851532,6.128375053405762,1.2882375717163086,2.1029489040374756,-1.8036705255508423,2.8322227001190186,5.912836074829102,3.573819637298584,3.573819637298584,-3.499946355819702,3.0768587589263916,3.0768587589263916,1.6871310472488403,1.6871310472488403,1.6871310472488403,1.6871310472488403,1.6871310472488403,3.524944543838501,3.524944543838501,0.5248172283172607,0.5248172283172607,0.5248172283172607,1.5544272661209106,2.9391376972198486,-0.8804196119308472,-0.8804196119308472,-0.6091755628585815,-0.8804196119308472,-0.9506743550300598,-4.876298904418945,-4.306708335876465,-1.6388355493545532,-0.37680351734161377,-2.596318006515503,-1.3156856298446655,-0.3671776354312897,-0.5635931491851807,-1.0322660207748413,-3.0483498573303223,-0.9572575092315674,-0.9572575092315674,-1.0007909536361694,-1.0007909536361694,-0.7736871838569641,-0.9457076787948608,-1.4680217504501343,-0.6052836179733276,-0.08508320152759552,-0.6961171627044678,-1.2147443294525146,-0.8111000657081604,-1.523429036140442,-0.024436218664050102,-0.024436218664050102,-0.648907482624054,-0.17145781219005585,-0.17145781219005585,-1.9855930805206299,-0.4444027543067932,-0.07679347693920135,-1.666193962097168,-1.6208328008651733,-6.149720191955566,-1.8316651582717896,-1.63430917263031,-1.3654534816741943,-0.7538341283798218,-1.743879795074463,-2.6379451751708984,-0.24212300777435303,-0.24212300777435303,-0.15221981704235077,-1.239802598953247,-1.801378607749939,-0.9073132276535034,-0.03245377540588379,-0.03245377540588379,0,-0.13026542961597443,-0.13026542961597443,-0.13026542961597443,-2.7890589237213135,-1.3247170448303223,-1.45822012424469,-1.2765229940414429,-1.7862399816513062,-1.1961086988449097,-3.18999981880188,-3.1909890174865723,-0.005023022182285786,-1.5869678258895874,-1.5200310945510864,-0.06694017350673676,-0.06694017350673676,-2.65151047706604,-0.7866238355636597,-0.7866238355636597,-1.1718138456344604,-1.4655184745788574,-1.7146570682525635,-1.5281010866165161,-2.5236518383026123,0,-1.1961086988449097,-2.245882511138916,-2.0297961235046387,-1.0637199878692627,-0.12598565220832825,-0.12598565220832825,-4.0753374099731445,0,-0.14745032787322998,-0.14745032787322998,0,0,-2.6167819499969482,-1.1961086988449097,-1.7450199127197266,0,0,0,0,-1.0637199878692627,0,0,0,0,0,0,0,0,-0.7350523471832275,-0.7350523471832275,0,0,0,0,0,-1.7145287990570068,2.059206519883979],[-1.8834986686706543,-0.3014512360095978,-0.6153534054756165,-2.2345261573791504,0,2.91099214553833,-0.1423995941877365,-2.124215602874756,-0.11048921942710876,-0.08898935467004776,0.9566724896430969,-3.2153470516204834,0,-2.120546579360962,-2.1448049545288086,0,0,0,-0.40548378229141235,-0.40548378229141235,-0.4713399112224579,0.8894515037536621,-0.04828919470310211,-0.6867827773094177,0.711271345615387,-0.040990300476551056,0.372173547744751,-0.3208465576171875,-0.45154666900634766,-0.9665976166725159,-0.9665976166725159,1.9999290704727173,-0.10528668761253357,-0.10528668761253357,-0.19556459784507751,-0.19556459784507751,-0.19556459784507751,-0.19556459784507751,-0.19556459784507751,0,0,0,0,0,-0.7816334366798401,-0.31697598099708557,3.1341452598571777,3.1341452598571777,-0.045834656804800034,3.1341452598571777,-1.2299188375473022,8.57469367980957,1.554491639137268,4.298833847045898,-2.676713228225708,3.359640121459961,2.40771484375,-2.788851022720337,0.39001449942588806,3.758725881576538,0.7996091842651367,4.903209209442139,4.903209209442139,1.138812780380249,1.138812780380249,7.031057834625244,5.653050422668457,2.9284210205078125,2.3474042415618896,3.1810221672058105,2.8089346885681152,4.66042423248291,5.1990532875061035,0.8092219829559326,1.7097156047821045,1.7097156047821045,4.272752285003662,2.0786023139953613,2.0786023139953613,2.0786023139953613,2.5772368907928467,2.905380964279175,-2.523414134979248,-0.5969294905662537,-1.980439305305481,-1.4368540048599243,-3.8457577228546143,-2.98429012298584,-1.1308943033218384,-1.0867408514022827,-1.0754269361495972,-0.2338750958442688,-0.2338750958442688,-1.0775612592697144,-0.4907034635543823,-0.3014512360095978,-0.3096902072429657,-1.2787266969680786,-1.2787266969680786,-0.7641317248344421,-0.10351980477571487,-0.10351980477571487,-0.10351980477571487,-2.448248863220215,-0.7457950711250305,-2.3261215686798096,-3.1461029052734375,-1.9644479751586914,-1.505350112915039,-2.016826868057251,-2.164811849594116,-0.06780705600976944,-0.7816334366798401,-0.9463883638381958,-1.3773635625839233,-1.3773635625839233,-0.8380904793739319,-0.40286341309547424,-0.40286341309547424,0,-0.7415772676467896,-1.9801987409591675,-1.212989091873169,-1.8162072896957397,-0.8517995476722717,0,-1.7675615549087524,-2.4023005962371826,-2.6025822162628174,-0.16117078065872192,-0.16117078065872192,-0.033746883273124695,-0.12033575028181076,-0.07796035706996918,-0.015490388497710228,0,0,-1.6549100875854492,0,0,-0.15549245476722717,-0.15549245476722717,-0.15549245476722717,0,-2.72066593170166,-0.24246926605701447,-0.02795739658176899,-0.0199759341776371,-0.0199759341776371,-0.20829112827777863,-0.20829112827777863,-0.20829112827777863,0,0,-0.4010410010814667,-0.4010410010814667,-0.4010410010814667,-0.6637818813323975,0,0,0,1.282593478797425],[-0.8870661854743958,1.284219741821289,1.9574884176254272,-0.36803102493286133,-2.6926491260528564,-4.60230016708374,-2.2864890098571777,5.077690124511719,-1.0906726121902466,0,1.1271742582321167,2.2030587196350098,-0.6991044878959656,-1.366186261177063,-1.5922200679779053,0,0,0,-1.0408989191055298,-0.3228442966938019,-0.3228442966938019,0.9304906129837036,0.4527127146720886,-0.17356817424297333,-4.13435173034668,-2.2864890098571777,-1.5349650382995605,-0.13928166031837463,-0.13928166031837463,-0.1544656604528427,-0.1544656604528427,0.13612833619117737,0,0,-0.10451676696538925,-0.10451676696538925,-0.10451676696538925,-0.10451676696538925,-0.10451676696538925,-0.8840910196304321,-0.8840910196304321,-0.5497864484786987,-0.5497864484786987,-0.5497864484786987,-1.0486409664154053,-1.1662628650665283,-0.3274710178375244,-0.3274710178375244,-0.13812315464019775,-0.3274710178375244,2.429373025894165,-1.2808911800384521,1.4655578136444092,-1.0924630165100098,1.5108344554901123,-0.2666037976741791,-0.01953851245343685,0,-0.1598961502313614,-0.45646825432777405,-1.8591006994247437,-0.22365830838680267,-0.22365830838680267,0,0,-0.17647483944892883,-0.7453049421310425,-0.07551717013120651,0,-0.1598961502313614,0,0.4962587058544159,-0.01953851245343685,-1.546989917755127,-0.8675961494445801,-0.8675961494445801,2.363309383392334,-0.8246989250183105,-0.8246989250183105,-1.1017862558364868,-0.49503642320632935,0,9.426177024841309,2.3160088062286377,7.989002704620361,4.255097389221191,6.129237651824951,4.7742180824279785,5.169214725494385,2.749164581298828,4.254359722137451,0.9202718734741211,0.9202718734741211,2.5959179401397705,1.8950517177581787,4.531576156616211,3.027923583984375,3.1582231521606445,3.1582231521606445,4.476865291595459,1.3575396537780762,1.3575396537780762,1.3575396537780762,-1.4721641540527344,-0.3157631456851959,-1.0547659397125244,-2.4652674198150635,-2.073486328125,-1.7056869268417358,-2.015760660171509,-2.170574426651001,-0.25159263610839844,-0.1878882348537445,-0.8684706687927246,-0.4627099931240082,-0.4627099931240082,-0.7537293434143066,-0.11795124411582947,-0.11795124411582947,-0.7933794260025024,-0.6570447683334351,-2.4561285972595215,-1.2457865476608276,-1.4049327373504639,-2.675276041030884,-4.414402961730957,-1.7138060331344604,-1.2009644508361816,-0.4854107201099396,-0.06984435766935349,-0.06984435766935349,-0.10832452028989792,-0.3350902497768402,-0.09067443758249283,-0.09067443758249283,-3.751255512237549,-3.751255512237549,-0.23066264390945435,-0.12399285286664963,-0.2233218103647232,-0.8479238748550415,-0.8479238748550415,-0.8479238748550415,-1.7845405340194702,-0.08596887439489365,-0.06657882034778595,-0.01648361049592495,-0.7772400975227356,-0.7772400975227356,0,0,0,-0.4217759668827057,-0.2062128335237503,-0.5508624911308289,-0.33604422211647034,-0.33604422211647034,-0.1606033444404602,-0.0001570142776472494,-0.0001570142776472494,0,0.8122143037246735],[1.6333476305007935,-1.5424143075942993,-0.8679413199424744,-1.6577333211898804,-1.8856663703918457,-0.04732833057641983,-1.1866400241851807,-1.1866400241851807,-0.08371927589178085,-0.7060707211494446,0.7564200758934021,-0.5994161367416382,-0.28642281889915466,-2.1144540309906006,-3.0155014991760254,-0.35022270679473877,-1.3942855596542358,-0.35022270679473877,-1.0968084335327148,-0.4959152936935425,-0.4959152936935425,1.396234393119812,-0.6998404860496521,-1.1601332426071167,2.2599782943725586,-0.4050341844558716,0.23299871385097504,-0.6758268475532532,-0.6821613907814026,-0.6897018551826477,-0.6897018551826477,-0.7653944492340088,-0.0016044597141444683,-0.0016044597141444683,-0.12481338530778885,-0.12481338530778885,-0.12481338530778885,-0.12481338530778885,-0.12481338530778885,-0.4045381546020508,-0.4045381546020508,-0.8037639260292053,-0.8037639260292053,-0.8037639260292053,0.04872806370258331,0.7214865684509277,-0.1782098412513733,-0.1782098412513733,-0.010559989139437675,-0.1782098412513733,-0.016592886298894882,-3.2814505100250244,-2.3992204666137695,-0.6839157342910767,2.9018325805664062,-0.6839157342910767,-1.7469919919967651,-0.5308902263641357,-0.8531677722930908,-0.5308902263641357,2.017951726913452,-1.773372769355774,-1.773372769355774,0,0,-1.9549952745437622,0.816061794757843,-1.5246104001998901,-0.6839157342910767,-0.16115109622478485,-1.0006697177886963,-1.0536129474639893,-1.0536129474639893,-1.819472074508667,0,0,-0.3744884431362152,0,0,-0.46543896198272705,1.6097724437713623,0,-0.3717098534107208,-0.7073525786399841,-0.7312613129615784,-0.46642065048217773,-2.472949981689453,-0.3744884431362152,-0.8911216259002686,-0.29527318477630615,-0.7429761290550232,0,0,-0.00043851000373251736,0,-0.43361228704452515,0,-0.3415720760822296,-0.3415720760822296,0,-0.35594460368156433,-0.35594460368156433,-0.35594460368156433,5.894054412841797,2.2069504261016846,5.004032611846924,9.211254119873047,9.836198806762695,2.610240936279297,4.862268447875977,8.67709732055664,-1.22525954246521,0.6358087658882141,3.712860107421875,2.7960901260375977,2.7960901260375977,5.180598258972168,2.777418851852417,2.777418851852417,4.202079772949219,3.6556694507598877,-3.4796605110168457,-1.6494938135147095,-2.327338218688965,-4.283430576324463,-1.111543893814087,-1.5517990589141846,-0.748204231262207,-1.3301128149032593,-1.5660982131958008,-1.5660982131958008,-0.9411365389823914,-0.3426508903503418,-0.0389101579785347,-0.0389101579785347,-0.6455508470535278,-0.6455508470535278,-1.593719482421875,-0.10537907481193542,-0.46543896198272705,-0.9410483241081238,-0.9410483241081238,-0.9410483241081238,-0.04126966372132301,-0.8890480399131775,-0.22213883697986603,0,-2.493952989578247,-2.493952989578247,-0.06873884797096252,-0.06873884797096252,-0.06873884797096252,0,0,-0.0011760834604501724,-0.0011760834604501724,-0.0011760834604501724,0,0,0,-0.018634015694260597,1.2412055789825898],[0.7483056783676147,-1.419765591621399,-0.004763443488627672,-0.5352587103843689,-3.1162490844726562,-0.2948547303676605,-1.5673577785491943,-4.207563877105713,-1.4447221755981445,-4.0479416847229,0.1149841845035553,-1.1375031471252441,-0.7319540977478027,-1.5817195177078247,2.3673930168151855,-1.378736138343811,-3.333224296569824,-1.378736138343811,-0.9658893942832947,-0.5988066792488098,-3.05668306350708,-0.6357554197311401,-1.3669434785842896,-1.1147958040237427,-3.17038631439209,-0.12481395900249481,2.1419854164123535,-0.6759393215179443,-1.9974708557128906,-0.2869037389755249,-0.2869037389755249,2.219395637512207,-1.2756601572036743,-1.2756601572036743,-0.23883338272571564,-0.23883338272571564,-0.23883338272571564,-0.23883338272571564,-0.23883338272571564,-1.8525850772857666,-1.8525850772857666,0,0,0,-0.2661232650279999,-1.1371277570724487,-0.8958411812782288,-0.8958411812782288,-0.8527911305427551,-0.8958411812782288,-1.2480989694595337,-5.685641765594482,2.911247491836548,-4.505002021789551,-0.4362330436706543,-3.085453510284424,-0.015032592229545116,-0.015032592229545116,-0.04198359325528145,-1.755829095840454,-1.8080241680145264,-0.8712051510810852,-0.8712051510810852,0,0,-1.902176022529602,-2.162182331085205,0,-0.7189198732376099,-0.019434703513979912,-0.03140941634774208,-0.0716085359454155,0,3.868501901626587,-0.8959430456161499,-0.8959430456161499,-2.1511552333831787,-1.3531651496887207,-1.3531651496887207,3.6405444145202637,1.2148092985153198,-2.3175957202911377,-2.4494612216949463,0,-2.4442758560180664,-0.9570444226264954,-1.0420533418655396,-0.8326213359832764,-4.6120076179504395,-0.7712026238441467,-0.7330663204193115,-2.351752519607544,-2.351752519607544,-0.31334587931632996,-0.40723708271980286,-0.5317586660385132,-0.5700386166572571,0,0,-1.7390556335449219,-0.05960123613476753,-0.05960123613476753,-0.05960123613476753,-1.5225950479507446,-0.7854363322257996,-1.0353211164474487,-4.673392295837402,-6.696183681488037,2.7445032596588135,-0.5760086178779602,-0.8469527959823608,-0.5760086178779602,0,0,-0.20632357895374298,-0.20632357895374298,0,-0.6918989419937134,-0.6918989419937134,-0.12781697511672974,0,6.077202320098877,2.9825870990753174,4.49738883972168,6.7544264793396,4.4626641273498535,5.886077880859375,3.8224048614501953,2.6032602787017822,2.2315750122070312,2.2315750122070312,5.4584221839904785,2.3003594875335693,1.9361038208007812,4.286710739135742,4.907889366149902,4.907889366149902,5.909576892852783,0.7154290080070496,4.9972381591796875,3.2838096618652344,3.2838096618652344,3.2838096618652344,5.696502685546875,5.179509162902832,0.8224701285362244,2.0110788345336914,4.926090717315674,4.926090717315674,0.6738480925559998,0.6738480925559998,0.6738480925559998,-1.6144254207611084,1.2704510688781738,3.203519344329834,1.9284753799438477,1.9284753799438477,-2.4122910499572754,1.0913517475128174,1.0913517475128174,5.261139392852783,1.9811587736336536]]}}}}},"intentDomains":{},"extraSentences":[["pt","não consigo acessar o site"],["pt","a página não carrega no navegador"],["pt","erro ao fazer login no sistema"],["pt","o aplicativo não abre no celular"],["pt","app fecha sozinho"],["pt","problema na interface do sistema"],["pt","erro ao carregar a página inicial"],["pt","não consigo navegar no sistema"],["pt","falha ao acessar a aplicação web"],["pt","erro ao consumir a api"],["pt","o sistema web está fora do ar"],["pt","a tela fica em branco ao abrir"],["pt","não consigo entrar na conta"],["pt","problema ao clicar nos botões do site"],["pt","o app trava ao iniciar"],["pt","a inteligência artificial está retornando respostas erradas"],["pt","o modelo de ia não está funcionando corretamente"],["pt","resultado inesperado da previsão do modelo"],["pt","erro no processamento de linguagem natural"],["pt","o modelo não reconhece a intenção corretamente"],["pt","falha na classificação automática"],["pt","problema no treinamento do modelo"],["pt","a ia não está aprendendo corretamente"],["pt","resposta incoerente da inteligência artificial"],["pt","erro na inferência do modelo"],["pt","resultado inconsistente do algoritmo"],["pt","problema com o modelo de machine learning"],["pt","a previsão está incorreta"],["pt","erro na análise de texto pela ia"],["pt","modelo não responde como esperado"],["pt","o dashboard não está carregando"],["pt","erro ao gerar relatório"],["pt","os dados do painel estão incorretos"],["pt","problema na visualização dos gráficos"],["pt","relatório não atualiza com dados novos"],["pt","indicadores estão errados no dashboard"],["pt","falha ao carregar o painel de BI"],["pt","dados inconsistentes no relatório"],["pt","não consigo visualizar os gráficos"],["pt","erro na atualização dos dados"],["pt","painel apresenta valores incorretos"],["pt","problema na consulta de dados"],["pt","dashboard mostra informações desatualizadas"],["pt","erro ao acessar relatórios"],["pt","visualização de dados não funciona"],["pt","o robô não executou a tarefa"],["pt","falha na automação do processo"],["pt","bot parou de funcionar"],["pt","erro na execução do robô"],["pt","processo automatizado não iniciou"],["pt","automação falhou durante execução"],["pt","o bot travou no meio do processo"],["pt","erro no workflow automatizado"],["pt","tarefa automática não foi concluída"],["pt","problema na execução do script"],["pt","robô não completou a atividade"],["pt","falha ao rodar automação"],["pt","erro no job automatizado"],["pt","bot não responde"],["pt","automação não está funcionando"],["pt","o dispositivo não conecta na rede"],["pt","sensor não está enviando dados"],["pt","equipamento está offline"],["pt","falha na comunicação com o dispositivo"],["pt","dispositivo não responde aos comandos"],["pt","equipamento não aparece no sistema"],["pt","falha na integração com o dispositivo"],["pt","sensor parou de funcionar"],["pt","erro na rede de dispositivos"],["pt","dispositivo desconectando frequentemente"],["pt","dados de telemetria não chegam"],["pt","a impressora não conecta na rede"],["pt","impressora não responde aos comandos"],["pt","erro ao enviar impressão para o dispositivo"],["pt","a impressora está offline no sistema"],["pt","não consigo imprimir pela rede"],["pt","o leitor de código de barras não funciona"],["pt","scanner não está enviando dados"],["pt","câmera de segurança não conecta"],["pt","falha na comunicação com a câmera"],["pt","o dispositivo de controle de acesso não responde"],["pt","catraca eletrônica não está funcionando"],["pt","sensor de presença não detecta movimento"],["pt","sensor de temperatura não envia dados"],["pt","terminal de ponto não conecta ao sistema"],["pt","o relógio de ponto não está registrando"],["pt","equipamento de monitoramento está offline"],["pt","falha na conexão com o dispositivo físico"],["pt","o hardware não aparece no sistema"],["pt","dispositivo de rede desconectando sozinho"],["pt","problema com equipamento conectado"],["pt","site não abre"],["pt","erro no login"]]},"ner":{"settings":{"tag":"ner","entityPreffix":"%","entitySuffix":"%"},"rules":{}},"nlgManager":{"settings":{"tag":"nlg-manager"},"responses":{}},"actionManager":{"settings":{"tag":"action-manager"},"actions":{}},"slotManager":{}} \ No newline at end of file +{"settings":{"languages":["pt"],"tag":"nlp","threshold":0.5,"autoLoad":true,"autoSave":true,"modelFileName":"model.nlp","executeActionsBeforeAnswers":false,"calculateSentiment":true},"nluManager":{"settings":{"tag":"nlu-manager"},"locales":["pt"],"languageNames":{},"domainManagers":{"pt":{"settings":{"locale":"pt","trainByDomain":false,"tag":"domain-manager-pt","nluByDomain":{"default":{"className":"NeuralNlu","settings":{}}},"useStemDict":true},"stemDict":{"acess,consig,nao,o,sit":{"intent":"web_app","domain":"default"},"a,carreg,nao,naveg,no,pagin":{"intent":"web_app","domain":"default"},"ao,erro,faz,login,no,sistem":{"intent":"web_app","domain":"default"},"abre,aplic,celul,nao,no,o":{"intent":"web_app","domain":"default"},"app,fech,sozinh":{"intent":"web_app","domain":"default"},"do,interfac,na,problem,sistem":{"intent":"web_app","domain":"default"},"a,ao,carreg,erro,inicial,pagin":{"intent":"web_app","domain":"default"},"consig,nao,naveg,no,sistem":{"intent":"web_app","domain":"default"},"a,acess,ao,aplicaca,falh,web":{"intent":"web_app","domain":"default"},"a,ao,api,consum,erro":{"intent":"web_app","domain":"default"},"ar,do,esta,for,o,sistem,web":{"intent":"web_app","domain":"default"},"a,abrir,ao,branc,em,fic,tel":{"intent":"web_app","domain":"default"},"consig,cont,entrar,na,nao":{"intent":"web_app","domain":"default"},"ao,boto,clic,do,nos,problem,sit":{"intent":"web_app","domain":"default"},"ao,app,inic,o,trav":{"intent":"web_app","domain":"default"},"a,artificial,errad,esta,inteligenc,respost,retorn":{"intent":"ai","domain":"default"},"corret,de,esta,funcion,ia,model,nao,o":{"intent":"ai","domain":"default"},"da,do,inesper,model,previsa,result":{"intent":"ai","domain":"default"},"de,erro,linguag,natural,no,process":{"intent":"ai","domain":"default"},"a,corret,intenca,model,nao,o,reconhec":{"intent":"ai","domain":"default"},"automat,classificaca,falh,na":{"intent":"ai","domain":"default"},"do,model,no,problem,treinament":{"intent":"ai","domain":"default"},"a,aprend,corret,esta,ia,nao":{"intent":"ai","domain":"default"},"artificial,da,incoerent,inteligenc,respost":{"intent":"ai","domain":"default"},"do,erro,inferenc,model,na":{"intent":"ai","domain":"default"},"algoritm,do,inconsistent,result":{"intent":"ai","domain":"default"},"com,de,learning,machin,model,o,problem":{"intent":"ai","domain":"default"},"a,esta,incorret,previsa":{"intent":"ai","domain":"default"},"analis,de,erro,ia,na,pel,text":{"intent":"ai","domain":"default"},"com,esper,model,nao,respond":{"intent":"ai","domain":"default"},"carreg,dashboard,esta,nao,o":{"intent":"bi","domain":"default"},"ao,erro,ger,relatori":{"intent":"bi","domain":"default"},"dad,do,esta,incorret,os,painel":{"intent":"bi","domain":"default"},"dos,grafic,na,problem,visualizaca":{"intent":"bi","domain":"default"},"atualiz,com,dad,nao,nov,relatori":{"intent":"bi","domain":"default"},"dashboard,errad,esta,indic,no":{"intent":"bi","domain":"default"},"ao,bi,carreg,de,falh,o,painel":{"intent":"bi","domain":"default"},"dad,inconsistent,no,relatori":{"intent":"bi","domain":"default"},"consig,grafic,nao,os,visualiz":{"intent":"bi","domain":"default"},"atualizaca,dad,dos,erro,na":{"intent":"bi","domain":"default"},"apresent,incorret,painel,valor":{"intent":"bi","domain":"default"},"consult,dad,de,na,problem":{"intent":"bi","domain":"default"},"dashboard,desatualiz,informaco,mostr":{"intent":"bi","domain":"default"},"acess,ao,erro,relatori":{"intent":"bi","domain":"default"},"dad,de,funcion,nao,visualizaca":{"intent":"bi","domain":"default"},"a,execut,nao,o,rob,taref":{"intent":"rpa","domain":"default"},"automaca,do,falh,na,process":{"intent":"rpa","domain":"default"},"bot,de,funcion,par":{"intent":"rpa","domain":"default"},"do,erro,execuca,na,rob":{"intent":"rpa","domain":"default"},"automatiz,inic,nao,process":{"intent":"rpa","domain":"default"},"automaca,durant,execuca,falh":{"intent":"rpa","domain":"default"},"bot,do,mei,no,o,process,trav":{"intent":"rpa","domain":"default"},"automatiz,erro,no,workflow":{"intent":"rpa","domain":"default"},"automat,conclu,foi,nao,taref":{"intent":"rpa","domain":"default"},"do,execuca,na,problem,script":{"intent":"rpa","domain":"default"},"a,ativ,complet,nao,rob":{"intent":"rpa","domain":"default"},"ao,automaca,falh,rod":{"intent":"rpa","domain":"default"},"automatiz,erro,job,no":{"intent":"rpa","domain":"default"},"bot,nao,respond":{"intent":"rpa","domain":"default"},"automaca,esta,funcion,nao":{"intent":"rpa","domain":"default"},"conect,disposit,na,nao,o,red":{"intent":"iot","domain":"default"},"dad,envi,esta,nao,sensor":{"intent":"iot","domain":"default"},"equip,esta,offlin":{"intent":"iot","domain":"default"},"com,comunicaca,disposit,falh,na,o":{"intent":"iot","domain":"default"},"aos,comand,disposit,nao,respond":{"intent":"iot","domain":"default"},"aparec,equip,nao,no,sistem":{"intent":"iot","domain":"default"},"com,disposit,falh,integraca,na,o":{"intent":"iot","domain":"default"},"de,funcion,par,sensor":{"intent":"iot","domain":"default"},"de,disposit,erro,na,red":{"intent":"iot","domain":"default"},"desconect,disposit,frequent":{"intent":"iot","domain":"default"},"cheg,dad,de,nao,telemetr":{"intent":"iot","domain":"default"},"a,conect,impressor,na,nao,red":{"intent":"iot","domain":"default"},"aos,comand,impressor,nao,respond":{"intent":"iot","domain":"default"},"ao,disposit,envi,erro,impressa,o,par":{"intent":"iot","domain":"default"},"a,esta,impressor,no,offlin,sistem":{"intent":"iot","domain":"default"},"consig,imprim,nao,pel,red":{"intent":"iot","domain":"default"},"barr,codig,de,funcion,leitor,nao,o":{"intent":"iot","domain":"default"},"dad,envi,esta,nao,scann":{"intent":"iot","domain":"default"},"cam,conect,de,nao,seguranc":{"intent":"iot","domain":"default"},"a,cam,com,comunicaca,falh,na":{"intent":"iot","domain":"default"},"acess,control,de,disposit,nao,o,respond":{"intent":"iot","domain":"default"},"catrac,eletron,esta,funcion,nao":{"intent":"iot","domain":"default"},"de,detect,moviment,nao,presenc,sensor":{"intent":"iot","domain":"default"},"dad,de,envi,nao,sensor,temperatur":{"intent":"iot","domain":"default"},"ao,conect,de,nao,pont,sistem,terminal":{"intent":"iot","domain":"default"},"de,esta,nao,o,pont,registr,relogi":{"intent":"iot","domain":"default"},"de,equip,esta,monitor,offlin":{"intent":"iot","domain":"default"},"com,conexa,disposit,falh,fisic,na,o":{"intent":"iot","domain":"default"},"aparec,hardwar,nao,no,o,sistem":{"intent":"iot","domain":"default"},"de,desconect,disposit,red,sozinh":{"intent":"iot","domain":"default"},"com,conect,equip,problem":{"intent":"iot","domain":"default"}},"intentDict":{"web_app":"default","ai":"default","bi":"default","rpa":"default","iot":"default"},"sentences":[{"domain":"default","utterance":"não consigo acessar o site","intent":"web_app"},{"domain":"default","utterance":"a página não carrega no navegador","intent":"web_app"},{"domain":"default","utterance":"erro ao fazer login no sistema","intent":"web_app"},{"domain":"default","utterance":"o aplicativo não abre no celular","intent":"web_app"},{"domain":"default","utterance":"app fecha sozinho","intent":"web_app"},{"domain":"default","utterance":"problema na interface do sistema","intent":"web_app"},{"domain":"default","utterance":"erro ao carregar a página inicial","intent":"web_app"},{"domain":"default","utterance":"não consigo navegar no sistema","intent":"web_app"},{"domain":"default","utterance":"falha ao acessar a aplicação web","intent":"web_app"},{"domain":"default","utterance":"erro ao consumir a api","intent":"web_app"},{"domain":"default","utterance":"o sistema web está fora do ar","intent":"web_app"},{"domain":"default","utterance":"a tela fica em branco ao abrir","intent":"web_app"},{"domain":"default","utterance":"não consigo entrar na conta","intent":"web_app"},{"domain":"default","utterance":"problema ao clicar nos botões do site","intent":"web_app"},{"domain":"default","utterance":"o app trava ao iniciar","intent":"web_app"},{"domain":"default","utterance":"a inteligência artificial está retornando respostas erradas","intent":"ai"},{"domain":"default","utterance":"o modelo de ia não está funcionando corretamente","intent":"ai"},{"domain":"default","utterance":"resultado inesperado da previsão do modelo","intent":"ai"},{"domain":"default","utterance":"erro no processamento de linguagem natural","intent":"ai"},{"domain":"default","utterance":"o modelo não reconhece a intenção corretamente","intent":"ai"},{"domain":"default","utterance":"falha na classificação automática","intent":"ai"},{"domain":"default","utterance":"problema no treinamento do modelo","intent":"ai"},{"domain":"default","utterance":"a ia não está aprendendo corretamente","intent":"ai"},{"domain":"default","utterance":"resposta incoerente da inteligência artificial","intent":"ai"},{"domain":"default","utterance":"erro na inferência do modelo","intent":"ai"},{"domain":"default","utterance":"resultado inconsistente do algoritmo","intent":"ai"},{"domain":"default","utterance":"problema com o modelo de machine learning","intent":"ai"},{"domain":"default","utterance":"a previsão está incorreta","intent":"ai"},{"domain":"default","utterance":"erro na análise de texto pela ia","intent":"ai"},{"domain":"default","utterance":"modelo não responde como esperado","intent":"ai"},{"domain":"default","utterance":"o dashboard não está carregando","intent":"bi"},{"domain":"default","utterance":"erro ao gerar relatório","intent":"bi"},{"domain":"default","utterance":"os dados do painel estão incorretos","intent":"bi"},{"domain":"default","utterance":"problema na visualização dos gráficos","intent":"bi"},{"domain":"default","utterance":"relatório não atualiza com dados novos","intent":"bi"},{"domain":"default","utterance":"indicadores estão errados no dashboard","intent":"bi"},{"domain":"default","utterance":"falha ao carregar o painel de BI","intent":"bi"},{"domain":"default","utterance":"dados inconsistentes no relatório","intent":"bi"},{"domain":"default","utterance":"não consigo visualizar os gráficos","intent":"bi"},{"domain":"default","utterance":"erro na atualização dos dados","intent":"bi"},{"domain":"default","utterance":"painel apresenta valores incorretos","intent":"bi"},{"domain":"default","utterance":"problema na consulta de dados","intent":"bi"},{"domain":"default","utterance":"dashboard mostra informações desatualizadas","intent":"bi"},{"domain":"default","utterance":"erro ao acessar relatórios","intent":"bi"},{"domain":"default","utterance":"visualização de dados não funciona","intent":"bi"},{"domain":"default","utterance":"o robô não executou a tarefa","intent":"rpa"},{"domain":"default","utterance":"falha na automação do processo","intent":"rpa"},{"domain":"default","utterance":"bot parou de funcionar","intent":"rpa"},{"domain":"default","utterance":"erro na execução do robô","intent":"rpa"},{"domain":"default","utterance":"processo automatizado não iniciou","intent":"rpa"},{"domain":"default","utterance":"automação falhou durante execução","intent":"rpa"},{"domain":"default","utterance":"o bot travou no meio do processo","intent":"rpa"},{"domain":"default","utterance":"erro no workflow automatizado","intent":"rpa"},{"domain":"default","utterance":"tarefa automática não foi concluída","intent":"rpa"},{"domain":"default","utterance":"problema na execução do script","intent":"rpa"},{"domain":"default","utterance":"robô não completou a atividade","intent":"rpa"},{"domain":"default","utterance":"falha ao rodar automação","intent":"rpa"},{"domain":"default","utterance":"erro no job automatizado","intent":"rpa"},{"domain":"default","utterance":"bot não responde","intent":"rpa"},{"domain":"default","utterance":"automação não está funcionando","intent":"rpa"},{"domain":"default","utterance":"o dispositivo não conecta na rede","intent":"iot"},{"domain":"default","utterance":"sensor não está enviando dados","intent":"iot"},{"domain":"default","utterance":"equipamento está offline","intent":"iot"},{"domain":"default","utterance":"falha na comunicação com o dispositivo","intent":"iot"},{"domain":"default","utterance":"dispositivo não responde aos comandos","intent":"iot"},{"domain":"default","utterance":"equipamento não aparece no sistema","intent":"iot"},{"domain":"default","utterance":"falha na integração com o dispositivo","intent":"iot"},{"domain":"default","utterance":"sensor parou de funcionar","intent":"iot"},{"domain":"default","utterance":"erro na rede de dispositivos","intent":"iot"},{"domain":"default","utterance":"dispositivo desconectando frequentemente","intent":"iot"},{"domain":"default","utterance":"dados de telemetria não chegam","intent":"iot"},{"domain":"default","utterance":"a impressora não conecta na rede","intent":"iot"},{"domain":"default","utterance":"impressora não responde aos comandos","intent":"iot"},{"domain":"default","utterance":"erro ao enviar impressão para o dispositivo","intent":"iot"},{"domain":"default","utterance":"a impressora está offline no sistema","intent":"iot"},{"domain":"default","utterance":"não consigo imprimir pela rede","intent":"iot"},{"domain":"default","utterance":"o leitor de código de barras não funciona","intent":"iot"},{"domain":"default","utterance":"scanner não está enviando dados","intent":"iot"},{"domain":"default","utterance":"câmera de segurança não conecta","intent":"iot"},{"domain":"default","utterance":"falha na comunicação com a câmera","intent":"iot"},{"domain":"default","utterance":"o dispositivo de controle de acesso não responde","intent":"iot"},{"domain":"default","utterance":"catraca eletrônica não está funcionando","intent":"iot"},{"domain":"default","utterance":"sensor de presença não detecta movimento","intent":"iot"},{"domain":"default","utterance":"sensor de temperatura não envia dados","intent":"iot"},{"domain":"default","utterance":"terminal de ponto não conecta ao sistema","intent":"iot"},{"domain":"default","utterance":"o relógio de ponto não está registrando","intent":"iot"},{"domain":"default","utterance":"equipamento de monitoramento está offline","intent":"iot"},{"domain":"default","utterance":"falha na conexão com o dispositivo físico","intent":"iot"},{"domain":"default","utterance":"o hardware não aparece no sistema","intent":"iot"},{"domain":"default","utterance":"dispositivo de rede desconectando sozinho","intent":"iot"},{"domain":"default","utterance":"problema com equipamento conectado","intent":"iot"}],"domains":{"master_domain":{"settings":{"locale":"pt","tag":"nlu-pt","keepStopwords":true,"nonefeatureValue":1,"nonedeltaMultiplier":1.2,"spellCheck":false,"spellCheckDistance":1,"filterZeros":true,"log":true},"features":{"nao":1,"consig":1,"acess":1,"o":1,"sit":1,"a":1,"pagin":1,"carreg":1,"no":1,"naveg":1,"erro":1,"ao":1,"faz":1,"login":1,"sistem":1,"aplic":1,"abre":1,"celul":1,"app":1,"fech":1,"sozinh":1,"problem":1,"na":1,"interfac":1,"do":1,"inicial":1,"falh":1,"aplicaca":1,"web":1,"consum":1,"api":1,"esta":1,"for":1,"ar":1,"tel":1,"fic":1,"em":1,"branc":1,"abrir":1,"entrar":1,"cont":1,"clic":1,"nos":1,"boto":1,"trav":1,"inic":1,"inteligenc":1,"artificial":1,"retorn":1,"respost":1,"errad":1,"model":1,"de":1,"ia":1,"funcion":1,"corret":1,"result":1,"inesper":1,"da":1,"previsa":1,"process":1,"linguag":1,"natural":1,"reconhec":1,"intenca":1,"classificaca":1,"automat":1,"treinament":1,"aprend":1,"incoerent":1,"inferenc":1,"inconsistent":1,"algoritm":1,"com":1,"machin":1,"learning":1,"incorret":1,"analis":1,"text":1,"pel":1,"respond":1,"esper":1,"dashboard":1,"ger":1,"relatori":1,"os":1,"dad":1,"painel":1,"visualizaca":1,"dos":1,"grafic":1,"atualiz":1,"nov":1,"indic":1,"bi":1,"visualiz":1,"atualizaca":1,"apresent":1,"valor":1,"consult":1,"mostr":1,"informaco":1,"desatualiz":1,"rob":1,"execut":1,"taref":1,"automaca":1,"bot":1,"par":1,"execuca":1,"automatiz":1,"durant":1,"mei":1,"workflow":1,"foi":1,"conclu":1,"script":1,"complet":1,"ativ":1,"rod":1,"job":1,"disposit":1,"conect":1,"red":1,"sensor":1,"envi":1,"equip":1,"offlin":1,"comunicaca":1,"aos":1,"comand":1,"aparec":1,"integraca":1,"desconect":1,"frequent":1,"telemetr":1,"cheg":1,"impressor":1,"impressa":1,"imprim":1,"leitor":1,"codig":1,"barr":1,"scann":1,"cam":1,"seguranc":1,"control":1,"catrac":1,"eletron":1,"presenc":1,"detect":1,"moviment":1,"temperatur":1,"terminal":1,"pont":1,"relogi":1,"registr":1,"monitor":1,"conexa":1,"fisic":1,"hardwar":1},"intents":{"web_app":1,"ai":1,"bi":1,"rpa":1,"iot":1},"intentFeatures":{"web_app":{"nao":1,"consig":1,"acess":1,"o":1,"sit":1,"a":1,"pagin":1,"carreg":1,"no":1,"naveg":1,"erro":1,"ao":1,"faz":1,"login":1,"sistem":1,"aplic":1,"abre":1,"celul":1,"app":1,"fech":1,"sozinh":1,"problem":1,"na":1,"interfac":1,"do":1,"inicial":1,"falh":1,"aplicaca":1,"web":1,"consum":1,"api":1,"esta":1,"for":1,"ar":1,"tel":1,"fic":1,"em":1,"branc":1,"abrir":1,"entrar":1,"cont":1,"clic":1,"nos":1,"boto":1,"trav":1,"inic":1},"ai":{"a":1,"inteligenc":1,"artificial":1,"esta":1,"retorn":1,"respost":1,"errad":1,"o":1,"model":1,"de":1,"ia":1,"nao":1,"funcion":1,"corret":1,"result":1,"inesper":1,"da":1,"previsa":1,"do":1,"erro":1,"no":1,"process":1,"linguag":1,"natural":1,"reconhec":1,"intenca":1,"falh":1,"na":1,"classificaca":1,"automat":1,"problem":1,"treinament":1,"aprend":1,"incoerent":1,"inferenc":1,"inconsistent":1,"algoritm":1,"com":1,"machin":1,"learning":1,"incorret":1,"analis":1,"text":1,"pel":1,"respond":1,"esper":1},"bi":{"o":1,"dashboard":1,"nao":1,"esta":1,"carreg":1,"erro":1,"ao":1,"ger":1,"relatori":1,"os":1,"dad":1,"do":1,"painel":1,"incorret":1,"problem":1,"na":1,"visualizaca":1,"dos":1,"grafic":1,"atualiz":1,"com":1,"nov":1,"indic":1,"errad":1,"no":1,"falh":1,"de":1,"bi":1,"inconsistent":1,"consig":1,"visualiz":1,"atualizaca":1,"apresent":1,"valor":1,"consult":1,"mostr":1,"informaco":1,"desatualiz":1,"acess":1,"funcion":1},"rpa":{"o":1,"rob":1,"nao":1,"execut":1,"a":1,"taref":1,"falh":1,"na":1,"automaca":1,"do":1,"process":1,"bot":1,"par":1,"de":1,"funcion":1,"erro":1,"execuca":1,"automatiz":1,"inic":1,"durant":1,"trav":1,"no":1,"mei":1,"workflow":1,"automat":1,"foi":1,"conclu":1,"problem":1,"script":1,"complet":1,"ativ":1,"ao":1,"rod":1,"job":1,"respond":1,"esta":1},"iot":{"o":1,"disposit":1,"nao":1,"conect":1,"na":1,"red":1,"sensor":1,"esta":1,"envi":1,"dad":1,"equip":1,"offlin":1,"falh":1,"comunicaca":1,"com":1,"respond":1,"aos":1,"comand":1,"aparec":1,"no":1,"sistem":1,"integraca":1,"par":1,"de":1,"funcion":1,"erro":1,"desconect":1,"frequent":1,"telemetr":1,"cheg":1,"a":1,"impressor":1,"ao":1,"impressa":1,"consig":1,"imprim":1,"pel":1,"leitor":1,"codig":1,"barr":1,"scann":1,"cam":1,"seguranc":1,"control":1,"acess":1,"catrac":1,"eletron":1,"presenc":1,"detect":1,"moviment":1,"temperatur":1,"terminal":1,"pont":1,"relogi":1,"registr":1,"monitor":1,"conexa":1,"fisic":1,"hardwar":1,"sozinh":1,"problem":1}},"featuresToIntent":{"nao":["web_app","ai","bi","rpa","iot"],"consig":["web_app","bi","iot"],"acess":["web_app","bi","iot"],"o":["web_app","ai","bi","rpa","iot"],"sit":["web_app"],"a":["web_app","ai","rpa","iot"],"pagin":["web_app"],"carreg":["web_app","bi"],"no":["web_app","ai","bi","rpa","iot"],"naveg":["web_app"],"erro":["web_app","ai","bi","rpa","iot"],"ao":["web_app","bi","rpa","iot"],"faz":["web_app"],"login":["web_app"],"sistem":["web_app","iot"],"aplic":["web_app"],"abre":["web_app"],"celul":["web_app"],"app":["web_app"],"fech":["web_app"],"sozinh":["web_app","iot"],"problem":["web_app","ai","bi","rpa","iot"],"na":["web_app","ai","bi","rpa","iot"],"interfac":["web_app"],"do":["web_app","ai","bi","rpa"],"inicial":["web_app"],"falh":["web_app","ai","bi","rpa","iot"],"aplicaca":["web_app"],"web":["web_app"],"consum":["web_app"],"api":["web_app"],"esta":["web_app","ai","bi","rpa","iot"],"for":["web_app"],"ar":["web_app"],"tel":["web_app"],"fic":["web_app"],"em":["web_app"],"branc":["web_app"],"abrir":["web_app"],"entrar":["web_app"],"cont":["web_app"],"clic":["web_app"],"nos":["web_app"],"boto":["web_app"],"trav":["web_app","rpa"],"inic":["web_app","rpa"],"inteligenc":["ai"],"artificial":["ai"],"retorn":["ai"],"respost":["ai"],"errad":["ai","bi"],"model":["ai"],"de":["ai","bi","rpa","iot"],"ia":["ai"],"funcion":["ai","bi","rpa","iot"],"corret":["ai"],"result":["ai"],"inesper":["ai"],"da":["ai"],"previsa":["ai"],"process":["ai","rpa"],"linguag":["ai"],"natural":["ai"],"reconhec":["ai"],"intenca":["ai"],"classificaca":["ai"],"automat":["ai","rpa"],"treinament":["ai"],"aprend":["ai"],"incoerent":["ai"],"inferenc":["ai"],"inconsistent":["ai","bi"],"algoritm":["ai"],"com":["ai","bi","iot"],"machin":["ai"],"learning":["ai"],"incorret":["ai","bi"],"analis":["ai"],"text":["ai"],"pel":["ai","iot"],"respond":["ai","rpa","iot"],"esper":["ai"],"dashboard":["bi"],"ger":["bi"],"relatori":["bi"],"os":["bi"],"dad":["bi","iot"],"painel":["bi"],"visualizaca":["bi"],"dos":["bi"],"grafic":["bi"],"atualiz":["bi"],"nov":["bi"],"indic":["bi"],"bi":["bi"],"visualiz":["bi"],"atualizaca":["bi"],"apresent":["bi"],"valor":["bi"],"consult":["bi"],"mostr":["bi"],"informaco":["bi"],"desatualiz":["bi"],"rob":["rpa"],"execut":["rpa"],"taref":["rpa"],"automaca":["rpa"],"bot":["rpa"],"par":["rpa","iot"],"execuca":["rpa"],"automatiz":["rpa"],"durant":["rpa"],"mei":["rpa"],"workflow":["rpa"],"foi":["rpa"],"conclu":["rpa"],"script":["rpa"],"complet":["rpa"],"ativ":["rpa"],"rod":["rpa"],"job":["rpa"],"disposit":["iot"],"conect":["iot"],"red":["iot"],"sensor":["iot"],"envi":["iot"],"equip":["iot"],"offlin":["iot"],"comunicaca":["iot"],"aos":["iot"],"comand":["iot"],"aparec":["iot"],"integraca":["iot"],"desconect":["iot"],"frequent":["iot"],"telemetr":["iot"],"cheg":["iot"],"impressor":["iot"],"impressa":["iot"],"imprim":["iot"],"leitor":["iot"],"codig":["iot"],"barr":["iot"],"scann":["iot"],"cam":["iot"],"seguranc":["iot"],"control":["iot"],"catrac":["iot"],"eletron":["iot"],"presenc":["iot"],"detect":["iot"],"moviment":["iot"],"temperatur":["iot"],"terminal":["iot"],"pont":["iot"],"relogi":["iot"],"registr":["iot"],"monitor":["iot"],"conexa":["iot"],"fisic":["iot"],"hardwar":["iot"]},"neuralNetwork":{"settings":{"locale":"pt","tag":"nlu-pt","keepStopwords":true,"nonefeatureValue":1,"nonedeltaMultiplier":1.2,"spellCheck":false,"spellCheckDistance":1,"filterZeros":true,"log":true},"features":["nao","consig","acess","o","sit","a","pagin","carreg","no","naveg","erro","ao","faz","login","sistem","aplic","abre","celul","app","fech","sozinh","problem","na","interfac","do","inicial","falh","aplicaca","web","consum","api","esta","for","ar","tel","fic","em","branc","abrir","entrar","cont","clic","nos","boto","trav","inic","inteligenc","artificial","retorn","respost","errad","model","de","ia","funcion","corret","result","inesper","da","previsa","process","linguag","natural","reconhec","intenca","classificaca","automat","treinament","aprend","incoerent","inferenc","inconsistent","algoritm","com","machin","learning","incorret","analis","text","pel","respond","esper","dashboard","ger","relatori","os","dad","painel","visualizaca","dos","grafic","atualiz","nov","indic","bi","visualiz","atualizaca","apresent","valor","consult","mostr","informaco","desatualiz","rob","execut","taref","automaca","bot","par","execuca","automatiz","durant","mei","workflow","foi","conclu","script","complet","ativ","rod","job","disposit","conect","red","sensor","envi","equip","offlin","comunicaca","aos","comand","aparec","integraca","desconect","frequent","telemetr","cheg","impressor","impressa","imprim","leitor","codig","barr","scann","cam","seguranc","control","catrac","eletron","presenc","detect","moviment","temperatur","terminal","pont","relogi","registr","monitor","conexa","fisic","hardwar"],"intents":["web_app","ai","bi","rpa","iot"],"perceptrons":[[-0.14921583235263824,5.273324012756348,2.4906299114227295,1.6134713888168335,4.712994575500488,3.159592628479004,4.658498287200928,1.8449842929840088,0.17477577924728394,4.238013744354248,-1.1629774570465088,4.097915172576904,3.189331293106079,3.189331293106079,4.449103832244873,4.105490684509277,4.105490684509277,4.105490684509277,5.878068447113037,4.038778305053711,4.038778305053711,1.2920968532562256,1.7312896251678467,5.018344879150391,1.44896399974823,1.3750686645507812,-2.560457468032837,2.0357742309570312,4.734150409698486,3.9288551807403564,3.9288551807403564,-3.6864418983459473,2.6984505653381348,2.6984505653381348,1.3398823738098145,1.3398823738098145,1.3398823738098145,1.3398823738098145,1.3398823738098145,3.5487024784088135,3.5487024784088135,0.8025305271148682,0.8025305271148682,0.8025305271148682,0.6644282341003418,1.702704906463623,-0.7805680632591248,-0.7805680632591248,-0.6089834570884705,-0.7805680632591248,-0.9421440362930298,-4.366415977478027,-4.730751037597656,-1.5331192016601562,-0.37680351734161377,-2.4930801391601562,-1.159929633140564,-0.3557865023612976,-0.49659085273742676,-1.0165188312530518,-2.3957302570343018,-0.6800127029418945,-0.6800127029418945,-0.9282936453819275,-0.9282936453819275,-0.6274884343147278,-0.7893733978271484,-1.2928879261016846,-0.5936872959136963,-0.0555800162255764,-0.3691444396972656,-1.0380382537841797,-0.678411066532135,-1.1480203866958618,-0.024436218664050102,-0.024436218664050102,-0.6140792369842529,-0.10234275460243225,-0.10234275460243225,-1.722013235092163,-0.19019143283367157,-0.05937613546848297,-1.4199830293655396,-1.5127143859863281,-5.748041152954102,-1.5777174234390259,-0.8474184274673462,-1.5182671546936035,-0.7584218382835388,-1.0475817918777466,-2.399486541748047,-0.17535442113876343,-0.17535442113876343,-0.14397764205932617,-1.4393858909606934,-1.5474902391433716,-0.20965832471847534,-0.015624416060745716,-0.015624416060745716,0,-0.05480383709073067,-0.05480383709073067,-0.05480383709073067,-2.462066173553467,-1.3208091259002686,-1.3861135244369507,-1.3381401300430298,-1.1866192817687988,-1.2439533472061157,-2.5494892597198486,-1.017109751701355,-0.005023022182285786,-1.0995404720306396,-0.5274580121040344,-0.028970293700695038,-0.028970293700695038,-2.2439846992492676,-0.6973888874053955,-0.6973888874053955,-1.1724299192428589,-0.2774699628353119,-1.4827083349227905,-1.8302944898605347,-2.237194776535034,0,-1.2439533472061157,-2.071197271347046,-1.9538735151290894,-0.7536646127700806,-0.04002371430397034,-0.04002371430397034,-4.316061496734619,0,0,0,0,0,-2.495983839035034,-1.2439533472061157,-1.5173286199569702,0,0,0,0,-0.7536646127700806,0,0,0,0,0,0,0,0,-1.1090549230575562,-1.1090549230575562,0,0,0,0,0,-2.0965332984924316,0.3270211090084233],[-1.8962663412094116,-0.30147120356559753,-0.5963464379310608,-2.03133225440979,0,2.6419057846069336,-0.26220986247062683,-2.242788791656494,0.40454259514808655,-0.18798738718032837,1.5895370244979858,-3.368509292602539,0,0,-2.170072555541992,0,0,0,-0.4618889391422272,-0.4618889391422272,-0.5266009569168091,0.82444828748703,-0.21350355446338654,-0.5117493271827698,0.6071643233299255,-0.05274036154150963,0.5082144141197205,-0.3032301068305969,-0.43868696689605713,-1.1560360193252563,-1.1560360193252563,2.0293071269989014,-0.10876281559467316,-0.10876281559467316,-0.14480353891849518,-0.14480353891849518,-0.14480353891849518,-0.14480353891849518,-0.14480353891849518,0,0,0,0,0,-0.7852668762207031,-0.31606432795524597,3.1203787326812744,3.1203787326812744,0.036650024354457855,3.1203787326812744,-1.191260814666748,8.329254150390625,1.2408760786056519,4.278331279754639,-2.592327117919922,3.465162754058838,2.502960443496704,-2.730194091796875,0.35204505920410156,3.837385416030884,0.5651035904884338,4.520112037658691,4.520112037658691,1.1635347604751587,1.1635347604751587,6.973221778869629,5.571645259857178,2.655726671218872,2.3534040451049805,3.08499813079834,2.5284411907196045,4.4556498527526855,5.236219882965088,0.8680679798126221,1.808071255683899,1.808071255683899,4.249285697937012,1.977587342262268,1.977587342262268,1.977587342262268,2.5431909561157227,2.957288980484009,-2.603344202041626,-0.5985807180404663,-2.227052688598633,-1.3292773962020874,-4.075083255767822,-3.0258867740631104,-1.129827618598938,-1.0863370895385742,-1.0749304294586182,-0.2338750958442688,-0.2338750958442688,-1.1639357805252075,-0.49001196026802063,-0.30147120356559753,-0.3097720742225647,-1.3278518915176392,-1.3278518915176392,-0.7595250010490417,-0.10345467925071716,-0.10345467925071716,-0.10345467925071716,-2.4568028450012207,-0.7451705932617188,-2.3484084606170654,-2.9925601482391357,-2.074373245239258,-1.499553918838501,-1.9814248085021973,-2.541041612625122,-0.06796713918447495,-0.7852668762207031,-1.1295828819274902,-1.4007441997528076,-1.4007441997528076,-0.7842121720314026,-0.401059627532959,-0.401059627532959,0,-0.9674409627914429,-2.118751049041748,-1.323509931564331,-1.949196457862854,-0.8398855328559875,0,-1.813549280166626,-2.5211567878723145,-2.571044683456421,-0.144606813788414,-0.144606813788414,-0.033998873084783554,-0.12118277698755264,-0.07738962769508362,-0.015564659610390663,0,0,-1.8277132511138916,0,0,-0.15364795923233032,-0.15364795923233032,-0.15364795923233032,0,-2.6815876960754395,-0.2381402552127838,-0.02635272406041622,-0.02056511491537094,-0.02056511491537094,-0.20182208716869354,-0.20182208716869354,-0.20182208716869354,0,0,-0.36266008019447327,-0.36266008019447327,-0.36266008019447327,-0.5743405818939209,0,0,0,1.4510197284699091],[-0.8868489861488342,1.261805534362793,1.9325735569000244,-0.3475830554962158,-2.6877219676971436,-4.602719306945801,-2.2952613830566406,5.074197769165039,-0.9997996687889099,0,1.2277220487594604,2.088965892791748,-0.9424723386764526,-0.9424723386764526,-1.748685598373413,0,0,0,-1.0287436246871948,-0.3390742540359497,-0.3390742540359497,0.9696304798126221,0.4127757251262665,-0.1550855189561844,-4.11455774307251,-2.2952613830566406,-1.497730016708374,-0.1363820731639862,-0.1363820731639862,-0.1693139523267746,-0.1693139523267746,0.11322424560785294,0,0,-0.09654442220926285,-0.09654442220926285,-0.09654442220926285,-0.09654442220926285,-0.09654442220926285,-0.8747757077217102,-0.8747757077217102,-0.5321657061576843,-0.5321657061576843,-0.5321657061576843,-1.0211608409881592,-1.13603937625885,-0.33406054973602295,-0.33406054973602295,-0.13548484444618225,-0.33406054973602295,2.4051363468170166,-1.3057831525802612,1.4302655458450317,-1.0905914306640625,1.5067349672317505,-0.23933860659599304,-0.019344912841916084,0,-0.17086254060268402,-0.45759832859039307,-1.9274191856384277,-0.28878384828567505,-0.28878384828567505,0,0,-0.18642258644104004,-0.7558123469352722,-0.11138638854026794,0,-0.17086254060268402,0,0.43827560544013977,-0.019344912841916084,-1.5453234910964966,-0.8703593611717224,-0.8703593611717224,2.3488450050354004,-0.8497980237007141,-0.8497980237007141,-1.1210581064224243,-0.4776788055896759,0,9.371479034423828,2.3408455848693848,7.9548563957214355,4.249307632446289,6.096655368804932,4.796405792236328,5.17686128616333,2.7207894325256348,4.250263690948486,0.9358253479003906,0.9358253479003906,2.5669124126434326,1.9318581819534302,4.51154088973999,2.9838831424713135,3.129984140396118,3.129984140396118,4.495876312255859,1.362597107887268,1.362597107887268,1.362597107887268,-1.4738961458206177,-0.3157631456851959,-1.0548596382141113,-2.457961082458496,-2.0720088481903076,-1.7100424766540527,-2.009692907333374,-2.2463560104370117,-0.2519288659095764,-0.28334060311317444,-0.9069424271583557,-0.46280375123023987,-0.46280375123023987,-0.7436754703521729,-0.11795124411582947,-0.11795124411582947,-0.7863492965698242,-0.6823368668556213,-2.487663984298706,-1.2492655515670776,-1.4394136667251587,-2.665295124053955,-4.402729511260986,-1.7218363285064697,-1.200035572052002,-0.48736467957496643,-0.07250366359949112,-0.07250366359949112,-0.10959559679031372,-0.3340844213962555,-0.08953452855348587,-0.08953452855348587,-3.7364308834075928,-3.7364308834075928,-0.23170605301856995,-0.1221088245511055,-0.21894937753677368,-0.8564383387565613,-0.8564383387565613,-0.8564383387565613,-1.7858333587646484,-0.08693774044513702,-0.07080657035112381,-0.00818620901554823,-0.7841393947601318,-0.7841393947601318,0,0,0,-0.41724446415901184,-0.15211156010627747,-0.539215087890625,-0.3431954085826874,-0.3431954085826874,-0.16158711910247803,0,0,0,0.8560318064979838],[1.71736478805542,-1.7489374876022339,-0.9856632947921753,-1.8809747695922852,-1.2065633535385132,-0.10717631876468658,-1.3292235136032104,-1.3292235136032104,0.11075399816036224,-0.8413418531417847,1.0496735572814941,-0.8769705295562744,-0.508506178855896,-0.508506178855896,-3.103792428970337,-0.6821404099464417,-0.6821404099464417,-0.6821404099464417,-1.0606868267059326,-0.5588908791542053,-0.5588908791542053,1.405146598815918,-0.7442465424537659,-1.0510131120681763,2.096771001815796,-0.3731639087200165,0.3297342360019684,-0.629461944103241,-0.6353228092193604,-0.7691252827644348,-0.7691252827644348,-0.9537748098373413,-0.001337219262495637,-0.001337219262495637,-0.09587328881025314,-0.09587328881025314,-0.09587328881025314,-0.09587328881025314,-0.09587328881025314,-0.4008009433746338,-0.4008009433746338,-0.9472028017044067,-0.9472028017044067,-0.9472028017044067,0.1469130516052246,0.9028337001800537,-0.21814961731433868,-0.21814961731433868,-0.013787534087896347,-0.21814961731433868,-0.06319299340248108,-3.447995662689209,-2.5434417724609375,-0.6899605393409729,2.85660457611084,-0.6899605393409729,-1.7689006328582764,-0.5411572456359863,-0.9016516804695129,-0.5411572456359863,1.991402268409729,-1.9822440147399902,-1.9822440147399902,0,0,-2.025212049484253,0.6774435043334961,-1.580915093421936,-0.6899605393409729,-0.19828587770462036,-1.1277341842651367,-1.0642286539077759,-1.0642286539077759,-1.7823784351348877,0,0,-0.4236990213394165,0,0,-0.46663013100624084,1.4190744161605835,0,-0.4666794538497925,-0.8043500185012817,-0.8316284418106079,-0.4686487019062042,-2.493044376373291,-0.4236990213394165,-0.9456325769424438,-0.33277058601379395,-0.7976099252700806,0,0,-0.04454421624541283,0,-0.4390985369682312,0,-0.394095778465271,-0.394095778465271,0,-0.40532636642456055,-0.40532636642456055,-0.40532636642456055,5.769073009490967,2.3151235580444336,5.033216953277588,9.15988826751709,9.769220352172852,2.6562511920928955,4.726312637329102,8.256735801696777,-1.307504415512085,0.6421265602111816,3.4631521701812744,2.7168447971343994,2.7168447971343994,5.317729949951172,2.7343552112579346,2.7343552112579346,4.248777866363525,3.3954238891601562,-3.4696993827819824,-1.6429194211959839,-2.340505361557007,-4.304218769073486,-1.1173518896102905,-1.564702033996582,-0.7520742416381836,-1.302178144454956,-1.6054548025131226,-1.6054548025131226,-0.9479285478591919,-0.33816036581993103,-0.04135145619511604,-0.04135145619511604,-0.6418646574020386,-0.6418646574020386,-1.6230847835540771,-0.10522760450839996,-0.46663013100624084,-0.907012403011322,-0.907012403011322,-0.907012403011322,-0.05599546805024147,-0.8834660053253174,-0.22300714254379272,0,-2.5087497234344482,-2.5087497234344482,-0.06675026565790176,-0.06675026565790176,-0.06675026565790176,0,0,0,0,0,0,0,0,-0.018634015694260597,1.4253104044031264],[0.8989097476005554,-1.695504069328308,-0.21535272896289825,-0.6916399002075195,-1.5696724653244019,-0.3702593445777893,-1.7130858898162842,-4.242717742919922,-1.4351056814193726,-4.012387275695801,0.15278850495815277,-1.2594221830368042,-1.1176663637161255,-1.1176663637161255,2.296269178390503,-2.00677227973938,-2.00677227973938,-2.00677227973938,-0.9181512594223022,-0.6625722646713257,-3.0608878135681152,-0.5862056016921997,-1.4905565977096558,-1.1267389059066772,-3.152113199234009,-0.1454721987247467,2.246971368789673,-0.6298316121101379,-1.894837737083435,-0.29488420486450195,-0.29488420486450195,2.172968864440918,-1.2135741710662842,-1.2135741710662842,-0.22090372443199158,-0.22090372443199158,-0.22090372443199158,-0.22090372443199158,-0.22090372443199158,-1.7766047716140747,-1.7766047716140747,0,0,0,-0.15208816528320312,-1.159285068511963,-0.9055042862892151,-0.9055042862892151,-0.8212219476699829,-0.9055042862892151,-1.234468698501587,-5.709412097930908,2.852935791015625,-4.515779972076416,-0.5241464972496033,-3.0921688079833984,-0.03885091096162796,-0.025601346045732498,-0.09295416623353958,-1.7806103229522705,-1.9389369487762451,-0.8811307549476624,-0.8811307549476624,0,0,-1.9504326581954956,-2.282601833343506,0,-0.8024210333824158,-0.048151809722185135,-0.048731479793787,-0.055286955088377,-0.0004488907870836556,3.800156831741333,-0.8414925932884216,-0.8414925932884216,-2.1585404872894287,-1.3667209148406982,-1.3667209148406982,3.664473533630371,1.0772032737731934,-2.4259719848632812,-2.500542163848877,0,-2.442965507507324,-0.9585675597190857,-1.1558746099472046,-0.7699710130691528,-4.655697345733643,-0.8082637190818787,-0.7626203894615173,-2.3635754585266113,-2.3635754585266113,-0.3403661251068115,-0.3408415913581848,-0.5372068881988525,-0.5796148777008057,-0.005538828205317259,-0.005538828205317259,-1.645597219467163,-0.10293855518102646,-0.10293855518102646,-0.10293855518102646,-1.5708125829696655,-0.757127583026886,-1.077669620513916,-4.818539142608643,-6.699202060699463,2.7699098587036133,-0.6583440899848938,-0.9836190938949585,-0.6583440899848938,0,0,-0.28166529536247253,-0.28166529536247253,0,-0.7734033465385437,-0.7734033465385437,-0.13087394833564758,0,6.140957355499268,2.9568991661071777,4.4130682945251465,6.680005073547363,4.441697120666504,5.7440619468688965,3.8459529876708984,2.6725332736968994,2.1264398097991943,2.1264398097991943,5.414166450500488,2.32883620262146,1.8580166101455688,4.139917373657227,4.844059944152832,4.844059944152832,5.934769153594971,0.7481042146682739,5.035163879394531,3.288466453552246,3.288466453552246,3.288466453552246,5.544623374938965,5.092403888702393,0.7160487771034241,2.2056286334991455,4.841739654541016,4.841739654541016,0.6188017129898071,0.6188017129898071,0.6188017129898071,-1.659200668334961,1.261847734451294,3.1854171752929688,1.9188356399536133,1.9188356399536133,-2.3563995361328125,1.102721095085144,1.102721095085144,5.1670403480529785,2.1435356351793255]]}}}}},"intentDomains":{},"extraSentences":[["pt","não consigo acessar o site"],["pt","a página não carrega no navegador"],["pt","erro ao fazer login no sistema"],["pt","o aplicativo não abre no celular"],["pt","app fecha sozinho"],["pt","problema na interface do sistema"],["pt","erro ao carregar a página inicial"],["pt","não consigo navegar no sistema"],["pt","falha ao acessar a aplicação web"],["pt","erro ao consumir a api"],["pt","o sistema web está fora do ar"],["pt","a tela fica em branco ao abrir"],["pt","não consigo entrar na conta"],["pt","problema ao clicar nos botões do site"],["pt","o app trava ao iniciar"],["pt","a inteligência artificial está retornando respostas erradas"],["pt","o modelo de ia não está funcionando corretamente"],["pt","resultado inesperado da previsão do modelo"],["pt","erro no processamento de linguagem natural"],["pt","o modelo não reconhece a intenção corretamente"],["pt","falha na classificação automática"],["pt","problema no treinamento do modelo"],["pt","a ia não está aprendendo corretamente"],["pt","resposta incoerente da inteligência artificial"],["pt","erro na inferência do modelo"],["pt","resultado inconsistente do algoritmo"],["pt","problema com o modelo de machine learning"],["pt","a previsão está incorreta"],["pt","erro na análise de texto pela ia"],["pt","modelo não responde como esperado"],["pt","o dashboard não está carregando"],["pt","erro ao gerar relatório"],["pt","os dados do painel estão incorretos"],["pt","problema na visualização dos gráficos"],["pt","relatório não atualiza com dados novos"],["pt","indicadores estão errados no dashboard"],["pt","falha ao carregar o painel de BI"],["pt","dados inconsistentes no relatório"],["pt","não consigo visualizar os gráficos"],["pt","erro na atualização dos dados"],["pt","painel apresenta valores incorretos"],["pt","problema na consulta de dados"],["pt","dashboard mostra informações desatualizadas"],["pt","erro ao acessar relatórios"],["pt","visualização de dados não funciona"],["pt","o robô não executou a tarefa"],["pt","falha na automação do processo"],["pt","bot parou de funcionar"],["pt","erro na execução do robô"],["pt","processo automatizado não iniciou"],["pt","automação falhou durante execução"],["pt","o bot travou no meio do processo"],["pt","erro no workflow automatizado"],["pt","tarefa automática não foi concluída"],["pt","problema na execução do script"],["pt","robô não completou a atividade"],["pt","falha ao rodar automação"],["pt","erro no job automatizado"],["pt","bot não responde"],["pt","automação não está funcionando"],["pt","o dispositivo não conecta na rede"],["pt","sensor não está enviando dados"],["pt","equipamento está offline"],["pt","falha na comunicação com o dispositivo"],["pt","dispositivo não responde aos comandos"],["pt","equipamento não aparece no sistema"],["pt","falha na integração com o dispositivo"],["pt","sensor parou de funcionar"],["pt","erro na rede de dispositivos"],["pt","dispositivo desconectando frequentemente"],["pt","dados de telemetria não chegam"],["pt","a impressora não conecta na rede"],["pt","impressora não responde aos comandos"],["pt","erro ao enviar impressão para o dispositivo"],["pt","a impressora está offline no sistema"],["pt","não consigo imprimir pela rede"],["pt","o leitor de código de barras não funciona"],["pt","scanner não está enviando dados"],["pt","câmera de segurança não conecta"],["pt","falha na comunicação com a câmera"],["pt","o dispositivo de controle de acesso não responde"],["pt","catraca eletrônica não está funcionando"],["pt","sensor de presença não detecta movimento"],["pt","sensor de temperatura não envia dados"],["pt","terminal de ponto não conecta ao sistema"],["pt","o relógio de ponto não está registrando"],["pt","equipamento de monitoramento está offline"],["pt","falha na conexão com o dispositivo físico"],["pt","o hardware não aparece no sistema"],["pt","dispositivo de rede desconectando sozinho"],["pt","problema com equipamento conectado"]]},"ner":{"settings":{"tag":"ner","entityPreffix":"%","entitySuffix":"%"},"rules":{}},"nlgManager":{"settings":{"tag":"nlg-manager"},"responses":{}},"actionManager":{"settings":{"tag":"action-manager"},"actions":{}},"slotManager":{}} \ No newline at end of file diff --git a/backend/src/modules/ticket/presentation/controllers/ticket.controller.spec.ts b/backend/src/modules/ticket/presentation/controllers/ticket.controller.spec.ts index 31c9882..a24ea29 100644 --- a/backend/src/modules/ticket/presentation/controllers/ticket.controller.spec.ts +++ b/backend/src/modules/ticket/presentation/controllers/ticket.controller.spec.ts @@ -10,12 +10,11 @@ import { ReadByIdTicketUseCase } from '../../application/useCases/readById/readB import { TicketController } from './ticket.controller'; import { DeleteTicketUseCase } from '../../application/useCases/delete/delete.usecase'; import { INestApplication, ValidationPipe } from '@nestjs/common'; -import { - Ticket, - TicketStatus, -} from '../../domain/entities/ticket.entity'; +import { Ticket, TicketStatus } from '../../domain/entities/ticket.entity'; import { randomUUID } from 'crypto'; import request from 'supertest'; +import { JwtGuard } from '../../../auth/guards/jwt.guard'; +import { RolesGuard } from '../../../auth/guards/roles.guard'; describe('TicketController', () => { let app: INestApplication; @@ -70,7 +69,12 @@ describe('TicketController', () => { useValue: { execute: jest.fn() }, }, ], - }).compile(); + }) + .overrideGuard(JwtGuard) + .useValue({ canActivate: () => true }) + .overrideGuard(RolesGuard) + .useValue({ canActivate: () => true }) + .compile(); app = modulesFixture.createNestApplication(); await app.init(); diff --git a/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts b/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts index 1de5518..5ba6f0b 100644 --- a/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts +++ b/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts @@ -60,6 +60,8 @@ export class TicketController { @Get() @ApiOperation({ summary: 'Retorna todos os tickets' }) + @UseGuards(JwtGuard, RolesGuard) + @Roles(UserRole.ADMIN) @ApiResponse({ status: 200, description: 'Todos os tickets retornados com sucesso.', @@ -73,6 +75,8 @@ export class TicketController { @Get(':id') @ApiOperation({ summary: 'Retorna um ticket pelo ID' }) @ApiParam({ name: 'id', example: 'uuid-do-ticket' }) + @UseGuards(JwtGuard, RolesGuard) + @Roles(UserRole.ADMIN, UserRole.SUPPORT, UserRole.CLIENT) @ApiResponse({ status: 200, description: 'Ticket encontrado com sucesso.' }) async getById(@Param('id') id: string) { const response = await this.readByIdUseCase.execute(id); @@ -83,6 +87,8 @@ export class TicketController { @Get(':id/history') @ApiOperation({ summary: 'Retorna o histórico de um ticket pelo ID' }) @ApiParam({ name: 'id', example: 'uuid-do-ticket' }) + @UseGuards(JwtGuard, RolesGuard) + @Roles(UserRole.ADMIN, UserRole.SUPPORT, UserRole.CLIENT) @ApiResponse({ status: 200, description: 'Histórico retornado com sucesso.' }) async getHistoryById(@Param('id') id: string) { const response = await this.getHistoryUseCase.execute(id); @@ -94,6 +100,8 @@ export class TicketController { @ApiOperation({ summary: 'Escalona um ticket' }) @ApiParam({ name: 'id', example: 'uuid-do-ticket' }) @ApiBody({ type: EscalateTicketRequest }) + @UseGuards(JwtGuard, RolesGuard) + @Roles(UserRole.ADMIN, UserRole.SUPPORT) @ApiResponse({ status: 200, description: 'Ticket escalonado com sucesso.' }) async escalateTicket( @Param('id') id: string, @@ -110,6 +118,8 @@ export class TicketController { @ApiOperation({ summary: 'Atribui um agente ao ticket' }) @ApiParam({ name: 'id', example: 'uuid-do-ticket' }) @ApiBody({ type: AssignAgentRequest }) + @UseGuards(JwtGuard, RolesGuard) + @Roles(UserRole.ADMIN, UserRole.SUPPORT) @ApiResponse({ status: 200, description: 'Agente atribuído com sucesso.' }) async assignAgent(@Param('id') id: string, @Body() body: AssignAgentRequest) { const data = TicketMapper.toNewAgentInput(id, body); @@ -122,6 +132,8 @@ export class TicketController { @Delete(':id') @ApiOperation({ summary: 'Remove um ticket' }) @ApiParam({ name: 'id', example: 'uuid-do-ticket' }) + @UseGuards(JwtGuard, RolesGuard) + @Roles(UserRole.ADMIN) @ApiResponse({ status: 200, description: 'Ticket removido com sucesso.' }) async delete(@Param() id: string) { const response = await this.deleteUseCase.execute(id); diff --git a/backend/src/modules/user/user.schema.ts b/backend/src/modules/user/user.schema.ts index 601d675..1ea9508 100644 --- a/backend/src/modules/user/user.schema.ts +++ b/backend/src/modules/user/user.schema.ts @@ -18,6 +18,7 @@ export class User { password: string; @Prop({ + type: String, required: true, enum: UserRole, default: UserRole.CLIENT, From e828faba28123beacf461f8c72bcfbe1afeb2144 Mon Sep 17 00:00:00 2001 From: YgorPereira Date: Thu, 23 Apr 2026 21:25:27 -0300 Subject: [PATCH 03/11] feat: add read by clientId to tickets Co-authored-by: Copilot --- .../useCases/readAll/readAll.usecase.spec.ts | 24 +++++++++++++- .../useCases/readAll/readAll.usecase.ts | 11 +++++-- .../ticket.mongodb.repository.int.spec.ts | 32 +++++++++++++++++++ .../repository/ticket.repository.interface.ts | 2 +- .../repositories/ticket.mongodb.repository.ts | 5 ++- 5 files changed, 67 insertions(+), 7 deletions(-) diff --git a/backend/src/modules/ticket/application/useCases/readAll/readAll.usecase.spec.ts b/backend/src/modules/ticket/application/useCases/readAll/readAll.usecase.spec.ts index 3e88dae..e066f4b 100644 --- a/backend/src/modules/ticket/application/useCases/readAll/readAll.usecase.spec.ts +++ b/backend/src/modules/ticket/application/useCases/readAll/readAll.usecase.spec.ts @@ -3,6 +3,7 @@ import { randomUUID } from 'crypto'; import { ITicketRepository } from '../../../domain/repository/ticket.repository.interface'; import { Ticket } from '../../../domain/entities/ticket.entity'; import { ReadAllTicketUseCase } from './readAll.usecase'; +import { UserRole } from '../../../../shared/enums/user.enum'; describe('ReadAllTicketUseCase', () => { let repository: jest.Mocked; @@ -27,7 +28,10 @@ describe('ReadAllTicketUseCase', () => { it('should read all ticket successfully', async () => { repository.readAll.mockResolvedValue([ticket]); - const output = await useCase.execute(); + const output = await useCase.execute({ + userId: randomUUID(), + role: UserRole.SUPPORT, + }); expect(output).toBeDefined(); expect(Array.isArray(output)).toBe(true); @@ -39,4 +43,22 @@ describe('ReadAllTicketUseCase', () => { expect(output).not.toHaveProperty('escalate'); expect(output).not.toHaveProperty('assignToAgent'); }); + + it('should read all tickets with clientId filter', async () => { + repository.readAll.mockResolvedValue([ticket]); + const output = await useCase.execute({ + userId: ticket.clientId, + role: UserRole.CLIENT, + }); + expect(output).toBeDefined(); + expect(Array.isArray(output)).toBe(true); + expect(output[0].clientId).toBe(ticket.clientId); + expect(repository.readAll).toHaveBeenCalledWith({ + clientId: ticket.clientId, + }); + + expect(output).not.toHaveProperty('toPrimitives'); + expect(output).not.toHaveProperty('escalate'); + expect(output).not.toHaveProperty('assignToAgent'); + }); }); diff --git a/backend/src/modules/ticket/application/useCases/readAll/readAll.usecase.ts b/backend/src/modules/ticket/application/useCases/readAll/readAll.usecase.ts index 7216da6..7fa6926 100644 --- a/backend/src/modules/ticket/application/useCases/readAll/readAll.usecase.ts +++ b/backend/src/modules/ticket/application/useCases/readAll/readAll.usecase.ts @@ -5,6 +5,7 @@ import { TicketStatus, } from '../../../domain/entities/ticket.entity'; import { ITicketRepository } from '../../../domain/repository/ticket.repository.interface'; +import { UserRole } from '../../../../shared/enums/user.enum'; export interface ReadAllTicketOutput { id: string; @@ -26,8 +27,14 @@ export interface ReadAllTicketOutput { export class ReadAllTicketUseCase { constructor(private readonly repository: ITicketRepository) {} - async execute(): Promise { - const foundedTickets = await this.repository.readAll(); + async execute(input: { + userId: string; + role: UserRole; + }): Promise { + const filters = + input.role === UserRole.CLIENT ? { clientId: input.userId } : undefined; + + const foundedTickets = await this.repository.readAll({ ...filters }); const convertedTickets = foundedTickets.map((t: Ticket) => { const primitive = t.toPrimitives(); diff --git a/backend/src/modules/ticket/domain/repository/ticket.mongodb.repository.int.spec.ts b/backend/src/modules/ticket/domain/repository/ticket.mongodb.repository.int.spec.ts index 400fa32..9e10716 100644 --- a/backend/src/modules/ticket/domain/repository/ticket.mongodb.repository.int.spec.ts +++ b/backend/src/modules/ticket/domain/repository/ticket.mongodb.repository.int.spec.ts @@ -191,4 +191,36 @@ describe('ITicketRepository', () => { const deleteResult = await repository.delete(randomUUID()); expect(deleteResult).toBe(false); }); + + it('Should read all tickets by clientId successfully', async () => { + const clientId = randomUUID(); + + const ticket1 = Ticket.create({ + title: 'chamado 6', + category: 'bi', + description: 'descricao do chamado 6', + clientId, + }); + + const ticket2 = Ticket.create({ + title: 'chamado 7', + category: 'bi', + description: 'descricao do chamado 7', + clientId, + }); + + await repository.create(ticket1); + await repository.create(ticket2); + + const resultReadAll = await repository.readAll({ clientId }); + expect(resultReadAll).toBeDefined(); + expect(Array.isArray(resultReadAll)).toBe(true); + expect(resultReadAll.length).toBe(2); + resultReadAll.map((t) => expect(t).toBeInstanceOf(Ticket)); + + const resultReadAllWithAnotherClientId = await repository.readAll({ clientId: randomUUID() }); + expect(resultReadAllWithAnotherClientId).toBeDefined(); + expect(Array.isArray(resultReadAllWithAnotherClientId)).toBe(true); + expect(resultReadAllWithAnotherClientId.length).toBe(0); + }); }); diff --git a/backend/src/modules/ticket/domain/repository/ticket.repository.interface.ts b/backend/src/modules/ticket/domain/repository/ticket.repository.interface.ts index ca77f65..3cf2896 100644 --- a/backend/src/modules/ticket/domain/repository/ticket.repository.interface.ts +++ b/backend/src/modules/ticket/domain/repository/ticket.repository.interface.ts @@ -5,7 +5,7 @@ import { Ticket } from '../entities/ticket.entity'; export abstract class ITicketRepository { abstract create(ticket: Ticket): Promise; abstract save(ticket: Ticket): Promise; - abstract readAll(filter?: any): Promise; + abstract readAll(filters?: { clientId?: string }): Promise; abstract readById(id: string): Promise; abstract delete(id: string): Promise; } diff --git a/backend/src/modules/ticket/infra/repositories/ticket.mongodb.repository.ts b/backend/src/modules/ticket/infra/repositories/ticket.mongodb.repository.ts index 8276cb6..59f7e47 100644 --- a/backend/src/modules/ticket/infra/repositories/ticket.mongodb.repository.ts +++ b/backend/src/modules/ticket/infra/repositories/ticket.mongodb.repository.ts @@ -38,9 +38,8 @@ export class TicketMongoRepository extends ITicketRepository { return TicketMapper.toDomain(updated); } - async readAll(): Promise { - // eslint-disable-next-line @typescript-eslint/no-unsafe-argument - const tickets = await this.ticketModel.find(); + async readAll(filters?: { clientId: string }): Promise { + const tickets = await this.ticketModel.find(filters).exec(); const mappedTickets = tickets.map((t) => TicketMapper.toDomain(t)); return mappedTickets; } From 625b2c04dfa00e16eaa49060e2f6c7e628f80919 Mon Sep 17 00:00:00 2001 From: YgorPereira Date: Sat, 25 Apr 2026 21:04:55 -0300 Subject: [PATCH 04/11] feat: add filter to client role in list tickets Co-authored-by: Copilot --- .../presentation/controllers/ticket.controller.ts | 14 +++++++++++--- .../modules/ticket/presentation/dtos/create.dto.ts | 12 ++++++++++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts b/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts index 5ba6f0b..76d65d9 100644 --- a/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts +++ b/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ import { Body, Controller, @@ -6,6 +8,7 @@ import { Param, Post, Put, + Request, UseGuards, } from '@nestjs/common'; import { CreateTicketUseCase } from '../../application/useCases/create/create.usecase'; @@ -20,6 +23,7 @@ import { EscalateTicketRequest } from '../dtos/escalateTicket.dto'; import { TicketMapper } from '../mappers/ticket.mapper'; import { AssignAgentRequest } from '../dtos/assignAgent.dto'; import { + ApiBearerAuth, ApiBody, ApiOperation, ApiParam, @@ -33,6 +37,7 @@ import { UserRole } from '../../../shared/enums/user.enum'; @ApiTags('Ticket') @Controller('tickets') +@ApiBearerAuth() export class TicketController { constructor( private readonly createUseCase: CreateTicketUseCase, @@ -61,13 +66,16 @@ export class TicketController { @Get() @ApiOperation({ summary: 'Retorna todos os tickets' }) @UseGuards(JwtGuard, RolesGuard) - @Roles(UserRole.ADMIN) + @Roles(UserRole.ADMIN, UserRole.SUPPORT, UserRole.CLIENT) @ApiResponse({ status: 200, description: 'Todos os tickets retornados com sucesso.', }) - async getAll() { - const response = await this.readAllUseCase.execute(); + async getAll(@Request() req: any) { + const response = await this.readAllUseCase.execute({ + userId: req.user.id, + role: req.user.role, + }); return response; } diff --git a/backend/src/modules/ticket/presentation/dtos/create.dto.ts b/backend/src/modules/ticket/presentation/dtos/create.dto.ts index bfac97c..fecc973 100644 --- a/backend/src/modules/ticket/presentation/dtos/create.dto.ts +++ b/backend/src/modules/ticket/presentation/dtos/create.dto.ts @@ -1,4 +1,12 @@ -import { IsNotEmpty, IsNumber, IsOptional, IsString, Max, Min, IsUUID } from 'class-validator'; +import { + IsMongoId, + IsNotEmpty, + IsNumber, + IsOptional, + IsString, + Max, + Min, +} from 'class-validator'; import { ApiProperty } from '@nestjs/swagger'; export class CreateTicketRequest { @@ -16,7 +24,7 @@ export class CreateTicketRequest { @ApiProperty({ example: 'uuid-do-cliente', description: 'ID do cliente' }) @IsString() @IsNotEmpty() - @IsUUID() + @IsMongoId() clientId!: string; @ApiProperty({ example: 1, description: 'Nível do chamado (1 a 3)' }) From 9b9ce0c9e6d6da40a31727527a6de3915c92d9a9 Mon Sep 17 00:00:00 2001 From: YgorPereira Date: Sun, 26 Apr 2026 02:05:43 -0300 Subject: [PATCH 05/11] feat: repository get all for support filter by category and agentId Co-authored-by: Copilot --- backend/package-lock.json | 8 ++ backend/package.json | 1 + .../useCases/readAll/readAll.usecase.spec.ts | 55 +++++++++++++ .../useCases/readAll/readAll.usecase.ts | 7 +- .../ticket.mongodb.repository.int.spec.ts | 78 ++++++++++++++++--- .../repository/ticket.repository.interface.ts | 6 +- .../repositories/ticket.mongodb.repository.ts | 26 +++++-- .../infra/schemas/ticket.mongo.schema.ts | 5 +- .../controllers/ticket.controller.ts | 2 + backend/src/modules/user/user.schema.ts | 2 +- 10 files changed, 169 insertions(+), 21 deletions(-) diff --git a/backend/package-lock.json b/backend/package-lock.json index bbc0914..96f3896 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -41,6 +41,7 @@ "@nestjs/testing": "^11.0.1", "@types/express": "^5.0.0", "@types/jest": "^30.0.0", + "@types/mocha": "^10.0.10", "@types/morgan": "^1.9.10", "@types/multer": "^2.1.0", "@types/node": "^22.10.7", @@ -3772,6 +3773,13 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/mocha": { + "version": "10.0.10", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", + "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/morgan": { "version": "1.9.10", "resolved": "https://registry.npmjs.org/@types/morgan/-/morgan-1.9.10.tgz", diff --git a/backend/package.json b/backend/package.json index 6036c9f..22833fe 100644 --- a/backend/package.json +++ b/backend/package.json @@ -53,6 +53,7 @@ "@nestjs/testing": "^11.0.1", "@types/express": "^5.0.0", "@types/jest": "^30.0.0", + "@types/mocha": "^10.0.10", "@types/morgan": "^1.9.10", "@types/multer": "^2.1.0", "@types/node": "^22.10.7", diff --git a/backend/src/modules/ticket/application/useCases/readAll/readAll.usecase.spec.ts b/backend/src/modules/ticket/application/useCases/readAll/readAll.usecase.spec.ts index e066f4b..527c1f3 100644 --- a/backend/src/modules/ticket/application/useCases/readAll/readAll.usecase.spec.ts +++ b/backend/src/modules/ticket/application/useCases/readAll/readAll.usecase.spec.ts @@ -1,4 +1,5 @@ /* eslint-disable @typescript-eslint/unbound-method */ +import { describe, expect, it, beforeEach, jest } from '@jest/globals'; import { randomUUID } from 'crypto'; import { ITicketRepository } from '../../../domain/repository/ticket.repository.interface'; import { Ticket } from '../../../domain/entities/ticket.entity'; @@ -61,4 +62,58 @@ describe('ReadAllTicketUseCase', () => { expect(output).not.toHaveProperty('escalate'); expect(output).not.toHaveProperty('assignToAgent'); }); + + it('should read all tickets associated to the support agent or unassigned in their group', async () => { + const supId = randomUUID(); + const groupId = randomUUID(); + const categoryId = randomUUID(); + + const ticketAssignedToAgent = Ticket.create({ + title: 'ticket atribuído ao agente', + category: categoryId, + description: 'descricao', + clientId: randomUUID(), + }); + ticketAssignedToAgent.assignToAgent(supId); + + const ticketUnassignedInGroup = Ticket.create({ + title: 'ticket sem agente no grupo', + category: categoryId, + description: 'descricao', + clientId: randomUUID(), + }); + + const ticketOtherAgent = Ticket.create({ + title: 'ticket de outro agente', + category: categoryId, + description: 'descricao', + clientId: randomUUID(), + }); + ticketOtherAgent.assignToAgent(randomUUID()); + + repository.readAll.mockResolvedValue([ + ticketAssignedToAgent, + ticketUnassignedInGroup, + ]); + + const output = await useCase.execute({ + userId: supId, + groupId: groupId, + role: UserRole.SUPPORT, + }); + + expect(output).toBeDefined(); + expect(Array.isArray(output)).toBe(true); + expect(output).toHaveLength(2); + + expect(repository.readAll).toHaveBeenCalledWith({ + agentId: supId, + groupId: groupId, + }); + + // Garante que retornou primitivos, não instâncias do domínio + expect(output[0]).not.toHaveProperty('toPrimitives'); + expect(output[0]).not.toHaveProperty('escalate'); + expect(output[0]).not.toHaveProperty('assignToAgent'); + }); }); diff --git a/backend/src/modules/ticket/application/useCases/readAll/readAll.usecase.ts b/backend/src/modules/ticket/application/useCases/readAll/readAll.usecase.ts index 7fa6926..3a96e82 100644 --- a/backend/src/modules/ticket/application/useCases/readAll/readAll.usecase.ts +++ b/backend/src/modules/ticket/application/useCases/readAll/readAll.usecase.ts @@ -29,10 +29,15 @@ export class ReadAllTicketUseCase { async execute(input: { userId: string; + groupId?: string; role: UserRole; }): Promise { const filters = - input.role === UserRole.CLIENT ? { clientId: input.userId } : undefined; + input.role === UserRole.CLIENT + ? { clientId: input.userId } + : input.role === UserRole.SUPPORT + ? { agentId: input.userId, groupId: input.groupId } + : undefined; const foundedTickets = await this.repository.readAll({ ...filters }); diff --git a/backend/src/modules/ticket/domain/repository/ticket.mongodb.repository.int.spec.ts b/backend/src/modules/ticket/domain/repository/ticket.mongodb.repository.int.spec.ts index 9e10716..d08ab29 100644 --- a/backend/src/modules/ticket/domain/repository/ticket.mongodb.repository.int.spec.ts +++ b/backend/src/modules/ticket/domain/repository/ticket.mongodb.repository.int.spec.ts @@ -1,3 +1,11 @@ +import { + describe, + it, + expect, + beforeAll, + afterAll, + afterEach, +} from '@jest/globals'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { getConnectionToken, MongooseModule } from '@nestjs/mongoose'; import { Test, TestingModule } from '@nestjs/testing'; @@ -59,7 +67,7 @@ describe('ITicketRepository', () => { it('Should Create a ticket successfully', async () => { const ticketToCreate = Ticket.create({ title: 'chamado 1', - category: 'ia', + category: randomUUID(), description: 'descricao do chamado 1', clientId: randomUUID(), }); @@ -83,7 +91,7 @@ describe('ITicketRepository', () => { it('Should read all successfully', async () => { const ticketToCreate = Ticket.create({ title: 'chamado 2', - category: 'bi', + category: randomUUID(), description: 'descricao do chamado 2', clientId: randomUUID(), }); @@ -100,9 +108,11 @@ describe('ITicketRepository', () => { }); it('Should read a ticket by id successfully', async () => { + const categoryId = randomUUID(); + const ticketToCreate = Ticket.create({ title: 'chamado 3', - category: 'bi', + category: categoryId, description: 'descricao do chamado 3', clientId: randomUUID(), }); @@ -117,7 +127,7 @@ describe('ITicketRepository', () => { const primitiveResult = resultById?.toPrimitives(); expect(primitiveResult?.title).toBe('chamado 3'); - expect(primitiveResult?.category).toBe('bi'); + expect(primitiveResult?.category).toBe(categoryId); expect(primitiveResult?.priority).toBe(TicketPriority.LOW); expect(primitiveResult?.description).toBe('descricao do chamado 3'); }); @@ -130,7 +140,7 @@ describe('ITicketRepository', () => { it('Should Save a ticket successfully', async () => { const ticketToCreate = Ticket.create({ title: 'chamado 5', - category: 'bi', + category: randomUUID(), description: 'descricao do chamado 5', clientId: randomUUID(), }); @@ -154,7 +164,7 @@ describe('ITicketRepository', () => { it('Should return null when try to save a non-existent ticket', async () => { const ticket = Ticket.create({ title: 'chamado 5', - category: 'bi', + category: randomUUID(), description: 'descricao do chamado 5', clientId: randomUUID(), }); @@ -169,7 +179,7 @@ describe('ITicketRepository', () => { it('Should delete a ticket by id successfully', async () => { const ticketToCreate = Ticket.create({ title: 'chamado 5', - category: 'bi', + category: randomUUID(), description: 'descricao do chamado 5', clientId: randomUUID(), }); @@ -188,7 +198,7 @@ describe('ITicketRepository', () => { }); it('Should return false when try to delete a non-existent ticket', async () => { - const deleteResult = await repository.delete(randomUUID()); + const deleteResult = await repository.delete(randomUUID()); expect(deleteResult).toBe(false); }); @@ -197,14 +207,14 @@ describe('ITicketRepository', () => { const ticket1 = Ticket.create({ title: 'chamado 6', - category: 'bi', + category: randomUUID(), description: 'descricao do chamado 6', clientId, }); const ticket2 = Ticket.create({ title: 'chamado 7', - category: 'bi', + category: randomUUID(), description: 'descricao do chamado 7', clientId, }); @@ -218,9 +228,55 @@ describe('ITicketRepository', () => { expect(resultReadAll.length).toBe(2); resultReadAll.map((t) => expect(t).toBeInstanceOf(Ticket)); - const resultReadAllWithAnotherClientId = await repository.readAll({ clientId: randomUUID() }); + const resultReadAllWithAnotherClientId = await repository.readAll({ + clientId: randomUUID(), + }); expect(resultReadAllWithAnotherClientId).toBeDefined(); expect(Array.isArray(resultReadAllWithAnotherClientId)).toBe(true); expect(resultReadAllWithAnotherClientId.length).toBe(0); }); + + it('should read all tickets by agentId or unassigned tickets in the same group', async () => { + const agentId = randomUUID(); + const categoryId = randomUUID(); + + const ticket1 = Ticket.create({ + title: 'chamado 1', + category: categoryId, + description: 'atribuído ao agente', + clientId: randomUUID(), + }); + ticket1.assignToAgent(agentId); + + const ticket2 = Ticket.create({ + title: 'chamado 2', + category: categoryId, + description: 'sem agente no grupo', + clientId: randomUUID(), + }); + + const ticket3 = Ticket.create({ + title: 'chamado 3', + category: categoryId, + description: 'outro agente atribuído', + clientId: randomUUID(), + }); + ticket3.assignToAgent(randomUUID()); + + await repository.create(ticket1); + await repository.create(ticket2); + await repository.create(ticket3); + + const result = await repository.readAll({ agentId, categoryId }); + + expect(result).toBeDefined(); + expect(Array.isArray(result)).toBe(true); + expect(result.length).toBe(2); + result.forEach((t) => expect(t).toBeInstanceOf(Ticket)); + + const ids = result.map((t) => t.id); + expect(ids).toContain(ticket1.id); + expect(ids).toContain(ticket2.id); + expect(ids).not.toContain(ticket3.id); + }); }); diff --git a/backend/src/modules/ticket/domain/repository/ticket.repository.interface.ts b/backend/src/modules/ticket/domain/repository/ticket.repository.interface.ts index 3cf2896..7bbd220 100644 --- a/backend/src/modules/ticket/domain/repository/ticket.repository.interface.ts +++ b/backend/src/modules/ticket/domain/repository/ticket.repository.interface.ts @@ -5,7 +5,11 @@ import { Ticket } from '../entities/ticket.entity'; export abstract class ITicketRepository { abstract create(ticket: Ticket): Promise; abstract save(ticket: Ticket): Promise; - abstract readAll(filters?: { clientId?: string }): Promise; + abstract readAll(filters?: { + clientId?: string; + agentId?: string; + categoryId?: string; + }): Promise; abstract readById(id: string): Promise; abstract delete(id: string): Promise; } diff --git a/backend/src/modules/ticket/infra/repositories/ticket.mongodb.repository.ts b/backend/src/modules/ticket/infra/repositories/ticket.mongodb.repository.ts index 59f7e47..edfb412 100644 --- a/backend/src/modules/ticket/infra/repositories/ticket.mongodb.repository.ts +++ b/backend/src/modules/ticket/infra/repositories/ticket.mongodb.repository.ts @@ -1,4 +1,4 @@ -import { Model } from 'mongoose'; +import { Model, QueryFilter } from 'mongoose'; import { Ticket } from '../../domain/entities/ticket.entity'; import { ITicketRepository } from '../../domain/repository/ticket.repository.interface'; import { TicketLean, TicketSchemaClass } from '../schemas/ticket.mongo.schema'; @@ -38,10 +38,26 @@ export class TicketMongoRepository extends ITicketRepository { return TicketMapper.toDomain(updated); } - async readAll(filters?: { clientId: string }): Promise { - const tickets = await this.ticketModel.find(filters).exec(); - const mappedTickets = tickets.map((t) => TicketMapper.toDomain(t)); - return mappedTickets; + async readAll(filters?: { + clientId?: string; + agentId?: string; + categoryId?: string; + }): Promise { + let query: QueryFilter = {}; + + if (filters?.agentId) { + query = { + $or: [ + { agentId: filters.agentId }, + { category: filters.categoryId, agentId: null }, + ], + }; + } else if (filters?.clientId) { + query = { clientId: filters.clientId }; + } + + const tickets = await this.ticketModel.find(query).exec(); + return tickets.map((t) => TicketMapper.toDomain(t)); } async readById(id: string): Promise { diff --git a/backend/src/modules/ticket/infra/schemas/ticket.mongo.schema.ts b/backend/src/modules/ticket/infra/schemas/ticket.mongo.schema.ts index caf75e2..d3fb096 100644 --- a/backend/src/modules/ticket/infra/schemas/ticket.mongo.schema.ts +++ b/backend/src/modules/ticket/infra/schemas/ticket.mongo.schema.ts @@ -1,5 +1,5 @@ import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; -import { HydratedDocument, Document } from 'mongoose'; +import { HydratedDocument, Types } from 'mongoose'; import { TicketEventMessage, @@ -7,6 +7,7 @@ import { TicketPriority, TicketStatus, } from '../../domain/entities/ticket.entity'; +import { Category } from '../../../category/category.schema'; @Schema({ _id: false }) export class TicketHistoryEntrySchema { @@ -44,7 +45,7 @@ export class TicketSchemaClass { @Prop({ required: true }) description: string; - @Prop({ required: true }) + @Prop({ type: String, required: true }) category: string; @Prop({ required: true, enum: Object.values(TicketPriority) }) diff --git a/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts b/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts index 76d65d9..40c7d29 100644 --- a/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts +++ b/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts @@ -56,6 +56,8 @@ export class TicketController { @Roles(UserRole.CLIENT) @ApiResponse({ status: 201, description: 'Ticket criado com sucesso.' }) async create(@Body() body: CreateTicketRequest) { + // TODO: Enviar id automatica do cliente pelo token, não deixar o cliente enviar o id no body+ + const data = TicketMapper.toCreateInput(body); const response = await this.createUseCase.execute(data); diff --git a/backend/src/modules/user/user.schema.ts b/backend/src/modules/user/user.schema.ts index 1924eb0..b4b2576 100644 --- a/backend/src/modules/user/user.schema.ts +++ b/backend/src/modules/user/user.schema.ts @@ -27,7 +27,7 @@ export class User { @Prop({ required: false, - default: 1 + default: 1, }) level: number; From 21c1fd3ef741a279730ce21a9ebb447373b481bc Mon Sep 17 00:00:00 2001 From: YgorPereira Date: Sun, 26 Apr 2026 16:48:15 -0300 Subject: [PATCH 06/11] fix: fix categories filter to support --- backend/src/modules/auth/auth.service.ts | 1 + .../src/modules/auth/guards/jwt.strategy.ts | 1 + .../useCases/readAll/readAll.usecase.spec.ts | 13 ++- .../useCases/readAll/readAll.usecase.ts | 6 +- .../repositories/ticket.mongodb.repository.ts | 4 +- .../infra/schemas/ticket.mongo.schema.ts | 3 +- .../controllers/ticket.controller.spec.ts | 94 ++++++++++++++++++- .../controllers/ticket.controller.ts | 1 + .../presentation/dtos/assignAgent.dto.ts | 4 +- 9 files changed, 107 insertions(+), 20 deletions(-) diff --git a/backend/src/modules/auth/auth.service.ts b/backend/src/modules/auth/auth.service.ts index dca36d6..5d5e6de 100644 --- a/backend/src/modules/auth/auth.service.ts +++ b/backend/src/modules/auth/auth.service.ts @@ -85,6 +85,7 @@ export class AuthService { sub: user.id, email: user.email, role: user.role, + categories: user.categories ?? undefined, }); return { token: jwt }; } diff --git a/backend/src/modules/auth/guards/jwt.strategy.ts b/backend/src/modules/auth/guards/jwt.strategy.ts index a427243..1dec8bd 100644 --- a/backend/src/modules/auth/guards/jwt.strategy.ts +++ b/backend/src/modules/auth/guards/jwt.strategy.ts @@ -17,6 +17,7 @@ export class JwtStrategy extends PassportStrategy(Strategy) { id: payload.sub, email: payload.email, role: payload.role, + categories: (payload.categories ?? undefined).map((c) => c.id), }; } } diff --git a/backend/src/modules/ticket/application/useCases/readAll/readAll.usecase.spec.ts b/backend/src/modules/ticket/application/useCases/readAll/readAll.usecase.spec.ts index 527c1f3..e8b0543 100644 --- a/backend/src/modules/ticket/application/useCases/readAll/readAll.usecase.spec.ts +++ b/backend/src/modules/ticket/application/useCases/readAll/readAll.usecase.spec.ts @@ -65,12 +65,11 @@ describe('ReadAllTicketUseCase', () => { it('should read all tickets associated to the support agent or unassigned in their group', async () => { const supId = randomUUID(); - const groupId = randomUUID(); - const categoryId = randomUUID(); + const categories = [randomUUID()]; const ticketAssignedToAgent = Ticket.create({ title: 'ticket atribuído ao agente', - category: categoryId, + category: categories[0], description: 'descricao', clientId: randomUUID(), }); @@ -78,14 +77,14 @@ describe('ReadAllTicketUseCase', () => { const ticketUnassignedInGroup = Ticket.create({ title: 'ticket sem agente no grupo', - category: categoryId, + category: randomUUID(), description: 'descricao', clientId: randomUUID(), }); const ticketOtherAgent = Ticket.create({ title: 'ticket de outro agente', - category: categoryId, + category: categories[0], description: 'descricao', clientId: randomUUID(), }); @@ -98,7 +97,7 @@ describe('ReadAllTicketUseCase', () => { const output = await useCase.execute({ userId: supId, - groupId: groupId, + categories: categories, role: UserRole.SUPPORT, }); @@ -108,7 +107,7 @@ describe('ReadAllTicketUseCase', () => { expect(repository.readAll).toHaveBeenCalledWith({ agentId: supId, - groupId: groupId, + categories: categories, }); // Garante que retornou primitivos, não instâncias do domínio diff --git a/backend/src/modules/ticket/application/useCases/readAll/readAll.usecase.ts b/backend/src/modules/ticket/application/useCases/readAll/readAll.usecase.ts index 3a96e82..8462df7 100644 --- a/backend/src/modules/ticket/application/useCases/readAll/readAll.usecase.ts +++ b/backend/src/modules/ticket/application/useCases/readAll/readAll.usecase.ts @@ -16,7 +16,6 @@ export interface ReadAllTicketOutput { clientId: string; status: TicketStatus; agentId: string | null; - groupId: string | null; escalationLevel: number; createdAt: Date; updatedAt: Date | null; @@ -29,14 +28,14 @@ export class ReadAllTicketUseCase { async execute(input: { userId: string; - groupId?: string; + categories?: string[]; role: UserRole; }): Promise { const filters = input.role === UserRole.CLIENT ? { clientId: input.userId } : input.role === UserRole.SUPPORT - ? { agentId: input.userId, groupId: input.groupId } + ? { agentId: input.userId, categories: input.categories } : undefined; const foundedTickets = await this.repository.readAll({ ...filters }); @@ -53,7 +52,6 @@ export class ReadAllTicketUseCase { clientId: primitive.clientId, status: primitive.status, agentId: primitive.agentId, - groupId: primitive.groupId, escalationLevel: primitive.escalationLevel, createdAt: primitive.createdAt, updatedAt: primitive.updatedAt, diff --git a/backend/src/modules/ticket/infra/repositories/ticket.mongodb.repository.ts b/backend/src/modules/ticket/infra/repositories/ticket.mongodb.repository.ts index edfb412..bdf6325 100644 --- a/backend/src/modules/ticket/infra/repositories/ticket.mongodb.repository.ts +++ b/backend/src/modules/ticket/infra/repositories/ticket.mongodb.repository.ts @@ -41,7 +41,7 @@ export class TicketMongoRepository extends ITicketRepository { async readAll(filters?: { clientId?: string; agentId?: string; - categoryId?: string; + categories?: string[]; }): Promise { let query: QueryFilter = {}; @@ -49,7 +49,7 @@ export class TicketMongoRepository extends ITicketRepository { query = { $or: [ { agentId: filters.agentId }, - { category: filters.categoryId, agentId: null }, + { category: { $in: filters.categories ?? [] }, agentId: null }, ], }; } else if (filters?.clientId) { diff --git a/backend/src/modules/ticket/infra/schemas/ticket.mongo.schema.ts b/backend/src/modules/ticket/infra/schemas/ticket.mongo.schema.ts index d3fb096..821f325 100644 --- a/backend/src/modules/ticket/infra/schemas/ticket.mongo.schema.ts +++ b/backend/src/modules/ticket/infra/schemas/ticket.mongo.schema.ts @@ -1,5 +1,5 @@ import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; -import { HydratedDocument, Types } from 'mongoose'; +import { HydratedDocument } from 'mongoose'; import { TicketEventMessage, @@ -7,7 +7,6 @@ import { TicketPriority, TicketStatus, } from '../../domain/entities/ticket.entity'; -import { Category } from '../../../category/category.schema'; @Schema({ _id: false }) export class TicketHistoryEntrySchema { diff --git a/backend/src/modules/ticket/presentation/controllers/ticket.controller.spec.ts b/backend/src/modules/ticket/presentation/controllers/ticket.controller.spec.ts index a24ea29..5c4e847 100644 --- a/backend/src/modules/ticket/presentation/controllers/ticket.controller.spec.ts +++ b/backend/src/modules/ticket/presentation/controllers/ticket.controller.spec.ts @@ -9,12 +9,17 @@ import { ReadAllTicketUseCase } from '../../application/useCases/readAll/readAll import { ReadByIdTicketUseCase } from '../../application/useCases/readById/readById.usecase'; import { TicketController } from './ticket.controller'; import { DeleteTicketUseCase } from '../../application/useCases/delete/delete.usecase'; -import { INestApplication, ValidationPipe } from '@nestjs/common'; +import { + ExecutionContext, + INestApplication, + ValidationPipe, +} from '@nestjs/common'; import { Ticket, TicketStatus } from '../../domain/entities/ticket.entity'; import { randomUUID } from 'crypto'; import request from 'supertest'; import { JwtGuard } from '../../../auth/guards/jwt.guard'; import { RolesGuard } from '../../../auth/guards/roles.guard'; +import { UserRole } from '../../../shared/enums/user.enum'; describe('TicketController', () => { let app: INestApplication; @@ -30,7 +35,7 @@ describe('TicketController', () => { const ticketData = { title: 'chamado 1', - category: 'bi', + category: randomUUID(), description: 'descricao do chamado 1', clientId: randomUUID(), }; @@ -71,7 +76,17 @@ describe('TicketController', () => { ], }) .overrideGuard(JwtGuard) - .useValue({ canActivate: () => true }) + .useValue({ + canActivate: (context: ExecutionContext) => { + const req = context.switchToHttp().getRequest(); + req.user = { + id: randomUUID(), + role: UserRole.ADMIN, + groupId: randomUUID(), + }; + return true; + }, + }) .overrideGuard(RolesGuard) .useValue({ canActivate: () => true }) .compile(); @@ -349,4 +364,77 @@ describe('TicketController', () => { expect(deleteUseCase.execute).toHaveBeenCalledTimes(1); }); + + it('GET /tickets should return tickets filtered by agentId when role is SUPPORT', async () => { + const agentId = randomUUID(); + const categories = [randomUUID()]; + const primitives = ticket.toPrimitives(); + + const moduleFixture = await Test.createTestingModule({ + controllers: [TicketController], + providers: [ + { provide: CreateTicketUseCase, useValue: { execute: jest.fn() } }, + { provide: ReadAllTicketUseCase, useValue: { execute: jest.fn() } }, + { provide: ReadByIdTicketUseCase, useValue: { execute: jest.fn() } }, + { provide: GetHistoryTicketUseCase, useValue: { execute: jest.fn() } }, + { provide: EscalateTicketUseCase, useValue: { execute: jest.fn() } }, + { provide: NewAgentTicketUseCase, useValue: { execute: jest.fn() } }, + { provide: DeleteTicketUseCase, useValue: { execute: jest.fn() } }, + ], + }) + .overrideGuard(JwtGuard) + .useValue({ + canActivate: (context: ExecutionContext) => { + const req = context.switchToHttp().getRequest(); + req.user = { + id: agentId, + role: UserRole.SUPPORT, + categories: categories, // consistente com o JwtStrategy + }; + return true; + }, + }) + .overrideGuard(RolesGuard) + .useValue({ canActivate: () => true }) + .compile(); + + const isolatedApp = moduleFixture.createNestApplication(); + await isolatedApp.init(); + + const localReadAllUseCase = moduleFixture.get(ReadAllTicketUseCase); + + jest.spyOn(localReadAllUseCase, 'execute').mockResolvedValue([ + { + id: primitives._id, + title: primitives.title, + category: categories[0], + priority: primitives.priority, + description: primitives.description, + clientId: primitives.clientId, + status: primitives.status, + createdAt: primitives.createdAt, + agentId: agentId, + escalationLevel: 1, + updatedAt: null, + closedAt: null, + }, + ]); + + const response = await request(isolatedApp.getHttpServer()) + .get('/tickets') + .expect(200); + + expect(Array.isArray(response.body)).toBe(true); + expect(response.body[0]).toEqual( + expect.objectContaining({ agentId, category: categories[0] }), + ); + + expect(localReadAllUseCase.execute).toHaveBeenCalledWith({ + userId: agentId, + categories: categories, + role: UserRole.SUPPORT, + }); + + await isolatedApp.close(); + }); }); diff --git a/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts b/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts index 40c7d29..4afbf0b 100644 --- a/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts +++ b/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts @@ -76,6 +76,7 @@ export class TicketController { async getAll(@Request() req: any) { const response = await this.readAllUseCase.execute({ userId: req.user.id, + categories: req.user.categories ?? undefined, role: req.user.role, }); diff --git a/backend/src/modules/ticket/presentation/dtos/assignAgent.dto.ts b/backend/src/modules/ticket/presentation/dtos/assignAgent.dto.ts index 8c12b92..c6e9ade 100644 --- a/backend/src/modules/ticket/presentation/dtos/assignAgent.dto.ts +++ b/backend/src/modules/ticket/presentation/dtos/assignAgent.dto.ts @@ -1,10 +1,10 @@ -import { IsUUID, IsString } from 'class-validator'; +import { IsString, IsMongoId } from 'class-validator'; import { ApiProperty } from '@nestjs/swagger'; import { randomUUID } from 'crypto'; export class AssignAgentRequest { @ApiProperty({ example: randomUUID(), description: 'ID do agente' }) - @IsUUID() + @IsMongoId() @IsString() agentId!: string; } From 4ae26f0cca8964d313f605ad6cb545d33239a9d6 Mon Sep 17 00:00:00 2001 From: YgorPereira Date: Sun, 26 Apr 2026 17:07:51 -0300 Subject: [PATCH 07/11] refactor: send automatic clientId and agentId in necessary routes and remove from body validator Co-authored-by: Copilot --- .../useCases/create/create.usecase.ts | 16 +++++++--------- .../controllers/ticket.controller.ts | 13 +++++-------- .../ticket/presentation/dtos/assignAgent.dto.ts | 10 ---------- .../ticket/presentation/dtos/create.dto.ts | 16 +--------------- .../presentation/dtos/escalateTicket.dto.ts | 5 +++-- .../ticket/presentation/mappers/ticket.mapper.ts | 13 ++++--------- 6 files changed, 20 insertions(+), 53 deletions(-) delete mode 100644 backend/src/modules/ticket/presentation/dtos/assignAgent.dto.ts diff --git a/backend/src/modules/ticket/application/useCases/create/create.usecase.ts b/backend/src/modules/ticket/application/useCases/create/create.usecase.ts index 8cca044..8592f6f 100644 --- a/backend/src/modules/ticket/application/useCases/create/create.usecase.ts +++ b/backend/src/modules/ticket/application/useCases/create/create.usecase.ts @@ -1,15 +1,11 @@ import { Injectable } from '@nestjs/common'; -import { - Ticket, - TicketStatus, -} from '../../../domain/entities/ticket.entity'; +import { Ticket, TicketStatus } from '../../../domain/entities/ticket.entity'; import { ITicketRepository } from '../../../domain/repository/ticket.repository.interface'; import { TriageService } from '../../../../triage/application/triage.service'; export interface CreateTicketInput { title: string; description: string; - clientId: string; level?: number; } @@ -32,14 +28,16 @@ export class CreateTicketUseCase { private readonly triageService: TriageService, ) {} - async execute(input: CreateTicketInput): Promise { - const triageResult = await this.triageService.classify( - input.description, - ); + async execute( + input: CreateTicketInput, + clientId: string, + ): Promise { + const triageResult = await this.triageService.classify(input.description); const ticket = Ticket.create({ ...input, category: triageResult.category, + clientId: clientId, }); const created = await this.repository.create(ticket); diff --git a/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts b/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts index 4afbf0b..c477e10 100644 --- a/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts +++ b/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ import { @@ -21,7 +22,6 @@ import { ReadByIdTicketUseCase } from '../../application/useCases/readById/readB import { CreateTicketRequest } from '../dtos/create.dto'; import { EscalateTicketRequest } from '../dtos/escalateTicket.dto'; import { TicketMapper } from '../mappers/ticket.mapper'; -import { AssignAgentRequest } from '../dtos/assignAgent.dto'; import { ApiBearerAuth, ApiBody, @@ -55,12 +55,10 @@ export class TicketController { @UseGuards(JwtGuard, RolesGuard) @Roles(UserRole.CLIENT) @ApiResponse({ status: 201, description: 'Ticket criado com sucesso.' }) - async create(@Body() body: CreateTicketRequest) { - // TODO: Enviar id automatica do cliente pelo token, não deixar o cliente enviar o id no body+ - + async create(@Request() req: any, @Body() body: CreateTicketRequest) { const data = TicketMapper.toCreateInput(body); - const response = await this.createUseCase.execute(data); + const response = await this.createUseCase.execute(data, req.user.id); return response; } @@ -128,12 +126,11 @@ export class TicketController { @Put(':id/assignAgent') @ApiOperation({ summary: 'Atribui um agente ao ticket' }) @ApiParam({ name: 'id', example: 'uuid-do-ticket' }) - @ApiBody({ type: AssignAgentRequest }) @UseGuards(JwtGuard, RolesGuard) @Roles(UserRole.ADMIN, UserRole.SUPPORT) @ApiResponse({ status: 200, description: 'Agente atribuído com sucesso.' }) - async assignAgent(@Param('id') id: string, @Body() body: AssignAgentRequest) { - const data = TicketMapper.toNewAgentInput(id, body); + async assignAgent(@Request() req: any, @Param('id') id: string) { + const data = TicketMapper.toNewAgentInput(id, req.user.id); const response = await this.newAgentUseCase.execute(data); diff --git a/backend/src/modules/ticket/presentation/dtos/assignAgent.dto.ts b/backend/src/modules/ticket/presentation/dtos/assignAgent.dto.ts deleted file mode 100644 index c6e9ade..0000000 --- a/backend/src/modules/ticket/presentation/dtos/assignAgent.dto.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { IsString, IsMongoId } from 'class-validator'; -import { ApiProperty } from '@nestjs/swagger'; -import { randomUUID } from 'crypto'; - -export class AssignAgentRequest { - @ApiProperty({ example: randomUUID(), description: 'ID do agente' }) - @IsMongoId() - @IsString() - agentId!: string; -} diff --git a/backend/src/modules/ticket/presentation/dtos/create.dto.ts b/backend/src/modules/ticket/presentation/dtos/create.dto.ts index fecc973..8337b34 100644 --- a/backend/src/modules/ticket/presentation/dtos/create.dto.ts +++ b/backend/src/modules/ticket/presentation/dtos/create.dto.ts @@ -1,12 +1,4 @@ -import { - IsMongoId, - IsNotEmpty, - IsNumber, - IsOptional, - IsString, - Max, - Min, -} from 'class-validator'; +import { IsNumber, IsOptional, IsString, Max, Min } from 'class-validator'; import { ApiProperty } from '@nestjs/swagger'; export class CreateTicketRequest { @@ -21,12 +13,6 @@ export class CreateTicketRequest { @IsString() description!: string; - @ApiProperty({ example: 'uuid-do-cliente', description: 'ID do cliente' }) - @IsString() - @IsNotEmpty() - @IsMongoId() - clientId!: string; - @ApiProperty({ example: 1, description: 'Nível do chamado (1 a 3)' }) @IsOptional() @IsNumber() diff --git a/backend/src/modules/ticket/presentation/dtos/escalateTicket.dto.ts b/backend/src/modules/ticket/presentation/dtos/escalateTicket.dto.ts index 64e21ee..4c89ab5 100644 --- a/backend/src/modules/ticket/presentation/dtos/escalateTicket.dto.ts +++ b/backend/src/modules/ticket/presentation/dtos/escalateTicket.dto.ts @@ -13,9 +13,10 @@ export class EscalateTicketRequest { @IsNotEmpty() category!: string; - @ApiProperty({ + @ApiProperty({ example: 'Reiniciei o servidor e o problema persistiu.', - description: 'O que foi feito antes de escalonar' }) + description: 'O que foi feito antes de escalonar', + }) @IsString() @IsNotEmpty() whatWasDone!: string; diff --git a/backend/src/modules/ticket/presentation/mappers/ticket.mapper.ts b/backend/src/modules/ticket/presentation/mappers/ticket.mapper.ts index bdef10d..6e3f039 100644 --- a/backend/src/modules/ticket/presentation/mappers/ticket.mapper.ts +++ b/backend/src/modules/ticket/presentation/mappers/ticket.mapper.ts @@ -1,7 +1,6 @@ import { CreateTicketInput } from '../../application/useCases/create/create.usecase'; import { EscalateTicketInput } from '../../application/useCases/escalate/escalate.usecase'; import { NewAgentTicketInput } from '../../application/useCases/newAgent/newAgent.usecase'; -import { AssignAgentRequest } from '../dtos/assignAgent.dto'; import { CreateTicketRequest } from '../dtos/create.dto'; import { EscalateTicketRequest } from '../dtos/escalateTicket.dto'; @@ -10,18 +9,14 @@ export class TicketMapper { return { title: req.title, description: req.description, - clientId: req.clientId, - level: req.level + level: req.level, }; } - static toNewAgentInput( - id: string, - req: AssignAgentRequest, - ): NewAgentTicketInput { + static toNewAgentInput(id: string, agentId: string): NewAgentTicketInput { return { id: id, - agentId: req.agentId, + agentId: agentId, }; } @@ -33,7 +28,7 @@ export class TicketMapper { id: id, groupId: req.groupId, category: req.category, - whatWasDone: req.whatWasDone + whatWasDone: req.whatWasDone, }; } } From b7a945b3b6bcf8d723a593f09fa1d16d55b4ee7f Mon Sep 17 00:00:00 2001 From: YgorPereira Date: Sun, 26 Apr 2026 17:10:30 -0300 Subject: [PATCH 08/11] fix: correct input send on ticket repository test --- .../domain/repository/ticket.mongodb.repository.int.spec.ts | 5 ++++- .../ticket/domain/repository/ticket.repository.interface.ts | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/backend/src/modules/ticket/domain/repository/ticket.mongodb.repository.int.spec.ts b/backend/src/modules/ticket/domain/repository/ticket.mongodb.repository.int.spec.ts index d08ab29..5582b84 100644 --- a/backend/src/modules/ticket/domain/repository/ticket.mongodb.repository.int.spec.ts +++ b/backend/src/modules/ticket/domain/repository/ticket.mongodb.repository.int.spec.ts @@ -267,7 +267,10 @@ describe('ITicketRepository', () => { await repository.create(ticket2); await repository.create(ticket3); - const result = await repository.readAll({ agentId, categoryId }); + const result = await repository.readAll({ + agentId, + categories: [categoryId], + }); expect(result).toBeDefined(); expect(Array.isArray(result)).toBe(true); diff --git a/backend/src/modules/ticket/domain/repository/ticket.repository.interface.ts b/backend/src/modules/ticket/domain/repository/ticket.repository.interface.ts index 7bbd220..a62ab13 100644 --- a/backend/src/modules/ticket/domain/repository/ticket.repository.interface.ts +++ b/backend/src/modules/ticket/domain/repository/ticket.repository.interface.ts @@ -8,7 +8,7 @@ export abstract class ITicketRepository { abstract readAll(filters?: { clientId?: string; agentId?: string; - categoryId?: string; + categories?: string[]; }): Promise; abstract readById(id: string): Promise; abstract delete(id: string): Promise; From 639081636de9feb5908f81c45b689b042dcdad01 Mon Sep 17 00:00:00 2001 From: YgorPereira Date: Tue, 28 Apr 2026 11:24:59 -0300 Subject: [PATCH 09/11] fix: empty array for categories if user is not support --- backend/src/modules/auth/guards/jwt.strategy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/modules/auth/guards/jwt.strategy.ts b/backend/src/modules/auth/guards/jwt.strategy.ts index 1dec8bd..a48c912 100644 --- a/backend/src/modules/auth/guards/jwt.strategy.ts +++ b/backend/src/modules/auth/guards/jwt.strategy.ts @@ -17,7 +17,7 @@ export class JwtStrategy extends PassportStrategy(Strategy) { id: payload.sub, email: payload.email, role: payload.role, - categories: (payload.categories ?? undefined).map((c) => c.id), + categories: (payload.categories ?? []).map((c) => c.id), }; } } From 5e79c80f229bf4f097e9dfcb9471fe9e5401099f Mon Sep 17 00:00:00 2001 From: YgorPereira Date: Fri, 1 May 2026 15:25:54 -0300 Subject: [PATCH 10/11] fix: test and user role import --- .../src/modules/faq/presentation/controllers/faq.controller.ts | 2 +- .../ticket/presentation/controllers/ticket.controller.spec.ts | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/backend/src/modules/faq/presentation/controllers/faq.controller.ts b/backend/src/modules/faq/presentation/controllers/faq.controller.ts index 2b62e11..d60d980 100644 --- a/backend/src/modules/faq/presentation/controllers/faq.controller.ts +++ b/backend/src/modules/faq/presentation/controllers/faq.controller.ts @@ -7,11 +7,11 @@ import { ReadAllFaqUseCase } from "../../application/readAll/readAll.usecase"; import { ReadByIdFaqUseCase } from "../../application/readById/readById.usecase"; import { JwtGuard } from "../../../auth/guards/jwt.guard"; import { RolesGuard } from "../../../auth/guards/roles.guard"; -import { UserRole } from "../../../user/user.schema"; import { CreateFaqRequest } from "../dtos/create.dto"; import { FaqMapper } from "../mappers/faq.mapper"; import { Roles } from "../../../auth/guards/roles.decorator"; import { UpdateFaqRequest } from "../dtos/update.dto"; +import { UserRole } from "../../../shared/enums/user.enum"; @ApiTags('FAQ') @ApiBearerAuth() diff --git a/backend/src/modules/ticket/presentation/controllers/ticket.controller.spec.ts b/backend/src/modules/ticket/presentation/controllers/ticket.controller.spec.ts index 1820ba7..880101a 100644 --- a/backend/src/modules/ticket/presentation/controllers/ticket.controller.spec.ts +++ b/backend/src/modules/ticket/presentation/controllers/ticket.controller.spec.ts @@ -93,6 +93,7 @@ describe('TicketController', () => { provide: GetHistoryTicketUseCase, useValue: { execute: jest.fn() }, }, + ], }) .overrideGuard(JwtGuard) @@ -578,6 +579,8 @@ describe('TicketController', () => { { provide: EscalateTicketUseCase, useValue: { execute: jest.fn() } }, { provide: NewAgentTicketUseCase, useValue: { execute: jest.fn() } }, { provide: DeleteTicketUseCase, useValue: { execute: jest.fn() } }, + { provide: GetHistoryFilteredUseCase, useValue: { execute: jest.fn() } }, + { provide: CloseTicketUseCase, useValue: { execute: jest.fn() } }, ], }) .overrideGuard(JwtGuard) From 4ed9d0a4703d9e4896e9202730ad449d616fb725 Mon Sep 17 00:00:00 2001 From: YgorPereira Date: Fri, 1 May 2026 15:55:16 -0300 Subject: [PATCH 11/11] fix: delete param id --- .../ticket/presentation/controllers/ticket.controller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts b/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts index be5583f..2811ac3 100644 --- a/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts +++ b/backend/src/modules/ticket/presentation/controllers/ticket.controller.ts @@ -184,7 +184,7 @@ export class TicketController { @UseGuards(JwtGuard, RolesGuard) @Roles(UserRole.ADMIN) @ApiResponse({ status: 200, description: 'Ticket removido com sucesso.' }) - async delete(@Param() id: string) { + async delete(@Param('id') id: string) { const response = await this.deleteUseCase.execute(id); return { deleted: response };