diff --git a/database/migrations/Migration20260726120000_addEnableAiChatToRestaurants.ts b/database/migrations/Migration20260726120000_addEnableAiChatToRestaurants.ts new file mode 100644 index 0000000..a0db542 --- /dev/null +++ b/database/migrations/Migration20260726120000_addEnableAiChatToRestaurants.ts @@ -0,0 +1,13 @@ +import { Migration } from '@mikro-orm/migrations'; + +export class Migration20260726120000_addEnableAiChatToRestaurants extends Migration { + override async up(): Promise { + this.addSql( + `alter table "restaurants" add column "enable_ai_chat" boolean not null default false;`, + ); + } + + override async down(): Promise { + this.addSql(`alter table "restaurants" drop column "enable_ai_chat";`); + } +} diff --git a/src/common/enums/message.enum.ts b/src/common/enums/message.enum.ts index 32ced4e..6bfb4fc 100755 --- a/src/common/enums/message.enum.ts +++ b/src/common/enums/message.enum.ts @@ -602,6 +602,7 @@ export const enum AiMessage { NO_RESPONSE_FROM_AI_MODEL = 'خطا در دریافت پاسخ از مدل AI', LLM_SERVICE_ERROR = 'سرویس هوش مصنوعی موقتاً در دسترس نیست', INSUFFICIENT_CREDIT = 'اعتبار کیف پول رستوران برای استفاده از هوش مصنوعی کافی نیست', + AI_CHAT_DISABLED = 'چت هوش مصنوعی برای این رستوران فعال نیست', MESSAGE_NOT_FOUND_OR_ACCESS_DENIED = 'ایمیل یافت نشد یا دسترسی آن را ندارید', EMAIL_CONTENT_IS_EMPTY_OR_COULD_NOT_BE_EXTRACTED = 'محتوای ایمیل خالی است یا قابل استخراج نیست', DESCRIPTION_IS_REQUIRED = 'شرح و هدف قالب الزامی است', diff --git a/src/modules/ai/providers/ai.service.ts b/src/modules/ai/providers/ai.service.ts index cc4cfbd..080834a 100644 --- a/src/modules/ai/providers/ai.service.ts +++ b/src/modules/ai/providers/ai.service.ts @@ -50,6 +50,11 @@ export class AiService { async chat(dto: ChatDto, params: { restId?: string; userId?: string; slug?: string }): Promise { const restaurant = await this.resolveRestaurant(params.restId, params.slug); + + if (!restaurant.enableAiChat) { + throw new BadRequestException(AiMessage.AI_CHAT_DISABLED); + } + const user = params.userId ? await this.em.findOne(User, { id: params.userId }) : null; await this.ensureHasCredit(restaurant.id); diff --git a/src/modules/restaurants/dto/create-restaurant.dto.ts b/src/modules/restaurants/dto/create-restaurant.dto.ts index 632d6da..41ae5f4 100644 --- a/src/modules/restaurants/dto/create-restaurant.dto.ts +++ b/src/modules/restaurants/dto/create-restaurant.dto.ts @@ -52,4 +52,9 @@ export class CreateRestaurantDto { @IsBoolean() isActive?: boolean; + @ApiPropertyOptional({ example: false, description: 'فعال بودن چت هوش مصنوعی', default: false }) + @IsOptional() + @IsBoolean() + enableAiChat?: boolean; + } diff --git a/src/modules/restaurants/dto/setup-restaurant.dto.ts b/src/modules/restaurants/dto/setup-restaurant.dto.ts index eadfbe5..ae3212a 100644 --- a/src/modules/restaurants/dto/setup-restaurant.dto.ts +++ b/src/modules/restaurants/dto/setup-restaurant.dto.ts @@ -51,4 +51,9 @@ export class SetupRestaurantDto { @IsBoolean() isActive?: boolean; + @ApiPropertyOptional({ example: false, description: 'فعال بودن چت هوش مصنوعی', default: false }) + @IsOptional() + @IsBoolean() + enableAiChat?: boolean; + } diff --git a/src/modules/restaurants/entities/restaurant.entity.ts b/src/modules/restaurants/entities/restaurant.entity.ts index 1ca8e7d..9a58bb4 100644 --- a/src/modules/restaurants/entities/restaurant.entity.ts +++ b/src/modules/restaurants/entities/restaurant.entity.ts @@ -40,6 +40,9 @@ export class Restaurant extends BaseEntity { @Property({ default: true }) isActive: boolean = true; + @Property({ default: false }) + enableAiChat: boolean = false; + @Property({ nullable: true }) establishedYear?: number; diff --git a/src/modules/restaurants/providers/restaurants.service.ts b/src/modules/restaurants/providers/restaurants.service.ts index d2c296a..4bf83f8 100644 --- a/src/modules/restaurants/providers/restaurants.service.ts +++ b/src/modules/restaurants/providers/restaurants.service.ts @@ -73,6 +73,7 @@ export class RestaurantsService { establishedYear: dto.establishedYear, phones: dto.phone ? [dto.phone] : undefined, isActive: true, + enableAiChat: dto.enableAiChat ?? false, plan: dto.plan, domain: `https://dmenu.danakcorp.com/${slug}`, subscriptionId: dto.subscriptionId, diff --git a/src/seeders/restaurants.seeder.ts b/src/seeders/restaurants.seeder.ts index cadd9bb..67255ba 100644 --- a/src/seeders/restaurants.seeder.ts +++ b/src/seeders/restaurants.seeder.ts @@ -14,6 +14,7 @@ export class RestaurantsSeeder { subscriptionStartDate: new Date('2026-01-01'), subscriptionEndDate: new Date('2026-01-07'), isActive: true, + enableAiChat: false, }); em.persist(restaurant); }