From b783d3e9ef0f502b63dd8216aa4688e8982f83f0 Mon Sep 17 00:00:00 2001 From: qkrwogk Date: Thu, 7 Dec 2023 16:34:53 +0900 Subject: [PATCH 1/7] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20remove=20meaningless?= =?UTF-8?q?=20imports?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 필요없는 임포트 제거 --- packages/server/src/board/entities/board.entity.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/server/src/board/entities/board.entity.ts b/packages/server/src/board/entities/board.entity.ts index b192809..9ea16a9 100644 --- a/packages/server/src/board/entities/board.entity.ts +++ b/packages/server/src/board/entities/board.entity.ts @@ -3,12 +3,10 @@ import { Column, CreateDateColumn, Entity, - JoinColumn, JoinTable, ManyToMany, ManyToOne, OneToMany, - OneToOne, PrimaryGeneratedColumn, UpdateDateColumn, } from 'typeorm'; From 80142e40dcd1f43ed9d3f4b460b953c1b53ca0df Mon Sep 17 00:00:00 2001 From: qkrwogk Date: Thu, 7 Dec 2023 16:43:15 +0900 Subject: [PATCH 2/7] =?UTF-8?q?=E2=9C=85=20e2e=20test=20on=20sentiment=20m?= =?UTF-8?q?odule?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 감정 분석 모듈에 대한 e2e 테스트 코드 작성 --- .../test/sentiment/sentiment.e2e-spec.ts | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 packages/server/test/sentiment/sentiment.e2e-spec.ts diff --git a/packages/server/test/sentiment/sentiment.e2e-spec.ts b/packages/server/test/sentiment/sentiment.e2e-spec.ts new file mode 100644 index 0000000..c902dfd --- /dev/null +++ b/packages/server/test/sentiment/sentiment.e2e-spec.ts @@ -0,0 +1,35 @@ +import { INestApplication } from '@nestjs/common'; +import { Test } from '@nestjs/testing'; +import * as request from 'supertest'; +import { AppModule } from '../../src/app.module'; + +describe('SentimentController', () => { + let app: INestApplication; + + beforeEach(async () => { + const moduleFixture = await Test.createTestingModule({ + imports: [AppModule], + }).compile(); + + app = moduleFixture.createNestApplication(); + await app.init(); + }); + + it('should be defined', () => { + expect(app).toBeDefined(); + }); + + it('POST /sentiment', async () => { + const response = await request(app.getHttpServer()) + .post('/sentiment') + .send({ content: 'test' }) + .expect(200); + + expect(response).toHaveProperty('body'); + const { body } = response; + expect(body).toHaveProperty('color'); + const { color } = body; + expect(typeof color).toBe('string'); + expect(color.startsWith('#')).toBe(true); + }); +}); From cb378c3bce1fd83c345771d152e9f03689b4178a Mon Sep 17 00:00:00 2001 From: qkrwogk Date: Thu, 7 Dec 2023 16:44:20 +0900 Subject: [PATCH 3/7] =?UTF-8?q?=F0=9F=90=9B=20fix=20bugs=20on=20sentiment?= =?UTF-8?q?=20service?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 감정 분석 간 content가 undefined인 경우에 대한 에러 처리 - import 모듈 경로를 상대경로로 변경하여 테스트 에러 해결 --- packages/server/src/sentiment/sentiment.service.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/server/src/sentiment/sentiment.service.ts b/packages/server/src/sentiment/sentiment.service.ts index f6f130f..14824f5 100644 --- a/packages/server/src/sentiment/sentiment.service.ts +++ b/packages/server/src/sentiment/sentiment.service.ts @@ -1,11 +1,16 @@ -import { Injectable, InternalServerErrorException } from '@nestjs/common'; +import { + BadRequestException, + Injectable, + InternalServerErrorException, +} from '@nestjs/common'; import { GetSentimentDto } from './dto/get-sentiment.dto'; -import { clovaConfig } from 'src/config/clova.config'; +import { clovaConfig } from '../config/clova.config'; @Injectable() export class SentimentService { async getSentiment(body: GetSentimentDto) { const { content } = body; + if (!content) throw new BadRequestException('게시글 내용이 없습니다.'); const response = await fetch(clovaConfig.url, { method: 'POST', From 895ef200e626a5c0c7ac6e5007ad3f5efd6ba10d Mon Sep 17 00:00:00 2001 From: qkrwogk Date: Thu, 7 Dec 2023 19:29:19 +0900 Subject: [PATCH 4/7] =?UTF-8?q?=E2=9C=85=20e2e=20test=20on=20board=20modul?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 보드 모듈에 대한 테스트 코드 작성 --- packages/server/test/board/board.e2e-spec.ts | 262 +++++++++++-------- 1 file changed, 149 insertions(+), 113 deletions(-) diff --git a/packages/server/test/board/board.e2e-spec.ts b/packages/server/test/board/board.e2e-spec.ts index 08176c6..ab27743 100644 --- a/packages/server/test/board/board.e2e-spec.ts +++ b/packages/server/test/board/board.e2e-spec.ts @@ -3,11 +3,15 @@ import { INestApplication } from '@nestjs/common'; import * as request from 'supertest'; import { AppModule } from '../../src/app.module'; import { Board } from '../../src/board/entities/board.entity'; -import { UpdateBoardDto } from 'src/board/dto/update-board.dto'; -import { CreateBoardDto } from 'src/board/dto/create-board.dto'; +import { UpdateBoardDto } from '../../src/board/dto/update-board.dto'; +import { CreateBoardDto } from '../../src/board/dto/create-board.dto'; +import * as cookieParser from 'cookie-parser'; +import { encryptAes } from '../../src/util/aes.util'; describe('BoardController (/board, e2e)', () => { let app: INestApplication; + let accessToken: string; + let post_id: number; beforeEach(async () => { const moduleFixture: TestingModule = await Test.createTestingModule({ @@ -15,137 +19,121 @@ describe('BoardController (/board, e2e)', () => { }).compile(); app = moduleFixture.createNestApplication(); + app.use(cookieParser()); await app.init(); - }); - - // #39 [06-02] 서버는 사용자의 글 데이터를 전송한다. - it('GET /board/:id', async () => { - const response = await request(app.getHttpServer()) - .get('/board/1') - .expect(200); - - expect(response).toHaveProperty('body'); - expect((response as any).body).toHaveProperty('id'); - expect(response.body.id).toBe(1); - expect((response as any).body).toHaveProperty('title'); - expect((response as any).body).toHaveProperty('content'); - expect((response as any).body).toHaveProperty('author'); - expect((response as any).body).toHaveProperty('created_at'); - expect((response as any).body).toHaveProperty('updated_at'); - }); - - // (추가 필요) 서버는 사용자의 글 목록을 전송한다. - it('GET /board', async () => { - const response = await request(app.getHttpServer()) - .get('/board') - .expect(200); - - expect(response).toHaveProperty('body'); - expect(response.body).toBeInstanceOf(Array); - const boards = response.body as Board[]; - if (boards.length > 0) { - expect(boards[0]).toHaveProperty('id'); - expect(boards[0]).toHaveProperty('title'); - } - }); + // 유저 만들고 로그인 후 accessToken 받아오기 + const randomeBytes = Math.random().toString(36).slice(2, 10); - // #45 [06-08] 서버는 좋아요 / 좋아요 취소 요청을 받아 데이터베이스의 데이터를 수정한다. - it('PATCH /board/:id/like', async () => { - const board = { - title: 'test', - content: 'test', - author: 'test', + const newUser = { + username: randomeBytes, + nickname: randomeBytes, + password: randomeBytes, }; - const createdBoard = ( - await request(app.getHttpServer()).post('/board').send(board) - ).body; - expect(createdBoard).toHaveProperty('like_cnt'); - const cntBeforeLike = createdBoard.like_cnt; - const resLike = await request(app.getHttpServer()) - .patch(`/board/${createdBoard.id}/like`) - .expect(200); + await request(app.getHttpServer()).post('/auth/signup').send(newUser); - expect(resLike).toHaveProperty('body'); - expect(resLike.body).toHaveProperty('like_cnt'); - const cntAfterLike = resLike.body.like_cnt; + newUser.nickname = undefined; + const signInResponse = await request(app.getHttpServer()) + .post('/auth/signin') + .send(newUser); - expect(cntAfterLike).toBe(cntBeforeLike + 1); - }); - it('PATCH /board/:id/unlike', async () => { + signInResponse.headers['set-cookie'].forEach((cookie: string) => { + if (cookie.includes('accessToken')) { + accessToken = cookie.split(';')[0].split('=')[1]; + } + }); + + // 별글도 하나 생성 후 수행 const board = { title: 'test', content: 'test', - author: 'test', + star: '{}', }; - const createdBoard = ( - await request(app.getHttpServer()).post('/board').send(board) - ).body; - expect(createdBoard).toHaveProperty('like_cnt'); - const cntBeforeUnlike = createdBoard.like_cnt; - - const resUnlike = await request(app.getHttpServer()) - .patch(`/board/${createdBoard.id}/unlike`) - .expect(200); - - expect(resUnlike).toHaveProperty('body'); - expect(resUnlike.body).toHaveProperty('like_cnt'); - const cntAfterUnlike = resUnlike.body.like_cnt; + const postedBoard = await request(app.getHttpServer()) + .post('/post') + .set('Cookie', [`accessToken=${accessToken}`]) + .send(board); - expect(cntAfterUnlike).toBe(cntBeforeUnlike - 1); + post_id = postedBoard.body.id; }); // #60 [08-06] 서버는 전송 받은 데이터를 데이터베이스에 저장한다. - it('POST /board', async () => { + it('POST /post', async () => { const board = { title: 'test', content: 'test', - author: 'test', + star: '{}', }; const response = await request(app.getHttpServer()) - .post('/board') + .post('/post') + .set('Cookie', [`accessToken=${accessToken}`]) .send(board) .expect(201); expect(response).toHaveProperty('body'); - expect((response as any).body).toMatchObject(board); - expect((response as any).body).toHaveProperty('id'); - expect(typeof response.body.id).toBe('number'); + const { body } = response; + expect(body).toHaveProperty('id'); + expect(typeof body.id).toBe('number'); + expect(body).toHaveProperty('title'); + expect(body.title).toBe(board.title); + expect(body).toHaveProperty('content'); + expect(body.content).toBe(encryptAes(board.content)); // 암호화되었는지 확인 + expect(body).toHaveProperty('star'); + expect(typeof body.star).toBe('string'); }); - // #65 [09-03] 서버는 검색된 사용자의 글 데이터를 전송한다. - it('GET /board/by-author', async () => { - const author = 'testuser'; - const board = { + // #39 [06-02] 서버는 사용자의 글 데이터를 전송한다. + it('GET /post/:id', async () => { + const board: CreateBoardDto = { title: 'test', content: 'test', - author, + star: '{}', }; - await request(app.getHttpServer()).post('/board').send(board); + const newBoard = ( + await request(app.getHttpServer()) + .post('/post') + .set('Cookie', [`accessToken=${accessToken}`]) + .send(board) + ).body; const response = await request(app.getHttpServer()) - .get(`/board/by-author?author=${author}`) + .get(`/post/${newBoard.id}`) .expect(200); expect(response).toHaveProperty('body'); - expect(response.body).toBeInstanceOf(Array); + const { body } = response; + expect(body).toHaveProperty('id'); + expect(body.id).toBe(newBoard.id); + expect(body).toHaveProperty('title'); + expect(body).toHaveProperty('content'); + expect(body).toHaveProperty('like_cnt'); + expect(body).toHaveProperty('images'); + }); + + it('GET /post/:id/is-liked', async () => { + const response = await request(app.getHttpServer()) + .get(`/post/${post_id}/is-liked`) + .set('Cookie', [`accessToken=${accessToken}`]) + .expect(200); - const boards = response.body as Board[]; - expect(boards.length).toBeGreaterThan(0); - expect(boards[0]).toHaveProperty('id'); - expect(boards[0]).toHaveProperty('title'); + expect(response).toHaveProperty('body'); + const { text } = response; + expect(text === 'true' || text === 'false').toBe(true); }); // (추가 필요) 서버는 사용자의 요청에 따라 글을 수정한다. - it('PATCH /board/:id', async () => { + it('PATCH /post/:id', async () => { const board = { title: 'test', content: 'test', - author: 'test', + star: '{}', }; const createdBoard = ( - await request(app.getHttpServer()).post('/board').send(board) + await request(app.getHttpServer()) + .post('/post') + .set('Cookie', [`accessToken=${accessToken}`]) + .send(board) ).body; expect(createdBoard).toHaveProperty('id'); const id = createdBoard.id; @@ -156,8 +144,9 @@ describe('BoardController (/board, e2e)', () => { }; const updated = await request(app.getHttpServer()) - .patch(`/board/${id}`) - .send({ title: 'updated', content: 'updated' }) + .patch(`/post/${id}`) + .set('Cookie', [`accessToken=${accessToken}`]) + .send(toUpdate) .expect(200); expect(updated).toHaveProperty('body'); @@ -168,48 +157,95 @@ describe('BoardController (/board, e2e)', () => { expect(updatedBoard).toHaveProperty('title'); expect(updatedBoard.title).toBe(toUpdate.title); expect(updatedBoard).toHaveProperty('content'); - expect(updatedBoard.content).toBe(toUpdate.content); + expect(updatedBoard.content).toBe(encryptAes(toUpdate.content)); }); - // (추가 필요) 서버는 사용자의 요청에 따라 글을 삭제한다. - it('DELETE /board/:id', async () => { - const board: CreateBoardDto = { + // #45 [06-08] 서버는 좋아요 / 좋아요 취소 요청을 받아 데이터베이스의 데이터를 수정한다. + it('PATCH /post/:id/like', async () => { + const board = { title: 'test', content: 'test', star: '{}', }; - const newBoard = ( - await request(app.getHttpServer()).post('/board').send(board) + + const resCreate = await request(app.getHttpServer()) + .post('/post') + .set('Cookie', [`accessToken=${accessToken}`]) + .send(board); + const createdBoard = resCreate.body; + expect(createdBoard).toHaveProperty('like_cnt'); + const cntBeforeLike = createdBoard.like_cnt; + + const resLike = await request(app.getHttpServer()) + .patch(`/post/${createdBoard.id}/like`) + .set('Cookie', [`accessToken=${accessToken}`]) + .expect(200); + + expect(resLike).toHaveProperty('body'); + expect(resLike.body).toHaveProperty('like_cnt'); + const cntAfterLike = resLike.body.like_cnt; + + expect(cntAfterLike).toBe(cntBeforeLike + 1); + }); + it('PATCH /post/:id/unlike', async () => { + const board = { + title: 'test', + content: 'test', + star: '{}', + }; + const createdBoard = ( + await request(app.getHttpServer()) + .post('/post') + .set('Cookie', [`accessToken=${accessToken}`]) + .send(board) + ).body; + const likedBoard = ( + await request(app.getHttpServer()) + .patch(`/post/${createdBoard.id}/like`) + .set('Cookie', [`accessToken=${accessToken}`]) ).body; - await request(app.getHttpServer()) - .delete(`/board/${newBoard.id}`) + const cntBeforeUnlike = likedBoard.like_cnt; + + const resUnlike = await request(app.getHttpServer()) + .patch(`/post/${createdBoard.id}/unlike`) + .set('Cookie', [`accessToken=${accessToken}`]) .expect(200); - await request(app.getHttpServer()).get(`/board/${newBoard.id}`).expect(404); + expect(resUnlike).toHaveProperty('body'); + expect(resUnlike.body).toHaveProperty('like_cnt'); + const cntAfterUnlike = resUnlike.body.like_cnt; + + expect(cntAfterUnlike).toBe(cntBeforeUnlike - 1); }); - // #61 [08-07] 사진 정보는 스토리지 서버에 저장한다. - it('POST /board/:id/image', async () => { + // (추가 필요) 서버는 사용자의 요청에 따라 글을 삭제한다. + it('DELETE /post/:id', async () => { const board: CreateBoardDto = { title: 'test', content: 'test', star: '{}', }; const newBoard = ( - await request(app.getHttpServer()).post('/board').send(board) + await request(app.getHttpServer()) + .post('/post') + .set('Cookie', [`accessToken=${accessToken}`]) + .send(board) ).body; - const image = Buffer.from('test'); + await request(app.getHttpServer()) + .delete(`/post/${newBoard.id}`) + .set('Cookie', [`accessToken=${accessToken}`]) + .expect(200); - const response = await request(app.getHttpServer()) - .post(`/board/${newBoard.id}/image`) - .attach('file', image, 'test.png') - .expect(201); + await request(app.getHttpServer()).get(`/post/${newBoard.id}`).expect(404); + }); - expect(response).toHaveProperty('body'); - expect((response as any).body).toHaveProperty('id'); - expect(response.body.id).toBe(newBoard.id); - expect((response as any).body).toHaveProperty('filename'); + afterEach(async () => { + // 로그아웃 + await request(app.getHttpServer()) + .post('/auth/signout') + .set('Cookie', [`accessToken=${accessToken}`]); + await app.close(); }); }); From 3ff65bbd6ba6149a05571e54c4871cefd2899ed8 Mon Sep 17 00:00:00 2001 From: qkrwogk Date: Thu, 7 Dec 2023 19:30:46 +0900 Subject: [PATCH 5/7] =?UTF-8?q?=F0=9F=90=9B=20=20await=20all=20board=20con?= =?UTF-8?q?trollers=20before=20response?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 보드 컨트롤러 응답 전에 처리가 완료되도록 개선 --- packages/server/src/board/board.controller.ts | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/server/src/board/board.controller.ts b/packages/server/src/board/board.controller.ts index 4d91df0..e6bbac6 100644 --- a/packages/server/src/board/board.controller.ts +++ b/packages/server/src/board/board.controller.ts @@ -52,13 +52,13 @@ export class BoardController { @UseInterceptors(TransactionInterceptor) @UsePipes(ValidationPipe) @CreateBoardSwaggerDecorator() - createBoard( + async createBoard( @Body() createBoardDto: CreateBoardDto, @GetUser() userData: UserDataDto, @UploadedFiles() files: Express.Multer.File[], @GetQueryRunner() queryRunner: QueryRunner, ): Promise { - return this.boardService.createBoard( + return await this.boardService.createBoard( createBoardDto, userData, files, @@ -97,7 +97,7 @@ export class BoardController { @Param('id', ParseIntPipe) id: number, @GetUser() userData: UserDataDto, ): Promise { - return this.boardService.getIsLiked(id, userData); + return await this.boardService.getIsLiked(id, userData); } // 사진도 수정할 수 있도록 폼데이터 형태로 받기 @@ -107,14 +107,14 @@ export class BoardController { @UseInterceptors(TransactionInterceptor) @UsePipes(ValidationPipe) @UpdateBoardSwaggerDecorator() - updateBoard( + async updateBoard( @Param('id', ParseIntPipe) id: number, @Body() updateBoardDto: UpdateBoardDto, @GetUser() userData: UserDataDto, @UploadedFiles() files: Express.Multer.File[], @GetQueryRunner() queryRunner: QueryRunner, ) { - return this.boardService.updateBoard( + return await this.boardService.updateBoard( id, updateBoardDto, userData, @@ -127,22 +127,22 @@ export class BoardController { @UseGuards(CookieAuthGuard) @UsePipes(ValidationPipe) @PatchLikeSwaggerDecorator() - patchLike( + async patchLike( @Param('id', ParseIntPipe) id: number, @GetUser() userData: UserDataDto, ): Promise> { - return this.boardService.patchLike(id, userData); + return await this.boardService.patchLike(id, userData); } @Patch(':id/unlike') @UseGuards(CookieAuthGuard) @UsePipes(ValidationPipe) @PatchUnlikeSwaggerDecorator() - patchUnlike( + async patchUnlike( @Param('id', ParseIntPipe) id: number, @GetUser() userData: UserDataDto, ): Promise> { - return this.boardService.patchUnlike(id, userData); + return await this.boardService.patchUnlike(id, userData); } // 연관된 Image 및 Star, Like도 함께 삭제 @@ -151,11 +151,11 @@ export class BoardController { @UseInterceptors(TransactionInterceptor) @UsePipes(ValidationPipe) @DeleteBoardSwaggerDecorator() - deleteBoard( + async deleteBoard( @Param('id', ParseIntPipe) id: number, @GetUser() userData: UserDataDto, @GetQueryRunner() queryRunner: QueryRunner, ): Promise { - return this.boardService.deleteBoard(id, userData, queryRunner); + return await this.boardService.deleteBoard(id, userData, queryRunner); } } From 637ac9442c16436d3f8b436d07a85748ea3e9472 Mon Sep 17 00:00:00 2001 From: qkrwogk Date: Thu, 7 Dec 2023 19:32:23 +0900 Subject: [PATCH 6/7] =?UTF-8?q?=F0=9F=90=9B=20handle=20undefined=20or=20em?= =?UTF-8?q?pty=20files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - json request시 undefined로 files가 반환되는 에러를 핸들링하기 위해 조건문 수정 --- packages/server/src/board/board.service.ts | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/packages/server/src/board/board.service.ts b/packages/server/src/board/board.service.ts index 38c60ca..162a263 100644 --- a/packages/server/src/board/board.service.ts +++ b/packages/server/src/board/board.service.ts @@ -25,6 +25,7 @@ import { Model } from 'mongoose'; @Injectable() export class BoardService { constructor( + // private readonly dataSource: DataSource, @InjectRepository(Board) private readonly boardRepository: Repository, @InjectRepository(Image) @@ -41,6 +42,9 @@ export class BoardService { files: Express.Multer.File[], queryRunner: QueryRunner, ): Promise { + // const queryRunner = this.dataSource.createQueryRunner(); + // await queryRunner.startTransaction(); + const { title, content, star } = createBoardDto; const user = await queryRunner.manager.findOneBy(User, { @@ -84,6 +88,8 @@ export class BoardService { const createdBoard: Board = await queryRunner.manager.save(board); createdBoard.user.password = undefined; // password 제거하여 반환 + + // await queryRunner.commitTransaction(); return createdBoard; } @@ -114,6 +120,8 @@ export class BoardService { files: Express.Multer.File[], queryRunner: QueryRunner, ) { + await queryRunner.startTransaction(); + const board: Board = await queryRunner.manager.findOneBy(Board, { id }); if (!board) { throw new NotFoundException(`Not found board with id: ${id}`); @@ -131,7 +139,7 @@ export class BoardService { ); } - if (files.length > 0) { + if (files && files.length > 0) { const images: Image[] = []; for (const file of files) { const imageInfo = await this.uploadFile(file); @@ -165,6 +173,8 @@ export class BoardService { }); delete updatedBoard.user.password; // password 제거하여 반환 + + await queryRunner.commitTransaction(); return updatedBoard; } @@ -237,6 +247,8 @@ export class BoardService { userData: UserDataDto, queryRunner: QueryRunner, ): Promise { + await queryRunner.startTransaction(); + const board: Board = await queryRunner.manager.findOneBy(Board, { id }); if (!board) { @@ -265,6 +277,8 @@ export class BoardService { // 게시글 삭제 const result = await queryRunner.manager.delete(Board, { id }); + + await queryRunner.commitTransaction(); return result; } From 4310454fb1e6e085842264a5e54c321fa51af9c9 Mon Sep 17 00:00:00 2001 From: qkrwogk Date: Thu, 7 Dec 2023 19:44:06 +0900 Subject: [PATCH 7/7] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20transaction=20off?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 일단 내부 트랜잭션 꺼놓고 Transaction Interceptor를 고쳐서 사용하는 방향으로 고민해보자 --- packages/server/src/board/board.service.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/server/src/board/board.service.ts b/packages/server/src/board/board.service.ts index 162a263..54cd90b 100644 --- a/packages/server/src/board/board.service.ts +++ b/packages/server/src/board/board.service.ts @@ -120,7 +120,7 @@ export class BoardService { files: Express.Multer.File[], queryRunner: QueryRunner, ) { - await queryRunner.startTransaction(); + // await queryRunner.startTransaction(); const board: Board = await queryRunner.manager.findOneBy(Board, { id }); if (!board) { @@ -174,7 +174,7 @@ export class BoardService { delete updatedBoard.user.password; // password 제거하여 반환 - await queryRunner.commitTransaction(); + // await queryRunner.commitTransaction(); return updatedBoard; } @@ -247,7 +247,7 @@ export class BoardService { userData: UserDataDto, queryRunner: QueryRunner, ): Promise { - await queryRunner.startTransaction(); + // await queryRunner.startTransaction(); const board: Board = await queryRunner.manager.findOneBy(Board, { id }); @@ -278,7 +278,7 @@ export class BoardService { // 게시글 삭제 const result = await queryRunner.manager.delete(Board, { id }); - await queryRunner.commitTransaction(); + // await queryRunner.commitTransaction(); return result; }