Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { UnresolvedQueryModule } from './modules/message/unresolved-message.modu
import { ProfileModule } from './modules/profile/profile.module';
import { RequestLoggerMiddleware } from './internal/middlewares/request-logger.middleware';
import { GeminiModule } from './modules/gemini/gemini.module';
import { UserBotsModule } from './modules/user-bots/user-bots.module';

@Module({
imports: [
Expand Down Expand Up @@ -48,7 +49,9 @@ import { GeminiModule } from './modules/gemini/gemini.module';
QnAModule,
ProfileModule,
GeminiModule,
UserBotsModule,
],
providers: [],
})
export class AppModule {
configure(consumer: MiddlewareConsumer) {
Expand Down
10 changes: 10 additions & 0 deletions src/entities/messages.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,13 @@ export const enum QnaErrorMessages {
export const enum QnaSuccessMessages {
QNA_CREATED_SUCCESSFULLY = 'message.qna.success.successFullyCreated',
}

export const enum UserBotsErrorMessages {
USER_BOTS_ALREADY_EXISTS = 'message.userBots.errors.alreadyExists',
COULD_NOT_CREATED_USER_BOTS = 'message.userBots.errors.couldNotCreateUserBot',
COULD_NOT_UPDATED_USER_BOTS = 'message.userBots.errors.couldNotUpdatedUserBot',
INVALID_USER_BOTS_ID = 'message.userBots.errors.invalidUserBotId',
}
export const enum UserBotsSuccessMessages {
USER_BOTS_CREATED_SUCCESSFULLY = 'message.bot.errors.botCreationSuccessful',
}
9 changes: 9 additions & 0 deletions src/i18n/en/message.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,15 @@
"couldNotDeletedQnA": "Failed to deleted the QnA",
"couldNotCreateQnA": "Failed to create a QnA"
}
},
"userBots":{
"errors": {
"invalidUserBotId": "Invalid UserBot ID",
"couldNotUpdatedUserBot": "Failed to update a UserBot",
"couldNotDeletedUserBot": "Failed to deleted the UserBot",
"couldNotCreateUserBot": "Failed to create a UserBot",
"alreadyExists": "This user already exists in this botCreationSuccessful"
}
}

}
11 changes: 10 additions & 1 deletion src/modules/bot/bot.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,19 @@ import { BotRepository } from './bot.repository';
import { BotService } from './bot.service';
import { APIResponse } from 'src/internal/api-response/api-response.service';
import { PaginationService } from '../pagination/pagination.service';
import { UserBotsRepository } from '../user-bots/user-bots.repository';
import { UserRepository } from '../user/user.repository';

@Module({
imports: [MongooseModule.forFeature([{ name: 'Bot', schema: BotSchema }])],
controllers: [BotController],
providers: [BotService, BotRepository, APIResponse, PaginationService],
providers: [
BotService,
BotRepository,
APIResponse,
PaginationService,
UserBotsRepository,
UserRepository,
],
})
export class BotModule {}
22 changes: 21 additions & 1 deletion src/modules/bot/bot.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,17 @@ import {
} from 'src/entities/messages.entity';
import { ROLE } from 'src/entities/enum.entity';
import { startSession } from 'mongoose';
import { UserBotsRepository } from '../user-bots/user-bots.repository';
import { UserRepository } from '../user/user.repository';

