diff --git a/backend/src/tickets/tickets.controller.ts b/backend/src/tickets/tickets.controller.ts index 1666f9d..05e2ffc 100644 --- a/backend/src/tickets/tickets.controller.ts +++ b/backend/src/tickets/tickets.controller.ts @@ -107,11 +107,13 @@ export class TicketsController { @Request() req: any, @Body() dto: UpdateTicketStatusDto, ) { - const ticket = await this.ticketsService.findOne(id, req.user.id, req.user.role); - ticket.status = dto.status; + // Access check + await this.ticketsService.findOne(id, req.user.id, req.user.role); + const updateData: any = { status: dto.status }; if (dto.status === TicketStatus.CLOSED) { - ticket.closedAt = new Date(); + updateData.closedAt = new Date(); } - return this.ticketsService['ticketsRepo'].save(ticket); + await this.ticketsService.updateTicketFields(id, updateData); + return this.ticketsService.findOne(id, req.user.id, req.user.role); } } diff --git a/backend/src/tickets/tickets.service.ts b/backend/src/tickets/tickets.service.ts index 492aa11..59a1b1c 100644 --- a/backend/src/tickets/tickets.service.ts +++ b/backend/src/tickets/tickets.service.ts @@ -85,24 +85,20 @@ export class TicketsService { // ─── Reply to ticket ─── async reply(ticketId: string, userId: string, userRole: UserRole, dto: ReplyTicketDto): Promise { - const ticket = await this.findOne(ticketId, userId, userRole); + // Verify access first + await this.findOne(ticketId, userId, userRole); const msg = this.messagesRepo.create({ - ticketId: ticket.id, + ticketId, senderId: userId, senderRole: userRole, message: dto.message, }); const saved = await this.messagesRepo.save(msg); - // Update ticket status based on who replied - if (userRole === UserRole.USER) { - ticket.status = TicketStatus.WAITING; - } else { - // Staff or admin replied - ticket.status = TicketStatus.ANSWERED; - } - await this.ticketsRepo.save(ticket); + // Update ticket status directly (avoid cascade issues with loaded relations) + const newStatus = userRole === UserRole.USER ? TicketStatus.WAITING : TicketStatus.ANSWERED; + await this.ticketsRepo.update(ticketId, { status: newStatus }); this.logger.log(`Reply on ticket ${ticketId} by ${userRole} user ${userId}`); return saved; @@ -110,10 +106,17 @@ export class TicketsService { // ─── Close ticket ─── async close(ticketId: string, userId: string, userRole: UserRole): Promise { - const ticket = await this.findOne(ticketId, userId, userRole); - ticket.status = TicketStatus.CLOSED; - ticket.closedAt = new Date(); - return this.ticketsRepo.save(ticket); + await this.findOne(ticketId, userId, userRole); + await this.ticketsRepo.update(ticketId, { + status: TicketStatus.CLOSED, + closedAt: new Date(), + }); + return this.findOne(ticketId, userId, userRole); + } + + // ─── Update ticket fields (safe, no cascade) ─── + async updateTicketFields(ticketId: string, data: Partial): Promise { + await this.ticketsRepo.update(ticketId, data); } // ─── Staff: List department tickets ───