From ebb12cdb1fc42b0c8e7618e2270f949723b202b0 Mon Sep 17 00:00:00 2001 From: Sangmin Lee Date: Mon, 4 Nov 2024 15:56:24 +0900 Subject: [PATCH 1/3] =?UTF-8?q?[DVK-63]=20fix:=20=EC=A0=84=EC=9E=90?= =?UTF-8?q?=EC=B1=85=20API=EC=97=90=20Swagger=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/category/v1/dto/CategoryDto.kt | 5 +- .../backend/common/exception/ErrorResponse.kt | 21 ++ .../ebook/v1/controller/EbookController.kt | 23 +- .../v1/controller/docs/EbookControllerDocs.kt | 303 ++++++++++++++++++ .../ebook/v1/dto/DescriptionImageDto.kt | 6 +- .../backend/ebook/v1/dto/EbookDetailView.kt | 16 + .../devooks/backend/ebook/v1/dto/EbookView.kt | 9 + .../backend/ebook/v1/dto/ReviewView.kt | 4 + .../v1/dto/request/CreateEbookRequest.kt | 9 + .../v1/dto/request/ModifyEbookRequest.kt | 48 ++- .../v1/dto/response/DeleteEbookResponse.kt | 3 + .../ebook/v1/dto/response/EbookResponse.kt | 14 + .../backend/ebook/v1/error/EbookError.kt | 14 +- .../wishlist/v1/error/WishlistError.kt | 8 +- .../wishlist/v1/error/WishlistValidation.kt | 9 +- .../v1/controller/EbookControllerTest.kt | 32 +- 16 files changed, 437 insertions(+), 87 deletions(-) create mode 100644 src/main/kotlin/com/devooks/backend/common/exception/ErrorResponse.kt create mode 100644 src/main/kotlin/com/devooks/backend/ebook/v1/controller/docs/EbookControllerDocs.kt diff --git a/src/main/kotlin/com/devooks/backend/category/v1/dto/CategoryDto.kt b/src/main/kotlin/com/devooks/backend/category/v1/dto/CategoryDto.kt index fa9b6c3..eef29d4 100644 --- a/src/main/kotlin/com/devooks/backend/category/v1/dto/CategoryDto.kt +++ b/src/main/kotlin/com/devooks/backend/category/v1/dto/CategoryDto.kt @@ -1,10 +1,13 @@ package com.devooks.backend.category.v1.dto import com.devooks.backend.category.v1.domain.Category +import io.swagger.v3.oas.annotations.media.Schema import java.util.* data class CategoryDto( + @Schema(description = "카테고리 식별자") val id: UUID, + @Schema(description = "카테고리 이름") val name: String, ) { companion object { @@ -14,4 +17,4 @@ data class CategoryDto( name = name ) } -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/devooks/backend/common/exception/ErrorResponse.kt b/src/main/kotlin/com/devooks/backend/common/exception/ErrorResponse.kt new file mode 100644 index 0000000..2b8c1f7 --- /dev/null +++ b/src/main/kotlin/com/devooks/backend/common/exception/ErrorResponse.kt @@ -0,0 +1,21 @@ +package com.devooks.backend.common.exception + +import io.swagger.v3.oas.annotations.media.Schema +import java.util.* + +class ErrorResponse( + @Schema(description = "에러 발생 날짜", example = "2024-11-04T05:05:43.264+00:00") + val timestamp: Date, + @Schema(description = "에러 발생 API 경로", example = "/api/v1/ebook-inquiry-comments") + val path: String, + @Schema(description = "에러 상태 코드", example = "400") + val status: Int, + @Schema(description = "에러 유형", example = "BAD_REQUEST") + val error: String, + @Schema(description = "요청 식별자", example = "ebad5bcb-5") + val requestId: String, + @Schema(description = "에러 코드", example = "EBOOK-400-11") + val code: String, + @Schema(description = "에러 메시지", example = "문의 식별자가 반드시 필요합니다.") + val message: String, +) diff --git a/src/main/kotlin/com/devooks/backend/ebook/v1/controller/EbookController.kt b/src/main/kotlin/com/devooks/backend/ebook/v1/controller/EbookController.kt index b0078c8..7baec39 100644 --- a/src/main/kotlin/com/devooks/backend/ebook/v1/controller/EbookController.kt +++ b/src/main/kotlin/com/devooks/backend/ebook/v1/controller/EbookController.kt @@ -4,6 +4,7 @@ import com.devooks.backend.auth.v1.domain.Authorization import com.devooks.backend.auth.v1.service.TokenService import com.devooks.backend.category.v1.domain.Category import com.devooks.backend.category.v1.service.CategoryService +import com.devooks.backend.ebook.v1.controller.docs.EbookControllerDocs import com.devooks.backend.ebook.v1.domain.Ebook import com.devooks.backend.ebook.v1.domain.EbookImage import com.devooks.backend.ebook.v1.dto.command.CreateEbookCommand @@ -48,11 +49,11 @@ class EbookController( private val categoryService: CategoryService, private val relatedCategoryService: RelatedCategoryService, private val tokenService: TokenService, -) { +): EbookControllerDocs { @Transactional @PostMapping - suspend fun createEbook( + override suspend fun createEbook( @RequestBody request: CreateEbookRequest, @RequestHeader(AUTHORIZATION) @@ -72,7 +73,7 @@ class EbookController( } @GetMapping - suspend fun getEbooks( + override suspend fun getEbooks( @RequestParam(required = false, defaultValue = "") page: String, @RequestParam(required = false, defaultValue = "") @@ -107,8 +108,8 @@ class EbookController( } @GetMapping("/{ebookId}") - suspend fun getDetailOfEbook( - @PathVariable("ebookId", required = false) + override suspend fun getDetailOfEbook( + @PathVariable("ebookId", required = true) ebookId: String, @RequestHeader(AUTHORIZATION, required = false, defaultValue = "") authorization: String, @@ -122,12 +123,12 @@ class EbookController( @Transactional @PatchMapping("/{ebookId}") - suspend fun modifyEbook( - @PathVariable("ebookId", required = false) + override suspend fun modifyEbook( + @PathVariable("ebookId", required = true) ebookId: String, @RequestBody request: ModifyEbookRequest, - @RequestHeader(AUTHORIZATION, required = false, defaultValue = "") + @RequestHeader(AUTHORIZATION) authorization: String, ): ModifyEbookResponse { val requesterId = tokenService.getMemberId(Authorization(authorization)) @@ -141,10 +142,10 @@ class EbookController( @Transactional @DeleteMapping("/{ebookId}") - suspend fun deleteEbook( - @PathVariable("ebookId", required = false) + override suspend fun deleteEbook( + @PathVariable("ebookId", required = true) ebookId: String, - @RequestHeader(AUTHORIZATION, required = false, defaultValue = "") + @RequestHeader(AUTHORIZATION) authorization: String, ): DeleteEbookResponse { val requesterId = tokenService.getMemberId(Authorization(authorization)) diff --git a/src/main/kotlin/com/devooks/backend/ebook/v1/controller/docs/EbookControllerDocs.kt b/src/main/kotlin/com/devooks/backend/ebook/v1/controller/docs/EbookControllerDocs.kt new file mode 100644 index 0000000..39103d9 --- /dev/null +++ b/src/main/kotlin/com/devooks/backend/ebook/v1/controller/docs/EbookControllerDocs.kt @@ -0,0 +1,303 @@ +package com.devooks.backend.ebook.v1.controller.docs + +import com.devooks.backend.common.exception.ErrorResponse +import com.devooks.backend.ebook.v1.dto.request.CreateEbookRequest +import com.devooks.backend.ebook.v1.dto.request.ModifyEbookRequest +import com.devooks.backend.ebook.v1.dto.response.CreateEbookResponse +import com.devooks.backend.ebook.v1.dto.response.DeleteEbookResponse +import com.devooks.backend.ebook.v1.dto.response.GetDetailOfEbookResponse +import com.devooks.backend.ebook.v1.dto.response.GetEbooksResponse +import com.devooks.backend.ebook.v1.dto.response.ModifyEbookResponse +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.media.Content +import io.swagger.v3.oas.annotations.media.Schema +import io.swagger.v3.oas.annotations.responses.ApiResponse +import io.swagger.v3.oas.annotations.responses.ApiResponses +import io.swagger.v3.oas.annotations.tags.Tag +import org.springframework.http.MediaType.APPLICATION_JSON_VALUE + +@Tag(name = "전자책 API") +interface EbookControllerDocs { + + @Operation(summary = "전자책 목록 조회") + @ApiResponses( + value = [ + ApiResponse( + responseCode = "200", + description = "OK", + content = [ + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = GetEbooksResponse::class) + ) + ] + ), + ApiResponse( + responseCode = "400", + description = + "- COMMON-400-1 : 페이지는 1부터 조회할 수 있습니다.\n" + + "- COMMON-400-2 : 개수는 1~1000 까지 조회할 수 있습니다.\n" + + "- EBOOK-400-9 : 잘못된 형식의 EbookOrder(ex. LATEST, REVIEW) 입니다.", + content = arrayOf( + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ErrorResponse::class) + ) + ) + ), + ] + ) + suspend fun getEbooks( + @Schema(description = "페이지", required = true, nullable = false) + page: String, + @Schema(description = "개수", required = true, nullable = false) + count: String, + @Schema(description = "검색할 전자책 제목", required = false, nullable = true) + title: String, + @Schema(description = "검색할 판매자 식별자", required = false, nullable = true) + sellingMemberId: String, + @Schema(description = "검색할 전자책 식별자", required = false, nullable = true) + ebookIdList: List, + @Schema(description = "검색할 카테고리 식별자 목록", required = false, nullable = true) + categoryIdList: List, + @Schema(description = "정렬할 속성 (ex. LATEST, REVIEW)", required = false, nullable = true) + orderBy: String, + @Schema(description = "액세스 토큰", required = false, nullable = true) + authorization: String, + ): GetEbooksResponse + + @Operation(summary = "전자책 상세 조회") + @ApiResponses( + value = [ + ApiResponse( + responseCode = "200", + description = "OK", + content = [ + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = GetDetailOfEbookResponse::class) + ) + ] + ), + ApiResponse( + responseCode = "400", + description = + "- EBOOK-400-24 : 전자책 식별자가 반드시 필요합니다.\n" + + "- EBOOK-400-16 : 잘못된 형식의 전자책 식별자입니다.", + content = arrayOf( + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ErrorResponse::class) + ) + ) + ), + ApiResponse( + responseCode = "404", + description = + "- EBOOK-404-1 : 전자책을 찾을 수 없습니다.", + content = arrayOf( + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ErrorResponse::class) + ) + ) + ), + ] + ) + suspend fun getDetailOfEbook( + @Schema(description = "전자책 식별자", required = true, nullable = false) + ebookId: String, + @Schema(description = "액세스 토큰", required = false, nullable = true) + authorization: String, + ): GetDetailOfEbookResponse + + @Operation(summary = "전자책 등록") + @ApiResponses( + value = [ + ApiResponse( + responseCode = "200", + description = "OK", + content = [ + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = CreateEbookResponse::class) + ) + ] + ), + ApiResponse( + responseCode = "400", + description = + "- EBOOK-400-1 : PDF 식별자가 존재하지 않을 경우\n" + + "- EBOOK-400-2 : PDF 식별자가 UUID가 아닐 경우\n" + + "- EBOOK-400-3 : 전자책 제목이 비어있을 경우\n" + + "- EBOOK-400-4 : 관련 카테고리가 비어있을 경우\n" + + "- CATEGORY-400-1 : 카테고리 식별자가 UUID가 아닐 경우\n" + + "- EBOOK-400-20 : 메인 사진 식별자가 존재하지 않을 경우\n" + + "- EBOOK-400-21 : 메인 사진 식별자가 UUID가 아닐 경우\n" + + "- EBOOK-400-22 : 설명 사진 식별자가 존재하지 않을 경우\n" + + "- EBOOK-400-23 : 설명 사진 식별자가 UUID가 아닐 경우\n" + + "- EBOOK-400-5 : 가격이 0 ~ 9,999,999원이 아닐 경우\n" + + "- EBOOK-400-6 : 전자책 소개가 비어있을 경우\n" + + "- EBOOK-400-7 : 목차가 비어있을 경우", + content = arrayOf( + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ErrorResponse::class) + ) + ) + ), + ApiResponse( + responseCode = "403", + description = + "- PDF-403-1 : 다른 회원이 등록한 PDF를 올릴 경우\n" + + "- EBOOK-403-5 : 자신이 등록한 사진이 아닐 경우", + content = arrayOf( + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ErrorResponse::class) + ) + ) + ), + ApiResponse( + responseCode = "404", + description = + "- PDF-404-1 : PDF가 존재하지 않을 경우\n" + + "- CATEGORY-404-1 : 카테고리가 존재하지 않을 경우", + content = arrayOf( + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ErrorResponse::class) + ) + ) + ), + ] + ) + suspend fun createEbook( + request: CreateEbookRequest, + authorization: String, + ): CreateEbookResponse + + @Operation(summary = "전자책 수정") + @ApiResponses( + value = [ + ApiResponse( + responseCode = "200", + description = "OK", + content = [ + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ModifyEbookResponse::class) + ) + ] + ), + ApiResponse( + responseCode = "400", + description = + "- EBOOK-400-23 : 전자책 식별자가 존재하지 않을 경우\n" + + "- EBOOK-400-16 : 전자책 식별자가 UUID가 아닐 경우\n" + + "- EBOOK-400-3 : 전자책 제목이 null이 아니며 비어있을 경우\n" + + "- EBOOK-400-4 : 관련 카테고리가 null이 아니며 비어있을 경우\n" + + "- CATEGORY-400-1 : 관련 카테고리가 null이 아니며 카테고리 식별자가 UUID가 아닐 경우\n" + + "- EBOOK-400-20 : 메인 사진 식별자가 null이 아니며 존재하지 않을 경우\n" + + "- EBOOK-400-21 : 메인 사진 식별자가 null이 아니며 UUID가 아닐 경우\n" + + "- EBOOK-400-22 : 설명 사진 식별자가 null이 아니며 존재하지 않을 경우\n" + + "- EBOOK-400-23 : 설명 사진 식별자가 null이 아니며 UUID가 아닐 경우\n" + + "- EBOOK-400-5 : 가격이 null이 아니며 0 ~ 9,999,999원이 아닐 경우\n" + + "- EBOOK-400-6 : 전자책 소개가 null이 아니며 비어있을 경우\n" + + "- EBOOK-400-7 : 목차가 null이 아니며 비어있을 경우", + content = arrayOf( + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ErrorResponse::class) + ) + ) + ), + ApiResponse( + responseCode = "403", + description = + "- EBOOK-403-4 : 자신이 등록한 책이 아닐 경우", + content = arrayOf( + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ErrorResponse::class) + ) + ) + ), + ApiResponse( + responseCode = "404", + description = + "- EBOOK-404-1 : 전자책이 존재하지 않을 경우\n" + + "- EBOOK-404-4 : 메인 사진이 존재하지 않을 경우", + content = arrayOf( + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ErrorResponse::class) + ) + ) + ), + ] + ) + suspend fun modifyEbook( + @Schema(description = "전자책 식별자", required = true, nullable = false) + ebookId: String, + request: ModifyEbookRequest, + @Schema(description = "액세스 토큰", required = true, nullable = false) + authorization: String, + ): ModifyEbookResponse + + @Operation(summary = "전자책 삭제") + @ApiResponses( + value = [ + ApiResponse( + responseCode = "200", + description = "OK", + content = [ + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = DeleteEbookResponse::class) + ) + ] + ), + ApiResponse( + responseCode = "400", + description = + "- EBOOK-400-23 : 전자책 식별자가 존재하지 않을 경우\n" + + "- EBOOK-400-16 : 전자책 식별자가 UUID가 아닐 경우", + content = arrayOf( + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ErrorResponse::class) + ) + ) + ), + ApiResponse( + responseCode = "403", + description = + "- EBOOK-403-6 : 자신이 등록한 책이 아닐 경우", + content = arrayOf( + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ErrorResponse::class) + ) + ) + ), + ApiResponse( + responseCode = "404", + description = + "- EBOOK-404-1 : 전자책이 존재하지 않을 경우", + content = arrayOf( + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ErrorResponse::class) + ) + ) + ), + ] + ) + suspend fun deleteEbook( + @Schema(description = "전자책 식별자", required = true, nullable = false) + ebookId: String, + @Schema(description = "액세스 토큰", required = true, nullable = false) + authorization: String, + ): DeleteEbookResponse +} diff --git a/src/main/kotlin/com/devooks/backend/ebook/v1/dto/DescriptionImageDto.kt b/src/main/kotlin/com/devooks/backend/ebook/v1/dto/DescriptionImageDto.kt index c7bafe6..631003f 100644 --- a/src/main/kotlin/com/devooks/backend/ebook/v1/dto/DescriptionImageDto.kt +++ b/src/main/kotlin/com/devooks/backend/ebook/v1/dto/DescriptionImageDto.kt @@ -1,12 +1,16 @@ package com.devooks.backend.ebook.v1.dto import com.devooks.backend.ebook.v1.domain.EbookImage +import io.swagger.v3.oas.annotations.media.Schema import java.util.* import kotlin.io.path.pathString data class DescriptionImageDto( + @Schema(description = "설명 사진 식별자") val id: UUID, + @Schema(description = "사진 경로") val imagePath: String, + @Schema(description = "사진 순서") val order: Int, ) { companion object { @@ -17,4 +21,4 @@ data class DescriptionImageDto( order = order ) } -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/devooks/backend/ebook/v1/dto/EbookDetailView.kt b/src/main/kotlin/com/devooks/backend/ebook/v1/dto/EbookDetailView.kt index e4613aa..96bd047 100644 --- a/src/main/kotlin/com/devooks/backend/ebook/v1/dto/EbookDetailView.kt +++ b/src/main/kotlin/com/devooks/backend/ebook/v1/dto/EbookDetailView.kt @@ -1,22 +1,38 @@ package com.devooks.backend.ebook.v1.dto +import io.swagger.v3.oas.annotations.media.Schema import java.time.Instant import java.util.* data class EbookDetailView( + @Schema(description = "전자책 식별자") val id: UUID, + @Schema(description = "메인 사진 식별자") val mainImagePath: String, + @Schema(description = "설명 사진 목록") val descriptionImagePathList: List?, + @Schema(description = "찜 식별자") val wishlistId: UUID?, + @Schema(description = "제목") val title: String, + @Schema(description = "리뷰 정보") val review: ReviewView, + @Schema(description = "관련 카테고리 이름 목록") val relatedCategoryNameList: List, + @Schema(description = "작성자 이름") val sellingMemberId: UUID, + @Schema(description = "생성 날짜") val createdDate: Instant, + @Schema(description = "수정 날짜") val modifiedDate: Instant, + @Schema(description = "페이지 개수") val pageCount: Int, + @Schema(description = "가격") val price: Int, + @Schema(description = "PDF 식별자") val pdfId: UUID, + @Schema(description = "소개") val introduction: String, + @Schema(description = "목차") val tableOfContents: String, ) diff --git a/src/main/kotlin/com/devooks/backend/ebook/v1/dto/EbookView.kt b/src/main/kotlin/com/devooks/backend/ebook/v1/dto/EbookView.kt index d3270b7..f714bd5 100644 --- a/src/main/kotlin/com/devooks/backend/ebook/v1/dto/EbookView.kt +++ b/src/main/kotlin/com/devooks/backend/ebook/v1/dto/EbookView.kt @@ -1,14 +1,23 @@ package com.devooks.backend.ebook.v1.dto +import io.swagger.v3.oas.annotations.media.Schema import java.util.* data class EbookView( + @Schema(description = "전자책 식별자") val id: UUID, + @Schema(description = "메인 사진 경로") val mainImagePath: String, + @Schema(description = "제목") val title: String, + @Schema(description = "찜 식별자") val wishlistId: UUID?, + @Schema(description = "리뷰 정보") val review: ReviewView, + @Schema(description = "작성자 이름") val writerName: String, + @Schema(description = "가격") val price: Int, + @Schema(description = "관련 카테고리 이름 목록") val relatedCategoryNameList: List, ) diff --git a/src/main/kotlin/com/devooks/backend/ebook/v1/dto/ReviewView.kt b/src/main/kotlin/com/devooks/backend/ebook/v1/dto/ReviewView.kt index 944984f..dcd2bfd 100644 --- a/src/main/kotlin/com/devooks/backend/ebook/v1/dto/ReviewView.kt +++ b/src/main/kotlin/com/devooks/backend/ebook/v1/dto/ReviewView.kt @@ -1,6 +1,10 @@ package com.devooks.backend.ebook.v1.dto +import io.swagger.v3.oas.annotations.media.Schema + data class ReviewView( + @Schema(description = "평점") val rating: Double, + @Schema(description = "개수") val count: Int ) diff --git a/src/main/kotlin/com/devooks/backend/ebook/v1/dto/request/CreateEbookRequest.kt b/src/main/kotlin/com/devooks/backend/ebook/v1/dto/request/CreateEbookRequest.kt index a090c3a..97916d9 100644 --- a/src/main/kotlin/com/devooks/backend/ebook/v1/dto/request/CreateEbookRequest.kt +++ b/src/main/kotlin/com/devooks/backend/ebook/v1/dto/request/CreateEbookRequest.kt @@ -9,16 +9,25 @@ import com.devooks.backend.ebook.v1.error.validateMainImageId import com.devooks.backend.ebook.v1.error.validatePdfId import com.devooks.backend.ebook.v1.error.validateRelatedCategoryList import com.devooks.backend.ebook.v1.error.validateTableOfContents +import io.swagger.v3.oas.annotations.media.Schema import java.util.* data class CreateEbookRequest( + @Schema(description = "PDF 식별자", required = true, nullable = false) val pdfId: String?, + @Schema(description = "제목", required = true, nullable = false) val title: String?, + @Schema(description = "카테고리 식별자 목록", required = true, nullable = false) val relatedCategoryIdList: List?, + @Schema(description = "메인 사진 식별자", required = true, nullable = false) val mainImageId: String?, + @Schema(description = "설명 사진 식별자 목록", required = true, nullable = false) val descriptionImageIdList: List?, + @Schema(description = "가격", required = true, nullable = false) val price: Int?, + @Schema(description = "소개", required = true, nullable = false) val introduction: String?, + @Schema(description = "목차", required = true, nullable = false) val tableOfContents: String?, ) { fun toCommand(requesterId: UUID): CreateEbookCommand = diff --git a/src/main/kotlin/com/devooks/backend/ebook/v1/dto/request/ModifyEbookRequest.kt b/src/main/kotlin/com/devooks/backend/ebook/v1/dto/request/ModifyEbookRequest.kt index d29d34f..fe99740 100644 --- a/src/main/kotlin/com/devooks/backend/ebook/v1/dto/request/ModifyEbookRequest.kt +++ b/src/main/kotlin/com/devooks/backend/ebook/v1/dto/request/ModifyEbookRequest.kt @@ -10,49 +10,43 @@ import com.devooks.backend.ebook.v1.error.validateMainImageId import com.devooks.backend.ebook.v1.error.validateRelatedCategoryList import com.devooks.backend.ebook.v1.error.validateTableOfContents import com.devooks.backend.wishlist.v1.error.validateEbookId +import io.swagger.v3.oas.annotations.media.Schema import java.util.* data class ModifyEbookRequest( + @Schema(description = "수정할 내용 (값이 존재하지 않을 경우 수정하지 않음)") val ebook: Ebook?, - val isChanged: IsChanged?, ) { data class Ebook( + @Schema(description = "전자책 이름", required = false, nullable = true) val title: String? = null, + @Schema(description = "카테고리 식별자 목록", required = false, nullable = true) val relatedCategoryIdList: List? = null, + @Schema(description = "메인 사진 식별자", required = false, nullable = true) val mainImageId: String? = null, + @Schema(description = "설명 사진 식별자 목록", required = false, nullable = true) val descriptionImageIdList: List? = null, + @Schema(description = "소개", required = false, nullable = true) val introduction: String? = null, + @Schema(description = "목차", required = false, nullable = true) val tableOfContents: String? = null, + @Schema(description = "가격", required = false, nullable = true) val price: Int? = null, ) - data class IsChanged( - val title: Boolean? = false, - val relatedCategoryIdList: Boolean? = false, - val mainImage: Boolean? = false, - val descriptionImageList: Boolean? = false, - val introduction: Boolean? = false, - val tableOfContents: Boolean? = false, - val price: Boolean? = false, - ) - fun toCommand(ebookId: String, requesterId: UUID): ModifyEbookCommand = - if (isChanged != null) { - if (ebook != null) { - ModifyEbookCommand( - ebookId.validateEbookId(), - if (isChanged.title == true) ebook.title.validateEbookTitle() else null, - if (isChanged.relatedCategoryIdList == true) ebook.relatedCategoryIdList.validateRelatedCategoryList() else null, - if (isChanged.mainImage == true) ebook.mainImageId.validateMainImageId() else null, - if (isChanged.descriptionImageList == true) ebook.descriptionImageIdList.validateDescriptionImageIdList() else null, - if (isChanged.introduction == true) ebook.introduction.validateEbookIntroduction() else null, - if (isChanged.tableOfContents == true) ebook.tableOfContents.validateTableOfContents() else null, - if (isChanged.price == true) ebook.price.validateEbookPrice() else null, - requesterId - ) - } else { - throw EbookError.REQUIRED_IS_CHANGED_FOR_MODIFY.exception - } + if (ebook != null) { + ModifyEbookCommand( + ebookId = ebookId.validateEbookId(), + title = ebook.title?.validateEbookTitle(), + relatedCategoryIdList = ebook.relatedCategoryIdList?.validateRelatedCategoryList(), + mainImageId = ebook.mainImageId?.validateMainImageId(), + descriptionImageIdList = ebook.descriptionImageIdList?.validateDescriptionImageIdList(), + introduction = ebook.introduction?.validateEbookIntroduction(), + tableOfContents = ebook.tableOfContents?.validateTableOfContents(), + price = ebook.price?.validateEbookPrice(), + requesterId = requesterId + ) } else { throw EbookError.REQUIRED_EBOOK_FOR_MODIFY.exception } diff --git a/src/main/kotlin/com/devooks/backend/ebook/v1/dto/response/DeleteEbookResponse.kt b/src/main/kotlin/com/devooks/backend/ebook/v1/dto/response/DeleteEbookResponse.kt index 821aede..6ec4507 100644 --- a/src/main/kotlin/com/devooks/backend/ebook/v1/dto/response/DeleteEbookResponse.kt +++ b/src/main/kotlin/com/devooks/backend/ebook/v1/dto/response/DeleteEbookResponse.kt @@ -1,5 +1,8 @@ package com.devooks.backend.ebook.v1.dto.response +import io.swagger.v3.oas.annotations.media.Schema + data class DeleteEbookResponse( + @Schema(description = "결과 메시지", example = "전자책 삭제를 완료했습니다.") val message: String = "전자책 삭제를 완료했습니다." ) diff --git a/src/main/kotlin/com/devooks/backend/ebook/v1/dto/response/EbookResponse.kt b/src/main/kotlin/com/devooks/backend/ebook/v1/dto/response/EbookResponse.kt index 7f7353d..1f59b1d 100644 --- a/src/main/kotlin/com/devooks/backend/ebook/v1/dto/response/EbookResponse.kt +++ b/src/main/kotlin/com/devooks/backend/ebook/v1/dto/response/EbookResponse.kt @@ -7,22 +7,36 @@ import com.devooks.backend.ebook.v1.domain.Ebook import com.devooks.backend.ebook.v1.domain.EbookImage import com.devooks.backend.ebook.v1.dto.DescriptionImageDto import com.devooks.backend.ebook.v1.dto.DescriptionImageDto.Companion.toDto +import io.swagger.v3.oas.annotations.media.Schema import java.time.Instant import java.util.* data class EbookResponse( + @Schema(description = "전자책 식별자") val id: UUID, + @Schema(description = "PDF 식별자") val pdfId: UUID, + @Schema(description = "메인 사진 식별자") val mainImageId: UUID, + @Schema(description = "관련 카테고리 목록") val relatedCategoryList: List, + @Schema(description = "제목") val title: String, + @Schema(description = "가격") val price: Int, + @Schema(description = "목차") val tableOfContents: String, + @Schema(description = "소개") val introduction: String, + @Schema(description = "생성 날짜") val createdDate: Instant, + @Schema(description = "수정 날짜") val modifiedDate: Instant, + @Schema(description = "설명 사진 목록") val descriptionImageList: List, + @Schema(description = "판매자 회원 식별자") val sellingMemberId: UUID, + @Schema(description = "삭제 날짜", nullable = true) val deletedDate: Instant?, ) { constructor( diff --git a/src/main/kotlin/com/devooks/backend/ebook/v1/error/EbookError.kt b/src/main/kotlin/com/devooks/backend/ebook/v1/error/EbookError.kt index 68084f9..f6eb985 100644 --- a/src/main/kotlin/com/devooks/backend/ebook/v1/error/EbookError.kt +++ b/src/main/kotlin/com/devooks/backend/ebook/v1/error/EbookError.kt @@ -24,12 +24,12 @@ enum class EbookError(val exception: GeneralException) { INVALID_EBOOK_INQUIRY_COMMENT_ID(GeneralException("EBOOK-400-15", BAD_REQUEST, "잘못된 형식의 댓글 식별자입니다.")), INVALID_EBOOK_ID(GeneralException("EBOOK-400-16", BAD_REQUEST, "잘못된 형식의 전자책 식별자입니다.")), REQUIRED_EBOOK_FOR_MODIFY(GeneralException("EBOOK-400-17", BAD_REQUEST, "전자책이 반드시 필요합니다.")), - REQUIRED_IS_CHANGED_FOR_MODIFY(GeneralException("EBOOK-400-18", BAD_REQUEST, "수졍 여부가 반드시 필요합니다.")), - REQUIRED_MAIN_IMAGE(GeneralException("EBOOK-400-19", BAD_REQUEST, "메인 사진이 반드시 필요합니다.")), - REQUIRED_MAIN_IMAGE_ID(GeneralException("EBOOK-400-20", BAD_REQUEST, "메인 사진 식별자가 반드시 필요합니다.")), - INVALID_MAIN_IMAGE_ID(GeneralException("EBOOK-400-21", BAD_REQUEST, "잘못된 형식의 메인 사진 식별자입니다.")), - REQUIRED_DESCRIPTION_IMAGE_ID(GeneralException("EBOOK-400-22", BAD_REQUEST, "설명 사진 식별자가 반드시 필요합니다.")), - INVALID_DESCRIPTION_IMAGE_ID(GeneralException("EBOOK-400-23", BAD_REQUEST, "잘못된 형식의 설명 사진 식별자입니다.")), + REQUIRED_MAIN_IMAGE(GeneralException("EBOOK-400-18", BAD_REQUEST, "메인 사진이 반드시 필요합니다.")), + REQUIRED_MAIN_IMAGE_ID(GeneralException("EBOOK-400-19", BAD_REQUEST, "메인 사진 식별자가 반드시 필요합니다.")), + INVALID_MAIN_IMAGE_ID(GeneralException("EBOOK-400-20", BAD_REQUEST, "잘못된 형식의 메인 사진 식별자입니다.")), + REQUIRED_DESCRIPTION_IMAGE_ID(GeneralException("EBOOK-400-21", BAD_REQUEST, "설명 사진 식별자가 반드시 필요합니다.")), + INVALID_DESCRIPTION_IMAGE_ID(GeneralException("EBOOK-400-22", BAD_REQUEST, "잘못된 형식의 설명 사진 식별자입니다.")), + REQUIRED_EBOOK_ID(GeneralException("EBOOK-400-23", BAD_REQUEST, "전자책 식별자가 반드시 필요합니다.")), // 403 FORBIDDEN_BUYER_MEMBER_ID(GeneralException("EBOOK-403-1", FORBIDDEN, "자신의 책을 구매하는 것은 불가능합니다.")), @@ -45,4 +45,4 @@ enum class EbookError(val exception: GeneralException) { NOT_FOUND_EBOOK_INQUIRY_COMMENT(GeneralException("EBOOK-404-3", NOT_FOUND, "댓글을 찾을 수 없습니다")), NOT_FOUND_MAIN_IMAGE(GeneralException("EBOOK-404-4", NOT_FOUND, "메인 사진을 찾을 수 없습니다")), NOT_FOUND_DESCRIPTION_IMAGE(GeneralException("EBOOK-404-5", NOT_FOUND, "설명 사진을 찾을 수 없습니다")), -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/devooks/backend/wishlist/v1/error/WishlistError.kt b/src/main/kotlin/com/devooks/backend/wishlist/v1/error/WishlistError.kt index 621c668..317ab13 100644 --- a/src/main/kotlin/com/devooks/backend/wishlist/v1/error/WishlistError.kt +++ b/src/main/kotlin/com/devooks/backend/wishlist/v1/error/WishlistError.kt @@ -8,10 +8,8 @@ import org.springframework.http.HttpStatus.NOT_FOUND enum class WishlistError(val exception: GeneralException) { // 400 - REQUIRED_EBOOK_ID(GeneralException("WISHLIST-400-1", BAD_REQUEST, "전자책 식별자가 반드시 필요합니다.")), - INVALID_EBOOK_ID(GeneralException("WISHLIST-400-2", BAD_REQUEST, "잘못된 형식의 전자책 식별자 입니다.")), - INVALID_CATEGORY_ID(GeneralException("WISHLIST-400-3", BAD_REQUEST, "잘못된 형식의 카테고리 식별자 입니다.")), - INVALID_WISHLIST_ID(GeneralException("WISHLIST-400-4", BAD_REQUEST, "잘못된 형식의 찜 식별자 입니다.")), + INVALID_CATEGORY_ID(GeneralException("WISHLIST-400-1", BAD_REQUEST, "잘못된 형식의 카테고리 식별자 입니다.")), + INVALID_WISHLIST_ID(GeneralException("WISHLIST-400-2", BAD_REQUEST, "잘못된 형식의 찜 식별자 입니다.")), // 403 FORBIDDEN_DELETE_WISHLIST(GeneralException("WISHLIST-403-1", FORBIDDEN, "자신의 찜만 삭제할 수 있습니다.")), @@ -26,4 +24,4 @@ enum class WishlistError(val exception: GeneralException) { override fun toString(): String { return "WishlistError(exception=$exception)" } -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/devooks/backend/wishlist/v1/error/WishlistValidation.kt b/src/main/kotlin/com/devooks/backend/wishlist/v1/error/WishlistValidation.kt index 2bae4b5..dbd2cbb 100644 --- a/src/main/kotlin/com/devooks/backend/wishlist/v1/error/WishlistValidation.kt +++ b/src/main/kotlin/com/devooks/backend/wishlist/v1/error/WishlistValidation.kt @@ -1,15 +1,16 @@ package com.devooks.backend.wishlist.v1.error -import com.devooks.backend.common.error.validateUUID import com.devooks.backend.common.error.validateNotBlank +import com.devooks.backend.common.error.validateUUID +import com.devooks.backend.ebook.v1.error.EbookError import java.util.* fun String?.validateEbookId(): UUID = - validateNotBlank(WishlistError.REQUIRED_EBOOK_ID.exception) - .validateUUID(WishlistError.INVALID_EBOOK_ID.exception) + validateNotBlank(EbookError.REQUIRED_EBOOK_ID.exception) + .validateUUID(EbookError.INVALID_EBOOK_ID.exception) fun List.validateCategoryIds(): List = map { it.validateUUID(WishlistError.INVALID_CATEGORY_ID.exception) } fun String.validateWishlistId(): UUID = - validateUUID(WishlistError.INVALID_WISHLIST_ID.exception) \ No newline at end of file + validateUUID(WishlistError.INVALID_WISHLIST_ID.exception) diff --git a/src/test/kotlin/com/devooks/backend/ebook/v1/controller/EbookControllerTest.kt b/src/test/kotlin/com/devooks/backend/ebook/v1/controller/EbookControllerTest.kt index 567a60a..1b5eda8 100644 --- a/src/test/kotlin/com/devooks/backend/ebook/v1/controller/EbookControllerTest.kt +++ b/src/test/kotlin/com/devooks/backend/ebook/v1/controller/EbookControllerTest.kt @@ -685,15 +685,6 @@ internal class EbookControllerTest @Autowired constructor( tableOfContents = "tableOfContents2", introduction = "introduction2" ), - isChanged = ModifyEbookRequest.IsChanged( - title = true, - relatedCategoryIdList = true, - mainImage = true, - descriptionImageList = true, - introduction = true, - tableOfContents = true, - price = true, - ) ) val updatedEbook = webTestClient @@ -759,15 +750,6 @@ internal class EbookControllerTest @Autowired constructor( price = 20000, tableOfContents = "tableOfContents2", introduction = "introduction2" - ), - isChanged = ModifyEbookRequest.IsChanged( - title = true, - relatedCategoryIdList = true, - mainImage = true, - descriptionImageList = true, - introduction = true, - tableOfContents = true, - price = true, ) ) @@ -792,9 +774,6 @@ internal class EbookControllerTest @Autowired constructor( val modifyEbookRequest = ModifyEbookRequest( ebook = ModifyEbookRequest.Ebook( title = "title2", - ), - isChanged = ModifyEbookRequest.IsChanged( - title = true, ) ) @@ -829,10 +808,7 @@ internal class EbookControllerTest @Autowired constructor( val accessToken = tokenService.createTokenGroup(expectedMember1).accessToken val modifyEbookRequest = ModifyEbookRequest( - ebook = ModifyEbookRequest.Ebook(), - isChanged = ModifyEbookRequest.IsChanged( - title = true, - ) + ebook = ModifyEbookRequest.Ebook(title = "") ) webTestClient @@ -853,9 +829,6 @@ internal class EbookControllerTest @Autowired constructor( val modifyEbookRequest = ModifyEbookRequest( ebook = ModifyEbookRequest.Ebook( title = "title2", - ), - isChanged = ModifyEbookRequest.IsChanged( - title = true, ) ) @@ -878,9 +851,6 @@ internal class EbookControllerTest @Autowired constructor( val modifyEbookRequest = ModifyEbookRequest( ebook = ModifyEbookRequest.Ebook( title = "title2", - ), - isChanged = ModifyEbookRequest.IsChanged( - title = true, ) ) From 316a104a00aeb7ce6dbe12e9db0a5dd08f4e5a22 Mon Sep 17 00:00:00 2001 From: Sangmin Lee Date: Mon, 4 Nov 2024 16:07:14 +0900 Subject: [PATCH 2/3] =?UTF-8?q?[DVK-63]=20docs:=20=EC=9D=B8=EC=A6=9D=20API?= =?UTF-8?q?=EC=9D=98=20Swagger=20=EC=A0=81=EC=9A=A9=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../auth/v1/controller/AuthControllerDocs.kt | 142 +++++++++++++++--- .../backend/auth/v1/dto/CheckEmailResponse.kt | 3 + .../backend/auth/v1/dto/LoginRequest.kt | 11 +- .../backend/auth/v1/dto/LogoutResponse.kt | 3 + 4 files changed, 137 insertions(+), 22 deletions(-) diff --git a/src/main/kotlin/com/devooks/backend/auth/v1/controller/AuthControllerDocs.kt b/src/main/kotlin/com/devooks/backend/auth/v1/controller/AuthControllerDocs.kt index 80da039..f8b6dbf 100644 --- a/src/main/kotlin/com/devooks/backend/auth/v1/controller/AuthControllerDocs.kt +++ b/src/main/kotlin/com/devooks/backend/auth/v1/controller/AuthControllerDocs.kt @@ -8,12 +8,14 @@ import com.devooks.backend.auth.v1.dto.LogoutRequest import com.devooks.backend.auth.v1.dto.LogoutResponse import com.devooks.backend.auth.v1.dto.ReissueRequest import com.devooks.backend.auth.v1.dto.ReissueResponse +import com.devooks.backend.common.exception.ErrorResponse import io.swagger.v3.oas.annotations.Operation import io.swagger.v3.oas.annotations.media.Content import io.swagger.v3.oas.annotations.media.Schema import io.swagger.v3.oas.annotations.responses.ApiResponse import io.swagger.v3.oas.annotations.responses.ApiResponses import io.swagger.v3.oas.annotations.tags.Tag +import org.springframework.http.MediaType.APPLICATION_JSON_VALUE @Tag(name = "인증 API") interface AuthControllerDocs { @@ -21,13 +23,27 @@ interface AuthControllerDocs { @Operation(summary = "로그인") @ApiResponses( value = [ - ApiResponse(responseCode = "200", description = "OK"), + ApiResponse( + responseCode = "200", + description = "OK", + content = [ + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = LoginResponse::class) + ) + ] + ), ApiResponse( responseCode = "400", description = "- AUTH-400-1 : 인증 코드(authorizationCode)가 NULL이거나 빈 문자일 경우\n" + "- AUTH-400-2 : 인증 유형(oauthType)이 NAVER, KAKAO, GOOGLE 이 아닐 경우 ", - content = arrayOf(Content(schema = Schema(hidden = true))) + content = arrayOf( + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ErrorResponse::class) + ) + ) ), ApiResponse( responseCode = "401", @@ -35,20 +51,36 @@ interface AuthControllerDocs { "- AUTH-401-3 : 네이버 로그인을 실패할 경우\n" + "- AUTH-401-4 : 카카오 로그인을 실패할 경우\n" + "- AUTH-401-5 : 구글 로그인을 실패할 경우", - content = arrayOf(Content(schema = Schema(hidden = true))) + content = arrayOf( + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ErrorResponse::class) + ) + ) ), ApiResponse( responseCode = "403", description = "- AUTH-403-1 : 정지된 회원일 경우 경우\n" + "- AUTH-403-2 : 탈퇴한 회원일 경우", - content = arrayOf(Content(schema = Schema(hidden = true))) + content = arrayOf( + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ErrorResponse::class) + ) + ) ), ApiResponse( responseCode = "404", description = - "- MEMBER-404-1 : 회원을 찾을 수 없는 경우 (message에 oauthId를 넣어서 응답)", - content = arrayOf(Content(schema = Schema(hidden = true))) + "- MEMBER-404-1 : 회원을 찾을 수 없는 경우 " + + "(message에 oauthId를 넣어서 응답, {\"oauthId\" : \":oauthId\"})", + content = arrayOf( + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ErrorResponse::class) + ) + ) ) ] ) @@ -58,24 +90,48 @@ interface AuthControllerDocs { @Operation(summary = "로그아웃") @ApiResponses( value = [ - ApiResponse(responseCode = "200", description = "OK"), + ApiResponse( + responseCode = "200", + description = "OK", + content = [ + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = LogoutResponse::class) + ) + ] + ), ApiResponse( responseCode = "400", description = "- AUTH-400-3 : 리프래시 토큰(refreshToken)이 NULL이거나 빈 문자일 경우", - content = arrayOf(Content(schema = Schema(hidden = true))) + content = arrayOf( + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ErrorResponse::class) + ) + ) ), ApiResponse( responseCode = "401", description = "- AUTH-401-1 : 기간이 만료된 토큰일 경우", - content = arrayOf(Content(schema = Schema(hidden = true))) + content = arrayOf( + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ErrorResponse::class) + ) + ) ), ApiResponse( responseCode = "403", description = "- AUTH-403-1 : 잘못된 형식의 토큰일 경우", - content = arrayOf(Content(schema = Schema(hidden = true))) + content = arrayOf( + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ErrorResponse::class) + ) + ) ) ] ) @@ -84,31 +140,60 @@ interface AuthControllerDocs { @Operation(summary = "토큰 재발급") @ApiResponses( value = [ - ApiResponse(responseCode = "200", description = "OK"), + ApiResponse( + responseCode = "200", + description = "OK", + content = [ + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ReissueResponse::class) + ) + ] + ), ApiResponse( responseCode = "400", description = "- AUTH-400-3 : 리프래시 토큰(refreshToken)이 NULL이거나 빈 문자일 경우", - content = arrayOf(Content(schema = Schema(hidden = true))) + content = arrayOf( + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ErrorResponse::class) + ) + ) ), ApiResponse( responseCode = "401", description = "- AUTH-401-1 : 기간이 만료된 토큰일 경우\n" + "- AUTH-401-2 : 원본 리프래시 토큰과 일치하지 않을 경우", - content = arrayOf(Content(schema = Schema(hidden = true))) + content = arrayOf( + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ErrorResponse::class) + ) + ) ), ApiResponse( responseCode = "403", description = "- AUTH-403-1 : 잘못된 형식의 토큰일 경우", - content = arrayOf(Content(schema = Schema(hidden = true))) + content = arrayOf( + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ErrorResponse::class) + ) + ) ), ApiResponse( responseCode = "404", description = "- AUTH-404-1 : 리프래시 토큰이 존재하지 않을 경우", - content = arrayOf(Content(schema = Schema(hidden = true))) + content = arrayOf( + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ErrorResponse::class) + ) + ) ) ] ) @@ -117,19 +202,38 @@ interface AuthControllerDocs { @Operation(summary = "이메일 확인") @ApiResponses( value = [ - ApiResponse(responseCode = "200", description = "OK"), + ApiResponse( + responseCode = "200", + description = "OK", + content = [ + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = CheckEmailResponse::class) + ) + ] + ), ApiResponse( responseCode = "400", description = "- AUTH-400-16 : 이메일 값이 존재하지 않을 경우" + "- AUTH-400-17 : 이메일 형식이 아닐 경우", - content = arrayOf(Content(schema = Schema(hidden = true))) + content = arrayOf( + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ErrorResponse::class) + ) + ) ), ApiResponse( responseCode = "500", description = - "- AUTH-500-4 : 이메일 전송을 실패했을 경우", - content = arrayOf(Content(schema = Schema(hidden = true))) + "- AUTH-500-4 : 이메일 전송을 실패했을 경우", + content = arrayOf( + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = ErrorResponse::class) + ) + ) ) ] ) diff --git a/src/main/kotlin/com/devooks/backend/auth/v1/dto/CheckEmailResponse.kt b/src/main/kotlin/com/devooks/backend/auth/v1/dto/CheckEmailResponse.kt index 8982760..a79d32e 100644 --- a/src/main/kotlin/com/devooks/backend/auth/v1/dto/CheckEmailResponse.kt +++ b/src/main/kotlin/com/devooks/backend/auth/v1/dto/CheckEmailResponse.kt @@ -1,5 +1,8 @@ package com.devooks.backend.auth.v1.dto +import io.swagger.v3.oas.annotations.media.Schema + data class CheckEmailResponse( + @Schema(description = "결과 메시지", example = "이메일 인증이 완료됐습니다.") val message: String = "이메일 인증이 완료됐습니다." ) diff --git a/src/main/kotlin/com/devooks/backend/auth/v1/dto/LoginRequest.kt b/src/main/kotlin/com/devooks/backend/auth/v1/dto/LoginRequest.kt index b449a31..fa2bf42 100644 --- a/src/main/kotlin/com/devooks/backend/auth/v1/dto/LoginRequest.kt +++ b/src/main/kotlin/com/devooks/backend/auth/v1/dto/LoginRequest.kt @@ -7,12 +7,17 @@ import io.swagger.v3.oas.annotations.media.Schema data class LoginRequest( @Schema(description = "OAuth2 인증 코드", required = true, nullable = false) val authorizationCode: String?, - @Schema(description = "OAuth2 인증 유형", required = true, nullable = false, example = "NAVER") - val oauthType: String? + @Schema( + description = "OAuth2 인증 유형 (ex. NAVER, KAKAO, GOOGLE)", + required = true, + nullable = false, + example = "NAVER" + ) + val oauthType: String?, ) { fun toCommand(): LoginCommand = LoginCommand( authorizationCode = authorizationCode.validateAuthorizationCode(), oauthType = oauthType.validateOauthType() ) -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/devooks/backend/auth/v1/dto/LogoutResponse.kt b/src/main/kotlin/com/devooks/backend/auth/v1/dto/LogoutResponse.kt index 6a75b5d..12517cb 100644 --- a/src/main/kotlin/com/devooks/backend/auth/v1/dto/LogoutResponse.kt +++ b/src/main/kotlin/com/devooks/backend/auth/v1/dto/LogoutResponse.kt @@ -1,5 +1,8 @@ package com.devooks.backend.auth.v1.dto +import io.swagger.v3.oas.annotations.media.Schema + data class LogoutResponse( + @Schema(description = "결과 메시지", example = "로그아웃이 완료됐습니다.") val message: String = "로그아웃이 완료됐습니다." ) From 0a78cf02716ae88b691034637a3af4e79fb43c26 Mon Sep 17 00:00:00 2001 From: Sangmin Lee Date: Mon, 4 Nov 2024 16:08:32 +0900 Subject: [PATCH 3/3] =?UTF-8?q?[DVK-63]=20docs:=20=EC=B9=B4=ED=85=8C?= =?UTF-8?q?=EA=B3=A0=EB=A6=AC=20API=EC=9D=98=20Swagger=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../v1/controller/CategoryControllerDocs.kt | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/com/devooks/backend/category/v1/controller/CategoryControllerDocs.kt b/src/main/kotlin/com/devooks/backend/category/v1/controller/CategoryControllerDocs.kt index 1c01f02..17da4ad 100644 --- a/src/main/kotlin/com/devooks/backend/category/v1/controller/CategoryControllerDocs.kt +++ b/src/main/kotlin/com/devooks/backend/category/v1/controller/CategoryControllerDocs.kt @@ -2,14 +2,30 @@ package com.devooks.backend.category.v1.controller import com.devooks.backend.category.v1.dto.GetCategoriesResponse import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.media.Content +import io.swagger.v3.oas.annotations.media.Schema import io.swagger.v3.oas.annotations.responses.ApiResponse import io.swagger.v3.oas.annotations.responses.ApiResponses import io.swagger.v3.oas.annotations.tags.Tag +import org.springframework.http.MediaType.APPLICATION_JSON_VALUE @Tag(name = "카테고리 API") interface CategoryControllerDocs { @Operation(summary = "카테고리 목록 조회") - @ApiResponses(value = [ApiResponse(responseCode = "200", description = "OK")]) + @ApiResponses( + value = [ + ApiResponse( + responseCode = "200", + description = "OK", + content = [ + Content( + mediaType = APPLICATION_JSON_VALUE, + schema = Schema(implementation = GetCategoriesResponse::class) + ) + ] + ) + ] + ) suspend fun getCategories(): GetCategoriesResponse }