@Injectable()
export class BotService {
constructor(
private readonly botRepository: BotRepository,
private readonly apiResponse: APIResponse,
private readonly pagination: PaginationService,
private readonly userBotsRepo: UserBotsRepository,
private readonly userRepo: UserRepository,
) {}

async createBot(
Expand Down Expand Up @@ -74,13 +78,29 @@ export class BotService {
logo?: Express.Multer.File,
icon?: Express.Multer.File,
): Promise<IResponse<BotInterface>> {
const bot = await this.botRepository.findBotById(botId);
// Check if the bot exists
const [creatorRole, bot] = await Promise.all([
await this.userRepo.findRole({ _id: user?.roleId?._id }),
await this.botRepository.findBotById(botId),
]);
console.log('🚀 ~ BotService ~ creatorRole:', creatorRole);

if (!bot)
throw new HttpException(
{ message: BotErrorMessages.INVALID_BOT_ID },
HttpStatus.BAD_REQUEST,
);

const isOwner = await this.userBotsRepo.findByUserAndBot(user._id, botId);

// Check if the creatorRole is CUSTOMER or if the user is not the owner
if (!isOwner && creatorRole.name !== ROLE.SUPER_ADMIN) {
throw new HttpException(
{ message: UserErrorMessages.FORBIDDEN_PERMISSION },
HttpStatus.BAD_REQUEST,
);
}

const updatedBot = await this.botRepository.update(botId, data);

if (!updatedBot) {
Expand Down
3 changes: 2 additions & 1 deletion src/modules/profile/profile.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import { ProfileController } from './profile.controller';
import { ProfileService } from './profile.service';
import { UserModule } from 'src/modules/user/user.module';
import { APIResponse } from 'src/internal/api-response/api-response.service';
import { UserBotsRepository } from '../user-bots/user-bots.repository';

@Module({
imports: [UserModule],
controllers: [ProfileController],
providers: [ProfileService, APIResponse],
providers: [ProfileService, APIResponse, UserBotsRepository],
})
export class ProfileModule {}
7 changes: 6 additions & 1 deletion src/modules/profile/profile.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@ import { UserInterface } from 'src/modules/user/entities/user.entity';
import { UserRepository } from 'src/modules/user/user.repository';
import { UserService } from 'src/modules/user/user.service';
import { getRoleLabel } from 'src/utils';
import { UserBotsRepository } from '../user-bots/user-bots.repository';

@Injectable()
export class ProfileService {
constructor(
private userRepo: UserRepository,
private readonly response: APIResponse,
private readonly i18n: I18nService,
private userService: UserService,
private readonly userService: UserService,
private readonly userBotsRepo: UserBotsRepository,
) {}

/**
Expand Down Expand Up @@ -62,6 +64,9 @@ export class ProfileService {
(userInfo as any).permissions = await this.userRepo.getPermissionsArray({
roleId: user?.roleId._id,
});
const listOfUserBots = await this.userBotsRepo.findUserBots(user._id);

userInfo.botList = listOfUserBots.map((bot) => bot.botId);

return this.response.success(userInfo);
}
Expand Down
8 changes: 6 additions & 2 deletions src/modules/qna/qna.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ export class QnARepository {
query: Record<string, any>,
pagination: { skip: number; limit: number },
) {
console.log('🚀 ~ QnARepository ~ query:', query);
const client = await this.dbService.getClient();
try {
const { skip, limit } = pagination;
const { botId } = query;
console.log('🚀 ~ QnARepository ~ botId:', botId);

let sqlQuery =
'SELECT id, question, answer, "botId", "createdAt", "updatedAt" FROM question_n_answers';
Expand Down Expand Up @@ -67,11 +67,15 @@ export class QnARepository {

if (botId) {
sqlQuery += ' WHERE "botId" = $1';
queryParams.push(botId);
queryParams.push(botId.toString());
}

const result = await client.query(sqlQuery, queryParams);

return parseInt(result.rows[0].count);
} catch (error) {
console.error('Error in countVectors:', error);
throw error;
} finally {
client.release();
}
Expand Down
29 changes: 29 additions & 0 deletions src/modules/user-bots/dtos/user-bots.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { IsBoolean, IsNotEmpty, IsOptional, IsString } from 'class-validator';

export class CreateUserBotDto {
@IsString({
message: 'validation.isString',
})
@IsNotEmpty({
message: 'validation.isNotEmpty',
})
userId: string;

@IsString({
message: 'validation.isString',
})
@IsNotEmpty({
message: 'validation.isNotEmpty',
})
botId: string;

@IsOptional()
@IsBoolean()
isActive?: boolean;
}

export class UpdateUserBotDto {
@IsOptional()
@IsBoolean()
isActive?: boolean;
}
6 changes: 6 additions & 0 deletions src/modules/user-bots/entities/user-bots.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export class UserBots {
_id?: string;
userId: any;
botId?: any;
isActive?: boolean;
}
29 changes: 29 additions & 0 deletions src/modules/user-bots/entities/user-bots.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { model, Schema } from 'mongoose';
import { UserBots } from './user-bots.entity';

const UserBotsSchema = new Schema<UserBots>(
{
userId: {
type: Schema.Types.ObjectId,
required: true,
ref: 'User',
},
botId: {
type: Schema.Types.ObjectId,
required: true,
ref: 'Bot',
},
isActive: {
type: Boolean,
default: true,
},
},
{
timestamps: true,
versionKey: false,
},
);

const UserBotsModel = model<UserBots>('userbots', UserBotsSchema);

export { UserBotsModel, UserBotsSchema };
21 changes: 21 additions & 0 deletions src/modules/user-bots/user-bots.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { UserBotsService } from './user-bots.service';
import { UserBotsRepository } from './user-bots.repository';
import { UserBotsSchema } from './entities/user-bots.model';
import { BotRepository } from '../bot/bot.repository';
import { UserRepository } from '../user/user.repository';

@Module({
imports: [
MongooseModule.forFeature([{ name: 'UserBots', schema: UserBotsSchema }]),
],
providers: [
UserBotsService,
UserBotsRepository,
BotRepository,
UserRepository,
],
exports: [UserBotsService],
})
export class UserBotsModule {}
63 changes: 63 additions & 0 deletions src/modules/user-bots/user-bots.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { Injectable } from '@nestjs/common';
import { UserBotsModel } from './entities/user-bots.model';
import { CreateUserBotDto } from './dtos/user-bots.dto';
import { UserBots } from './entities/user-bots.entity';

@Injectable()
export class UserBotsRepository {
async create(createUserBotDto: CreateUserBotDto): Promise<UserBots> {
try {
return await UserBotsModel.create(createUserBotDto);
} catch (error) {
console.log('🚀 ~ UserBotsRepository ~ create ~ error:', error);

throw error;
}
}

async findByUserAndBot(
userId: string,
botId: string,
): Promise<UserBots | null> {
try {
return await UserBotsModel.findOne({ userId, botId });
} catch (error) {
console.log('🚀 ~ UserBotsRepository ~ error:', error);
throw error;
}
}

async findById(id: string): Promise<UserBots | null> {
try {
return await UserBotsModel.findById(id);
} catch (error) {
console.log('🚀 ~ UserBotsRepository ~ findById ~ error:', error);
throw error;
}
}

async update(
id: string,
updateData: Partial<UserBots>,
): Promise<UserBots | null> {
try {
return await UserBotsModel.findByIdAndUpdate(id, updateData, {
new: true,
});
} catch (error) {
console.log('🚀 ~ UserBotsRepository ~ error:', error);
throw error;
}
}

async findUserBots(userId: string): Promise<UserBots[]> {
try {
return await UserBotsModel.find({ userId, isActive: true }).select(
'-createdAt -updatedAt',
);
} catch (error) {
console.log('🚀 ~ UserBotsRepository ~ findUserBots ~ error:', error);
throw error;
}
}
}
Loading