diff --git a/src/modules/chat/DTO/create-chat.dto.ts b/src/modules/chat/DTO/create-chat.dto.ts index d461c96..eb8d6fa 100755 --- a/src/modules/chat/DTO/create-chat.dto.ts +++ b/src/modules/chat/DTO/create-chat.dto.ts @@ -1,19 +1,24 @@ -import { ApiProperty } from "@nestjs/swagger"; -import { IsNotEmpty, IsOptional, IsString, IsUrl, Length } from "class-validator"; +import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; +import { IsNotEmpty, IsOptional, IsString, Length } from "class-validator"; import { AttachmentType } from "../interfaces/chat"; import { TicketMessageEnum } from "../../../common/enums/message.enum"; export class CreateChatDto { - @IsNotEmpty({ message: TicketMessageEnum.MESSAGE_REQUIRED }) + @IsOptional() @IsString({ message: TicketMessageEnum.MESSAGE_STRING }) - @Length(1, 5000, { message: TicketMessageEnum.MESSAGE_LENGTH }) - @ApiProperty({ description: "The message content of the ticket" }) - content: string; + @Length(0, 5000, { message: TicketMessageEnum.MESSAGE_LENGTH }) + @ApiProperty({ description: "The message content of the ticket", required: false }) + content: string = ''; @IsOptional() @IsNotEmpty({ message: TicketMessageEnum.ATTACHMENT_REQUIRED }) @ApiProperty({ description: "attachment url", example: [{ type: '', url: '' }] }) attachments?: AttachmentType[]; + + @ApiPropertyOptional({ description: "Parent chat ID for reply" }) + @IsOptional() + @IsString() + parentId?: string; } diff --git a/src/modules/chat/providers/chat.service.ts b/src/modules/chat/providers/chat.service.ts index f826f58..abecbff 100755 --- a/src/modules/chat/providers/chat.service.ts +++ b/src/modules/chat/providers/chat.service.ts @@ -116,18 +116,31 @@ export class ChattService { } async createChat(refId: string, dto: CreateChatDto, user?: User, admin?: Admin) { - const { content, attachments } = dto + const { content = '', attachments, parentId } = dto if (!user && !admin) { throw new BadRequestException("One of user or admin is required") } + if (!content.trim() && (!attachments || attachments.length === 0)) { + throw new BadRequestException("Message content or attachment is required") + } + + let parent: Chat | undefined + if (parentId) { + parent = await this.findOneOrFail(parentId) + if (parent.refId !== refId) { + throw new BadRequestException("Parent message does not belong to this chat") + } + } + const ticket = this.chatRepository.create({ content, attachments, admin, user, - refId + refId, + parent, }) await this.chatRepository.em.persistAndFlush(ticket) @@ -137,6 +150,7 @@ export class ChattService { } async deleteChat(chat: Chat) { + await this.em.nativeUpdate(Chat, { parent: chat.id }, { parent: null }) await this.em.removeAndFlush(chat) return true } @@ -165,7 +179,7 @@ export class ChattService { async findOneOrFail(ticketId: string) { const ticket = await this.chatRepository.findOne({ id: ticketId }, - { populate: ['user'] }) + { populate: ['user', 'admin', 'parent'] }) if (!ticket) { throw new BadRequestException('ticket not found!') } diff --git a/src/modules/chat/repositories/chat.repository.ts b/src/modules/chat/repositories/chat.repository.ts index 866352a..483db5a 100755 --- a/src/modules/chat/repositories/chat.repository.ts +++ b/src/modules/chat/repositories/chat.repository.ts @@ -34,7 +34,7 @@ export class ChatRepository extends EntityRepository { limit, offset, orderBy: { createdAt: 'desc' }, - populate: ['admin', 'user'] + populate: ['admin', 'user', 'parent', 'parent.admin', 'parent.user'], });