chat
deploy to danak / build_and_deploy (push) Has been cancelled

This commit is contained in:
2026-07-17 23:59:00 +03:30
parent b2160a136a
commit 02c3a2e01d
3 changed files with 29 additions and 10 deletions
+11 -6
View File
@@ -1,19 +1,24 @@
import { ApiProperty } from "@nestjs/swagger"; import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
import { IsNotEmpty, IsOptional, IsString, IsUrl, Length } from "class-validator"; import { IsNotEmpty, IsOptional, IsString, Length } from "class-validator";
import { AttachmentType } from "../interfaces/chat"; import { AttachmentType } from "../interfaces/chat";
import { TicketMessageEnum } from "../../../common/enums/message.enum"; import { TicketMessageEnum } from "../../../common/enums/message.enum";
export class CreateChatDto { export class CreateChatDto {
@IsNotEmpty({ message: TicketMessageEnum.MESSAGE_REQUIRED }) @IsOptional()
@IsString({ message: TicketMessageEnum.MESSAGE_STRING }) @IsString({ message: TicketMessageEnum.MESSAGE_STRING })
@Length(1, 5000, { message: TicketMessageEnum.MESSAGE_LENGTH }) @Length(0, 5000, { message: TicketMessageEnum.MESSAGE_LENGTH })
@ApiProperty({ description: "The message content of the ticket" }) @ApiProperty({ description: "The message content of the ticket", required: false })
content: string; content: string = '';
@IsOptional() @IsOptional()
@IsNotEmpty({ message: TicketMessageEnum.ATTACHMENT_REQUIRED }) @IsNotEmpty({ message: TicketMessageEnum.ATTACHMENT_REQUIRED })
@ApiProperty({ description: "attachment url", example: [{ type: '', url: '' }] }) @ApiProperty({ description: "attachment url", example: [{ type: '', url: '' }] })
attachments?: AttachmentType[]; attachments?: AttachmentType[];
@ApiPropertyOptional({ description: "Parent chat ID for reply" })
@IsOptional()
@IsString()
parentId?: string;
} }
+17 -3
View File
@@ -116,18 +116,31 @@ export class ChattService {
} }
async createChat(refId: string, dto: CreateChatDto, user?: User, admin?: Admin) { async createChat(refId: string, dto: CreateChatDto, user?: User, admin?: Admin) {
const { content, attachments } = dto const { content = '', attachments, parentId } = dto
if (!user && !admin) { if (!user && !admin) {
throw new BadRequestException("One of user or admin is required") 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({ const ticket = this.chatRepository.create({
content, content,
attachments, attachments,
admin, admin,
user, user,
refId refId,
parent,
}) })
await this.chatRepository.em.persistAndFlush(ticket) await this.chatRepository.em.persistAndFlush(ticket)
@@ -137,6 +150,7 @@ export class ChattService {
} }
async deleteChat(chat: Chat) { async deleteChat(chat: Chat) {
await this.em.nativeUpdate(Chat, { parent: chat.id }, { parent: null })
await this.em.removeAndFlush(chat) await this.em.removeAndFlush(chat)
return true return true
} }
@@ -165,7 +179,7 @@ export class ChattService {
async findOneOrFail(ticketId: string) { async findOneOrFail(ticketId: string) {
const ticket = await this.chatRepository.findOne({ id: ticketId }, const ticket = await this.chatRepository.findOne({ id: ticketId },
{ populate: ['user'] }) { populate: ['user', 'admin', 'parent'] })
if (!ticket) { if (!ticket) {
throw new BadRequestException('ticket not found!') throw new BadRequestException('ticket not found!')
} }
@@ -34,7 +34,7 @@ export class ChatRepository extends EntityRepository<Chat> {
limit, limit,
offset, offset,
orderBy: { createdAt: 'desc' }, orderBy: { createdAt: 'desc' },
populate: ['admin', 'user'] populate: ['admin', 'user', 'parent', 'parent.admin', 'parent.user'],
}); });