ticket status

This commit is contained in:
2026-02-24 16:34:28 +03:30
parent 7886368601
commit 37d3a241e7
4 changed files with 71 additions and 0 deletions
@@ -0,0 +1,13 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsIn } from 'class-validator';
import { TicketStatusEnum } from '../enum/status.enum';
export class UpdateTicketStatusUserDto {
@ApiProperty({
description: 'User can only set status to closed',
enum: [TicketStatusEnum.CLOSED],
example: TicketStatusEnum.CLOSED,
})
@IsIn([TicketStatusEnum.CLOSED])
status: TicketStatusEnum.CLOSED;
}
@@ -0,0 +1,12 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsEnum } from 'class-validator';
import { TicketStatusEnum } from '../enum/status.enum';
export class UpdateTicketStatusDto {
@ApiProperty({
description: 'Ticket status',
enum: TicketStatusEnum,
})
@IsEnum(TicketStatusEnum)
status: TicketStatusEnum;
}
+21
View File
@@ -13,8 +13,10 @@ import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger';
import { TicketService } from './ticket.service';
import { CreateTicketDto } from './dto/create-ticket.dto';
import { UpdateTicketDto } from './dto/update-ticket.dto';
import { UpdateTicketStatusDto } from './dto/update-ticket-status.dto';
import { CreateTicketUserDto } from './dto/create-ticket-user.dto';
import { UpdateTicketUserDto } from './dto/update-ticket-user.dto';
import { UpdateTicketStatusUserDto } from './dto/update-ticket-status-user.dto';
import { SearchTicketQueryDto } from './dto/search-ticket-query.dto';
import { AdminAuthGuard } from '../auth/guards/adminAuth.guard';
import { AuthGuard } from '../auth/guards/auth.guard';
@@ -63,6 +65,17 @@ export class TicketController {
return this.ticketService.updateAsUser(id, updateTicketUserDto, userId);
}
@Patch('public/tickets/:id/status')
@UseGuards(AuthGuard)
@ApiOperation({ summary: 'Update ticket status (user can only set to closed)' })
updateStatusAsUser(
@Param('id') id: string,
@Body() dto: UpdateTicketStatusUserDto,
@UserId() userId: string,
) {
return this.ticketService.updateStatusAsUser(id, dto, userId);
}
// ================== Admin routes ===================
@Post('admin/tickets')
@@ -97,6 +110,14 @@ export class TicketController {
return this.ticketService.update(id, updateTicketDto);
}
@Patch('admin/tickets/:id/status')
@UseGuards(AdminAuthGuard)
@Permissions(PermissionEnum.MANAGE_TICKETS)
@ApiOperation({ summary: 'Update ticket status (admin can set any status)' })
updateStatusAsAdmin(@Param('id') id: string, @Body() dto: UpdateTicketStatusDto) {
return this.ticketService.updateStatusAsAdmin(id, dto);
}
@Delete('admin/tickets/:id')
@UseGuards(AdminAuthGuard)
@Permissions(PermissionEnum.MANAGE_TICKETS)
+25
View File
@@ -2,8 +2,10 @@ import { Injectable, NotFoundException, ForbiddenException } from '@nestjs/commo
import { EntityManager } from '@mikro-orm/postgresql';
import { CreateTicketDto } from './dto/create-ticket.dto';
import { UpdateTicketDto } from './dto/update-ticket.dto';
import { UpdateTicketStatusDto } from './dto/update-ticket-status.dto';
import { CreateTicketUserDto } from './dto/create-ticket-user.dto';
import { UpdateTicketUserDto } from './dto/update-ticket-user.dto';
import { UpdateTicketStatusUserDto } from './dto/update-ticket-status-user.dto';
import { SearchTicketQueryDto } from './dto/search-ticket-query.dto';
import { Ticket } from './entities/ticket.entity';
import { TicketRepository } from './repositories/ticket.repository';
@@ -165,6 +167,29 @@ export class TicketService {
return ticket;
}
async updateStatusAsAdmin(id: string, dto: UpdateTicketStatusDto) {
const ticket = await this.ticketRepository.findOne({ id }, { filters: ['notDeleted'] });
if (!ticket) {
throw new NotFoundException('Ticket not found');
}
ticket.status = dto.status;
await this.em.flush();
return ticket;
}
async updateStatusAsUser(id: string, _dto: UpdateTicketStatusUserDto, userId: string) {
const ticket = await this.ticketRepository.findOne({ id }, { filters: ['notDeleted'] });
if (!ticket) {
throw new NotFoundException('Ticket not found');
}
if (ticket.user?.id !== userId) {
throw new ForbiddenException('You can only update your own tickets');
}
ticket.status = TicketStatusEnum.CLOSED;
await this.em.flush();
return ticket;
}
async remove(id: string) {
const ticket = await this.ticketRepository.findOne({ id }, { filters: ['notDeleted'] });
if (!ticket) {