From a1c03a479d7b52a7b04b79a95d65a5271ac7ef53 Mon Sep 17 00:00:00 2001 From: hobiJeong Date: Mon, 4 Dec 2023 13:16:24 +0900 Subject: [PATCH] feat/#66: update notice-board put method --- .../controllers/notice-boards.controller.ts | 18 +++++ .../dto/put-update-notice-board.dto.ts | 14 ++++ .../services/notice-boards.service.ts | 76 +++++++++++++++++++ 3 files changed, 108 insertions(+) create mode 100644 src/apis/notice-boards/dto/put-update-notice-board.dto.ts diff --git a/src/apis/notice-boards/controllers/notice-boards.controller.ts b/src/apis/notice-boards/controllers/notice-boards.controller.ts index f14c226f..a15abb5a 100644 --- a/src/apis/notice-boards/controllers/notice-boards.controller.ts +++ b/src/apis/notice-boards/controllers/notice-boards.controller.ts @@ -7,6 +7,7 @@ import { // Get, // Patch, Post, + Put, Query, UseGuards, } from '@nestjs/common'; @@ -24,6 +25,7 @@ import { UserDto } from '@src/apis/users/dto/user.dto'; import { User } from '@src/decorators/user.decorator'; import { ParsePositiveIntPipe } from '@src/pipes/parse-positive-int.pipe'; import { NoticeBoardDto } from '../dto/notice-board.dto'; +import { PutUpdateNoticeBoardDto } from '../dto/put-update-notice-board.dto'; @ApiTags('notice-boards') @Controller('notice-boards') @@ -65,6 +67,22 @@ export class NoticeBoardsController { return this.noticeBoardService.findOneOrNotFound(noticeBoardId); } + @ApiNoticeBoard.PutUpdate({ summary: '공지게시글 수정' }) + @SetResponse({ key: 'noticeBoard', type: ResponseType.Detail }) + @UseGuards(JwtAuthGuard) + @Put(':noticeBoardId') + putUpdate( + @Param('noticeBoardId', ParsePositiveIntPipe) noticeBoardId: number, + @User() user: UserDto, + @Body() putUpdateNoticeBoardDto: PutUpdateNoticeBoardDto, + ) { + return this.noticeBoardService.putUpdate( + noticeBoardId, + user.id, + putUpdateNoticeBoardDto, + ); + } + // @Patch(':id') // update() {} diff --git a/src/apis/notice-boards/dto/put-update-notice-board.dto.ts b/src/apis/notice-boards/dto/put-update-notice-board.dto.ts new file mode 100644 index 00000000..df7520c4 --- /dev/null +++ b/src/apis/notice-boards/dto/put-update-notice-board.dto.ts @@ -0,0 +1,14 @@ +import { ApiProperty, PickType } from '@nestjs/swagger'; +import { CreateNoticeBoardDto } from './create-notice-board.dto'; +import { IsBoolean } from 'class-validator'; + +export class PutUpdateNoticeBoardDto extends PickType(CreateNoticeBoardDto, [ + 'title', + 'description', +] as const) { + @ApiProperty({ + description: '댓글 허용 여부', + }) + @IsBoolean() + allowComment: boolean; +} diff --git a/src/apis/notice-boards/services/notice-boards.service.ts b/src/apis/notice-boards/services/notice-boards.service.ts index 5c1a4f84..2fa57821 100644 --- a/src/apis/notice-boards/services/notice-boards.service.ts +++ b/src/apis/notice-boards/services/notice-boards.service.ts @@ -11,6 +11,8 @@ import { FindNoticeBoardListQueryDto } from '../dto/find-notice-board-list-query import { NoticeBoardsItemDto } from '../dto/notice-boards-item.dto'; import { NoticeBoardHistoryService } from '../notice-board-history/services/notice-board-history.service'; import { HttpNotFoundException } from '@src/http-exceptions/exceptions/http-not-found.exception'; +import { PutUpdateNoticeBoardDto } from '../dto/put-update-notice-board.dto'; +import { HttpForbiddenException } from '@src/http-exceptions/exceptions/http-forbidden.exception'; @Injectable() export class NoticeBoardsService { @@ -115,4 +117,78 @@ export class NoticeBoardsService { return new NoticeBoardDto(noticeBoard); } + + async putUpdate( + noticeBoardId: number, + userId: number, + putUpdateNoticeBoardDto: PutUpdateNoticeBoardDto, + ): Promise { + const existBoard = await this.noticeBoardRepository.findOne({ + select: { userId: true }, + where: { id: noticeBoardId }, + }); + + if (!existBoard) { + throw new HttpNotFoundException({ + code: COMMON_ERROR_CODE.RESOURCE_NOT_FOUND, + }); + } + + if (existBoard.userId !== userId) { + throw new HttpForbiddenException({ + code: COMMON_ERROR_CODE.PERMISSION_DENIED, + }); + } + + const queryRunner = this.dataSource.createQueryRunner(); + + queryRunner.connect(); + queryRunner.startTransaction(); + + try { + const entityManager = queryRunner.manager; + await entityManager.withRepository(this.noticeBoardRepository).update( + { + id: noticeBoardId, + }, + { + ...putUpdateNoticeBoardDto, + }, + ); + + const newPost = await entityManager + .withRepository(this.noticeBoardRepository) + .findOneByOrFail({ id: noticeBoardId }); + + await this.noticeBoardHistoryService.create( + entityManager, + userId, + noticeBoardId, + { + title: newPost.title, + description: newPost.description, + allowComment: newPost.allowComment, + }, + ); + + await queryRunner.commitTransaction(); + + return new NoticeBoardDto(newPost); + } catch (error) { + if (queryRunner.isTransactionActive) { + queryRunner.rollbackTransaction(); + } + + console.error(error); + throw new HttpInternalServerErrorException({ + code: COMMON_ERROR_CODE.SERVER_ERROR, + stack: error.stack, + ctx: '공지게시글 업데이트 중 알 수 없는 에러', + }); + } finally { + if (!queryRunner.isReleased) { + await queryRunner.release(); + } + } + } }