From b10e3c07000f805ce48d8de9477965ec4ba1cbc2 Mon Sep 17 00:00:00 2001 From: Chooooooo Date: Fri, 16 Feb 2024 00:21:11 +0900 Subject: [PATCH 1/8] =?UTF-8?q?Feat:=20=ED=86=A0=EC=9D=B5=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=EC=97=90=EC=84=9C=20ResponseEntity=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CRUD 기능을 위한 API 추가 - 토익 문제를 추가하고 수정하고 삭제하는 기능을 추가했습니다. - Response Entity를 적용하여 클라이언트에게 응답을 보내는 기능을 추가했습니다. Related to #35 --- .../backend/src/toeic/toeic.controller.ts | 51 +++++++++++++++++-- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/packages/backend/src/toeic/toeic.controller.ts b/packages/backend/src/toeic/toeic.controller.ts index cf7e21c..165853d 100644 --- a/packages/backend/src/toeic/toeic.controller.ts +++ b/packages/backend/src/toeic/toeic.controller.ts @@ -1,6 +1,16 @@ -import { Controller, Get, Param } from '@nestjs/common'; +import { + Body, + Controller, + Delete, + Get, + Param, + ParseIntPipe, + Patch, +} from '@nestjs/common'; import { ToeicService } from './toeic.service'; import { ApiSwagger } from '../common/swagger/api.decorator'; +import { ResponseEntity } from '../common/entity/response.entity'; +import { PatchToeicWithQuestion } from './dto/patch-quesion.dto'; @Controller('toeic') export class ToeicController { @@ -8,13 +18,44 @@ export class ToeicController { @Get() @ApiSwagger({ name: '토익 문제 조회' }) - findAll() { - return this.toeicService.findAll(); + async findAll() { + const result = await this.toeicService.findAll(); + return ResponseEntity.OK_WITH( + `Successfully find ${result.length} questsions`, + result, + ); } @Get('/:id') @ApiSwagger({ name: '토익 문제 조회' }) - findOne(@Param('id') id: number) { - return this.toeicService.findOne(+id); + async findOne(@Param('id', ParseIntPipe) id: number) { + const result = await this.toeicService.findOne(+id); + return ResponseEntity.OK_WITH( + `Successfully find question id: ${id}.`, + result, + ); + } + + @Patch('/:id') + @ApiSwagger({ name: '토익 문제 수정' }) + updateOne( + @Param('id', ParseIntPipe) id: number, + @Body() request: PatchToeicWithQuestion, + ) { + const result = this.toeicService.updateOne(+id, request.toEntity()); + return ResponseEntity.OK_WITH( + `Successfully update question id: ${id}.`, + result, + ); + } + + @Delete('/:id') + @ApiSwagger({ name: '토익 문제 수정' }) + deleteOne(@Param('id', ParseIntPipe) id: number) { + const result = this.toeicService.deleteOne(+id); + return ResponseEntity.OK_WITH( + `Successfully delete question id: ${id}.`, + result, + ); } } From d428d310499f878827148180abf4aa6985d46bfb Mon Sep 17 00:00:00 2001 From: Chooooooo Date: Sat, 17 Feb 2024 00:24:11 +0900 Subject: [PATCH 2/8] =?UTF-8?q?Refact:=20=EC=97=85=EB=8D=B0=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Data로 끝나는 Dto 이름을 변경 - 문제 수정에 수정 요청 바디 추가 Related to #35 --- packages/backend/src/toeic/toeic.service.ts | 17 ++++++++--------- packages/backend/src/upload/dto/upload.dto.ts | 4 ++-- packages/backend/src/upload/upload.interface.ts | 4 ++-- packages/backend/src/upload/upload.service.ts | 6 +++--- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/packages/backend/src/toeic/toeic.service.ts b/packages/backend/src/toeic/toeic.service.ts index 8effcdd..56a790b 100644 --- a/packages/backend/src/toeic/toeic.service.ts +++ b/packages/backend/src/toeic/toeic.service.ts @@ -1,18 +1,19 @@ import { Injectable } from '@nestjs/common'; -import { UploadedSheetData } from '../upload/dto/upload.dto'; +import { UploadedQuestionInSheet } from '../upload/dto/upload.dto'; import { PrismaService } from '../prisma/prisma.service'; +import { PatchQuestionToEntity } from './toeic.interface'; @Injectable() export class ToeicService { constructor(private prisma: PrismaService) {} - async create(filename: string, sheetData: UploadedSheetData) { + async create(filename: string, questionInSheet: UploadedQuestionInSheet) { return this.prisma.toeic.create({ data: { filename, - title: sheetData.title, + title: questionInSheet.title, questions: { - create: sheetData.data, + create: questionInSheet.data, }, }, }); @@ -23,7 +24,7 @@ export class ToeicService { } async findOne(id: number) { - return this.prisma.toeic.findUnique({ + return this.prisma.toeic.findUniqueOrThrow({ where: { id, }, @@ -44,14 +45,12 @@ export class ToeicService { }); } - async updateOne(id: number) { + async updateOne(id: number, data: PatchQuestionToEntity) { return this.prisma.toeic.update({ where: { id, }, - data: { - is_public: false, - }, + data, }); } } diff --git a/packages/backend/src/upload/dto/upload.dto.ts b/packages/backend/src/upload/dto/upload.dto.ts index d11fbb9..d28a807 100644 --- a/packages/backend/src/upload/dto/upload.dto.ts +++ b/packages/backend/src/upload/dto/upload.dto.ts @@ -1,7 +1,7 @@ import { ApiProperty } from '@nestjs/swagger'; -import { Question, UploadedQuestionSheet } from '../upload.interface'; +import { Question, UploadedSheetProps } from '../upload.interface'; -export class UploadedSheetData implements UploadedQuestionSheet { +export class UploadedQuestionInSheet implements UploadedSheetProps { @ApiProperty({ description: '엑셀파일 시트 이름입니다.', required: true, diff --git a/packages/backend/src/upload/upload.interface.ts b/packages/backend/src/upload/upload.interface.ts index 0a61770..e489473 100644 --- a/packages/backend/src/upload/upload.interface.ts +++ b/packages/backend/src/upload/upload.interface.ts @@ -1,6 +1,6 @@ import { Database } from 'src/supabase/schema/database.schema'; -export interface UploadedQuestionSheet { +export interface UploadedSheetProps { title: Database['public']['Tables']['toeic']['Row']['title']; data: Question[]; } @@ -17,5 +17,5 @@ export interface QuestionInFile { size: number; name: string; questionAmount: number; - sheets: UploadedQuestionSheet[]; + sheets: UploadedSheetProps[]; } diff --git a/packages/backend/src/upload/upload.service.ts b/packages/backend/src/upload/upload.service.ts index 31dab50..2ae7dc1 100644 --- a/packages/backend/src/upload/upload.service.ts +++ b/packages/backend/src/upload/upload.service.ts @@ -1,13 +1,13 @@ import { Injectable } from '@nestjs/common'; import { WorkBook, utils } from 'xlsx'; -import { UploadedSheetData } from './dto/upload.dto'; +import { UploadedQuestionInSheet } from './dto/upload.dto'; @Injectable() export class UploadService { - sheetToQuestions(workbook: WorkBook): UploadedSheetData[] { + sheetToQuestions(workbook: WorkBook): UploadedQuestionInSheet[] { return workbook.SheetNames.map( (title) => - new UploadedSheetData( + new UploadedQuestionInSheet( title, utils.sheet_to_json(workbook.Sheets[title]), ), From a6f5c504903d4e8e90a0350c3547fa3f0d4e1084 Mon Sep 17 00:00:00 2001 From: Chooooooo Date: Sun, 18 Feb 2024 00:26:10 +0900 Subject: [PATCH 3/8] =?UTF-8?q?Feat:=20=ED=86=A0=EC=9D=B5=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=EC=88=98=EC=A0=95=20=EC=9D=B8=ED=84=B0=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 수정 요청용 Body dto 추가 - 토익 문제 수정 시 필요한 인터페이스 추가 Related to #35 --- .../src/toeic/dto/patch-quesion.dto.ts | 119 ++++++++++++++++++ packages/backend/src/toeic/toeic.interface.ts | 29 +++++ 2 files changed, 148 insertions(+) create mode 100644 packages/backend/src/toeic/dto/patch-quesion.dto.ts create mode 100644 packages/backend/src/toeic/toeic.interface.ts diff --git a/packages/backend/src/toeic/dto/patch-quesion.dto.ts b/packages/backend/src/toeic/dto/patch-quesion.dto.ts new file mode 100644 index 0000000..c443836 --- /dev/null +++ b/packages/backend/src/toeic/dto/patch-quesion.dto.ts @@ -0,0 +1,119 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { Type } from 'class-transformer'; +import { + IsArray, + IsBoolean, + IsNotEmpty, + IsNumber, + IsOptional, + IsString, + IsUUID, + MaxLength, + MinLength, + ValidateNested, +} from 'class-validator'; +import { + PatchQuestionToEntity, + QuestionWithId, + ToeicReqBodyProps, +} from '../toeic.interface'; + +export class PatchToeicWithQuestion implements ToeicReqBodyProps { + @ApiProperty({ + description: '토익 문제 제목입니다.', + example: '해커스 토익 실전 1회', + }) + @IsString() + @MinLength(2) + @MaxLength(32) + @IsOptional() + @Type(() => String) + title: string; + + @ApiProperty({ + description: '토익 문제 공개 여부입니다.', + }) + @IsBoolean() + @Type(() => Boolean) + @IsOptional() + is_public: boolean; + + @ApiProperty({ + description: '토익 문제입니다.', + }) + @IsArray() + @ValidateNested({ each: true }) + @Type(() => PatchQuestion) + questions: PatchQuestion[]; + + toEntity(): PatchQuestionToEntity { + return { + title: this.title, + is_public: this.is_public, + questions: { + update: this.questions.map((question) => ({ + where: { id: question.id }, + data: { + question_number: question.question_number, + answer: question.answer, + content: question.content, + choice: question.choice, + translation: question.translation, + }, + })), + }, + }; + } +} + +export class PatchQuestion implements QuestionWithId { + @ApiProperty({ + description: '문제 DB 고유 ID입니다.', + example: 'uuid', + }) + @IsString() + @IsNotEmpty() + @IsUUID() + id: string; + + @ApiProperty({ + description: '문제 번호입니다.', + example: 1, + }) + @Type(() => Number) + @IsNumber() + question_number: number; + + @ApiProperty({ + description: '정답입니다.', + example: 'A', + }) + @IsString() + @MaxLength(1) + @IsOptional() + answer: string; + + @ApiProperty({ + description: '문제입니다.', + example: '문제입니다.', + }) + @IsString() + @IsOptional() + content: string; + + @ApiProperty({ + description: '선택지입니다.', + example: '(A) --- (B) --- (C) --- (D) ---.', + }) + @IsString() + @IsOptional() + choice: string; + + @ApiProperty({ + description: '문제 한글 번역입니다.', + example: '문제 한글 번역입니다.', + }) + @IsString() + @IsOptional() + translation: string; +} diff --git a/packages/backend/src/toeic/toeic.interface.ts b/packages/backend/src/toeic/toeic.interface.ts new file mode 100644 index 0000000..bd98316 --- /dev/null +++ b/packages/backend/src/toeic/toeic.interface.ts @@ -0,0 +1,29 @@ +import { Question } from '../upload/upload.interface'; + +export interface ToeicReqBodyProps { + title: string; + is_public: boolean; + questions: QuestionWithId[]; +} + +export interface QuestionWithId extends Question { + id: string; +} + +export interface PatchQuestionToEntity + extends Omit { + questions: { + update: { + where: { + id: string; + }; + data: { + question_number: number; + answer: string; + content: string; + choice: string; + translation: string; + }; + }[]; + }; +} From 2f4c3416c88156f3e90071fe8af0f12ff2e61e6c Mon Sep 17 00:00:00 2001 From: Chooooooo Date: Mon, 19 Feb 2024 16:59:27 +0900 Subject: [PATCH 4/8] =?UTF-8?q?Refact=20:=20=EC=BB=A8=ED=8A=B8=EB=A1=A4?= =?UTF-8?q?=EB=9F=AC=EC=97=90=EC=84=9C=20=EC=83=81=EC=84=B8=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20swagger=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 조회 -> 상세 조회로 변경 --- packages/backend/src/toeic/toeic.controller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/toeic/toeic.controller.ts b/packages/backend/src/toeic/toeic.controller.ts index 165853d..64b3f27 100644 --- a/packages/backend/src/toeic/toeic.controller.ts +++ b/packages/backend/src/toeic/toeic.controller.ts @@ -27,7 +27,7 @@ export class ToeicController { } @Get('/:id') - @ApiSwagger({ name: '토익 문제 조회' }) + @ApiSwagger({ name: '토익 문제 상세 조회' }) async findOne(@Param('id', ParseIntPipe) id: number) { const result = await this.toeicService.findOne(+id); return ResponseEntity.OK_WITH( From ae9c06d07585e77dddb305253075b0bcb1ea8ba6 Mon Sep 17 00:00:00 2001 From: Chooooooo Date: Mon, 19 Feb 2024 16:59:27 +0900 Subject: [PATCH 5/8] =?UTF-8?q?Refact=20:=20=EC=BB=A8=ED=8A=B8=EB=A1=A4?= =?UTF-8?q?=EB=9F=AC=EC=97=90=EC=84=9C=20=EC=83=81=EC=84=B8=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20swagger=20=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 조회 -> 상세 조회로 변경 Related to #35 --- packages/backend/src/toeic/toeic.controller.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/backend/src/toeic/toeic.controller.ts b/packages/backend/src/toeic/toeic.controller.ts index 64b3f27..1c4e76c 100644 --- a/packages/backend/src/toeic/toeic.controller.ts +++ b/packages/backend/src/toeic/toeic.controller.ts @@ -11,7 +11,9 @@ import { ToeicService } from './toeic.service'; import { ApiSwagger } from '../common/swagger/api.decorator'; import { ResponseEntity } from '../common/entity/response.entity'; import { PatchToeicWithQuestion } from './dto/patch-quesion.dto'; +import { ApiTags } from '@nestjs/swagger'; +@ApiTags('토익 문제') @Controller('toeic') export class ToeicController { constructor(private readonly toeicService: ToeicService) {} From 33cb986699e5a2aa4095e3454def064625972459 Mon Sep 17 00:00:00 2001 From: Chooooooo Date: Tue, 20 Feb 2024 20:40:59 +0900 Subject: [PATCH 6/8] =?UTF-8?q?Refact:=20=ED=86=A0=EC=9D=B5=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=EB=A6=AC=ED=8C=A9=ED=84=B0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 토익 문제 수정, 삭제시 매니저 권한이 필요하도록 수정 Related to #35 --- packages/backend/src/toeic/toeic.controller.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/toeic/toeic.controller.ts b/packages/backend/src/toeic/toeic.controller.ts index 1c4e76c..a6d1b18 100644 --- a/packages/backend/src/toeic/toeic.controller.ts +++ b/packages/backend/src/toeic/toeic.controller.ts @@ -12,6 +12,8 @@ import { ApiSwagger } from '../common/swagger/api.decorator'; import { ResponseEntity } from '../common/entity/response.entity'; import { PatchToeicWithQuestion } from './dto/patch-quesion.dto'; import { ApiTags } from '@nestjs/swagger'; +import { Role } from '../auth/constant/roles.enum'; +import { Roles } from '../auth/decorator/roles.decorator'; @ApiTags('토익 문제') @Controller('toeic') @@ -39,6 +41,7 @@ export class ToeicController { } @Patch('/:id') + @Roles([Role.MANAGER]) @ApiSwagger({ name: '토익 문제 수정' }) updateOne( @Param('id', ParseIntPipe) id: number, @@ -52,7 +55,8 @@ export class ToeicController { } @Delete('/:id') - @ApiSwagger({ name: '토익 문제 수정' }) + @Roles([Role.MANAGER]) + @ApiSwagger({ name: '토익 문제 삭제' }) deleteOne(@Param('id', ParseIntPipe) id: number) { const result = this.toeicService.deleteOne(+id); return ResponseEntity.OK_WITH( From a9333219f374a8b2d8702c117787ad264db0165d Mon Sep 17 00:00:00 2001 From: Chooooooo Date: Wed, 21 Feb 2024 21:01:14 +0900 Subject: [PATCH 7/8] =?UTF-8?q?Feat:=20=EB=AC=B8=EC=A0=9C=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=EC=A1=B0=ED=9A=8C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 토익 내의 문제 상세 조회 기능을 추가했습니다. - 문제 상세 조회를 위한 API를 추가했습니다. - 메서드 이름을 변경했습니다. Related to #35 --- .../backend/src/toeic/toeic.controller.ts | 25 +++++++++++++------ packages/backend/src/toeic/toeic.service.ts | 21 ++++++++++++---- .../backend/src/upload/upload.controller.ts | 2 +- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/packages/backend/src/toeic/toeic.controller.ts b/packages/backend/src/toeic/toeic.controller.ts index a6d1b18..4103d85 100644 --- a/packages/backend/src/toeic/toeic.controller.ts +++ b/packages/backend/src/toeic/toeic.controller.ts @@ -5,6 +5,7 @@ import { Get, Param, ParseIntPipe, + ParseUUIDPipe, Patch, } from '@nestjs/common'; import { ToeicService } from './toeic.service'; @@ -23,17 +24,27 @@ export class ToeicController { @Get() @ApiSwagger({ name: '토익 문제 조회' }) async findAll() { - const result = await this.toeicService.findAll(); + const result = await this.toeicService.findAllToeic(); return ResponseEntity.OK_WITH( `Successfully find ${result.length} questsions`, result, ); } + @Get('question/:uuid') + @ApiSwagger({ name: '문제 아이디로 상세 조회' }) + async findQuestionUnique(@Param('uuid', ParseUUIDPipe) uuid: string) { + const result = await this.toeicService.findQuestionUnique(uuid); + return ResponseEntity.OK_WITH( + `Successfully find question number ${result.question_number} in toeic id ${result.toeic_id}.`, + result, + ); + } + @Get('/:id') @ApiSwagger({ name: '토익 문제 상세 조회' }) - async findOne(@Param('id', ParseIntPipe) id: number) { - const result = await this.toeicService.findOne(+id); + async findToeicUnique(@Param('id', ParseIntPipe) id: number) { + const result = await this.toeicService.findToeicUnique(+id); return ResponseEntity.OK_WITH( `Successfully find question id: ${id}.`, result, @@ -43,11 +54,11 @@ export class ToeicController { @Patch('/:id') @Roles([Role.MANAGER]) @ApiSwagger({ name: '토익 문제 수정' }) - updateOne( + updateToeicUnique( @Param('id', ParseIntPipe) id: number, @Body() request: PatchToeicWithQuestion, ) { - const result = this.toeicService.updateOne(+id, request.toEntity()); + const result = this.toeicService.updateToeicUnique(+id, request.toEntity()); return ResponseEntity.OK_WITH( `Successfully update question id: ${id}.`, result, @@ -57,8 +68,8 @@ export class ToeicController { @Delete('/:id') @Roles([Role.MANAGER]) @ApiSwagger({ name: '토익 문제 삭제' }) - deleteOne(@Param('id', ParseIntPipe) id: number) { - const result = this.toeicService.deleteOne(+id); + deleteToeicUnique(@Param('id', ParseIntPipe) id: number) { + const result = this.toeicService.deleteToeicUnique(+id); return ResponseEntity.OK_WITH( `Successfully delete question id: ${id}.`, result, diff --git a/packages/backend/src/toeic/toeic.service.ts b/packages/backend/src/toeic/toeic.service.ts index 56a790b..b2d454a 100644 --- a/packages/backend/src/toeic/toeic.service.ts +++ b/packages/backend/src/toeic/toeic.service.ts @@ -7,7 +7,10 @@ import { PatchQuestionToEntity } from './toeic.interface'; export class ToeicService { constructor(private prisma: PrismaService) {} - async create(filename: string, questionInSheet: UploadedQuestionInSheet) { + async createToeic( + filename: string, + questionInSheet: UploadedQuestionInSheet, + ) { return this.prisma.toeic.create({ data: { filename, @@ -19,11 +22,11 @@ export class ToeicService { }); } - async findAll() { + async findAllToeic() { return this.prisma.toeic.findMany(); } - async findOne(id: number) { + async findToeicUnique(id: number) { return this.prisma.toeic.findUniqueOrThrow({ where: { id, @@ -34,7 +37,7 @@ export class ToeicService { }); } - async deleteOne(id: number) { + async deleteToeicUnique(id: number) { return this.prisma.toeic.update({ where: { id, @@ -45,7 +48,7 @@ export class ToeicService { }); } - async updateOne(id: number, data: PatchQuestionToEntity) { + async updateToeicUnique(id: number, data: PatchQuestionToEntity) { return this.prisma.toeic.update({ where: { id, @@ -53,4 +56,12 @@ export class ToeicService { data, }); } + + async findQuestionUnique(uuid: string) { + return this.prisma.question.findUniqueOrThrow({ + where: { + id: uuid, + }, + }); + } } diff --git a/packages/backend/src/upload/upload.controller.ts b/packages/backend/src/upload/upload.controller.ts index 635240f..e6278cd 100644 --- a/packages/backend/src/upload/upload.controller.ts +++ b/packages/backend/src/upload/upload.controller.ts @@ -40,7 +40,7 @@ export class UploadController { file: QuestionInFile, ) { file.sheets.map(async (sheet) => { - await this.toeicService.create(file.name, sheet); + await this.toeicService.createToeic(file.name, sheet); }); return ResponseEntity.CREATED_WITH( From 86fae1ed41d9732668a8e3e1fb95343a74d998cb Mon Sep 17 00:00:00 2001 From: Chooooooo Date: Fri, 23 Feb 2024 21:43:40 +0900 Subject: [PATCH 8/8] =?UTF-8?q?Refact:=20=ED=86=A0=EC=9D=B5=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=EC=A1=B0=ED=9A=8C=20API=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 토익 문제 조회 API에서 Query 파라미터 옵션 추가 - 기본으로 공개된 문제만 조회하도록 변경 Related to #35 --- .../src/toeic/dto/req-toeic-query.dto.ts | 24 +++++++++++++++++++ .../backend/src/toeic/toeic.controller.ts | 6 +++-- packages/backend/src/toeic/toeic.interface.ts | 4 ++++ packages/backend/src/toeic/toeic.service.ts | 6 ++--- 4 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 packages/backend/src/toeic/dto/req-toeic-query.dto.ts diff --git a/packages/backend/src/toeic/dto/req-toeic-query.dto.ts b/packages/backend/src/toeic/dto/req-toeic-query.dto.ts new file mode 100644 index 0000000..1e2e426 --- /dev/null +++ b/packages/backend/src/toeic/dto/req-toeic-query.dto.ts @@ -0,0 +1,24 @@ +import { ApiProperty } from '@nestjs/swagger'; +import { IsOptional, Max, Min } from 'class-validator'; +import { ToeicWhereInputProps } from '../toeic.interface'; +import { Type } from 'class-transformer'; + +export class ToeicQueryParam { + @ApiProperty({ + description: '문제 공개 여부 (0: 비공개, 1: 공개)', + required: false, + default: 1, + }) + @Min(0) + @Max(1) + @IsOptional() + @Type(() => Number) + isPublic: number; + + getQueryProps(): ToeicWhereInputProps { + return { + is_public: + typeof this.isPublic === 'undefined' ? true : Boolean(this.isPublic), + }; + } +} diff --git a/packages/backend/src/toeic/toeic.controller.ts b/packages/backend/src/toeic/toeic.controller.ts index 4103d85..8ca4411 100644 --- a/packages/backend/src/toeic/toeic.controller.ts +++ b/packages/backend/src/toeic/toeic.controller.ts @@ -7,6 +7,7 @@ import { ParseIntPipe, ParseUUIDPipe, Patch, + Query, } from '@nestjs/common'; import { ToeicService } from './toeic.service'; import { ApiSwagger } from '../common/swagger/api.decorator'; @@ -15,6 +16,7 @@ import { PatchToeicWithQuestion } from './dto/patch-quesion.dto'; import { ApiTags } from '@nestjs/swagger'; import { Role } from '../auth/constant/roles.enum'; import { Roles } from '../auth/decorator/roles.decorator'; +import { ToeicQueryParam } from './dto/req-toeic-query.dto'; @ApiTags('토익 문제') @Controller('toeic') @@ -23,8 +25,8 @@ export class ToeicController { @Get() @ApiSwagger({ name: '토익 문제 조회' }) - async findAll() { - const result = await this.toeicService.findAllToeic(); + async findAll(@Query() query: ToeicQueryParam) { + const result = await this.toeicService.findAllToeic(query.getQueryProps()); return ResponseEntity.OK_WITH( `Successfully find ${result.length} questsions`, result, diff --git a/packages/backend/src/toeic/toeic.interface.ts b/packages/backend/src/toeic/toeic.interface.ts index bd98316..dc52287 100644 --- a/packages/backend/src/toeic/toeic.interface.ts +++ b/packages/backend/src/toeic/toeic.interface.ts @@ -27,3 +27,7 @@ export interface PatchQuestionToEntity }[]; }; } + +export interface ToeicWhereInputProps { + is_public: boolean; +} diff --git a/packages/backend/src/toeic/toeic.service.ts b/packages/backend/src/toeic/toeic.service.ts index b2d454a..f38c60d 100644 --- a/packages/backend/src/toeic/toeic.service.ts +++ b/packages/backend/src/toeic/toeic.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common'; import { UploadedQuestionInSheet } from '../upload/dto/upload.dto'; import { PrismaService } from '../prisma/prisma.service'; -import { PatchQuestionToEntity } from './toeic.interface'; +import { PatchQuestionToEntity, ToeicWhereInputProps } from './toeic.interface'; @Injectable() export class ToeicService { @@ -22,8 +22,8 @@ export class ToeicService { }); } - async findAllToeic() { - return this.prisma.toeic.findMany(); + async findAllToeic(where: ToeicWhereInputProps) { + return this.prisma.toeic.findMany({ where }); } async findToeicUnique(id: number) {