From 0c6d8420fe77c00335d0c1cac0c39bfb4a99e3cd Mon Sep 17 00:00:00 2001 From: JaeUk Date: Wed, 2 Apr 2025 21:55:27 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20#140=20=EB=A3=A8=ED=8A=B8=20=EA=B5=AC?= =?UTF-8?q?=EB=A7=A4=20API=20=ED=8F=AC=EC=9D=B8=ED=8A=B8=EB=A1=9C=20?= =?UTF-8?q?=EA=B5=AC=EB=A7=A4=20=EC=8B=9C,=20=EB=B3=B4=EC=9C=A0=20?= =?UTF-8?q?=ED=8F=AC=EC=9D=B8=ED=8A=B8=EA=B0=80=20=EB=B6=80=EC=A1=B1?= =?UTF-8?q?=ED=95=9C=20=EA=B2=BD=EC=9A=B0=EC=97=90=20=EB=8C=80=ED=95=9C=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../routebox/application/route/PurchaseRouteUseCase.kt | 2 ++ .../routebox/routebox/controller/route/RouteController.kt | 7 ++++++- src/main/kotlin/com/routebox/routebox/domain/user/User.kt | 2 ++ .../com/routebox/routebox/domain/user/UserService.kt | 5 +++-- .../com/routebox/routebox/exception/CustomExceptionType.kt | 1 + .../routebox/exception/user/InsufficientPointException.kt | 6 ++++++ 6 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 src/main/kotlin/com/routebox/routebox/exception/user/InsufficientPointException.kt diff --git a/src/main/kotlin/com/routebox/routebox/application/route/PurchaseRouteUseCase.kt b/src/main/kotlin/com/routebox/routebox/application/route/PurchaseRouteUseCase.kt index c9b3e83..dfdf376 100644 --- a/src/main/kotlin/com/routebox/routebox/application/route/PurchaseRouteUseCase.kt +++ b/src/main/kotlin/com/routebox/routebox/application/route/PurchaseRouteUseCase.kt @@ -13,6 +13,7 @@ import com.routebox.routebox.domain.user_point_history.UserPointHistory import com.routebox.routebox.domain.user_point_history.UserPointHistoryService import com.routebox.routebox.exception.coupon.NoAvailableCouponException import com.routebox.routebox.exception.route.RouteNotFoundException +import com.routebox.routebox.exception.user.InsufficientPointException import com.routebox.routebox.exception.user.UserNotFoundException import org.springframework.stereotype.Component import org.springframework.transaction.annotation.Transactional @@ -33,6 +34,7 @@ class PurchaseRouteUseCase( * @throws NoAvailableCouponException (쿠폰으로 구매 시) 이용 가능한 쿠폰이 없는 경우 * @throws UserNotFoundException `buyerId`에 해당하는 유저가 없는 경우 * @throws RouteNotFoundException `routeId`에 해당하는, 구매할 루트 정보가 없는 경우 + * @throws InsufficientPointException (포인트로 구매 시) 루트를 구매하기에 포인트가 부족한 경우 */ @Transactional operator fun invoke(command: PurchaseRouteCommand) { diff --git a/src/main/kotlin/com/routebox/routebox/controller/route/RouteController.kt b/src/main/kotlin/com/routebox/routebox/controller/route/RouteController.kt index d30d06f..bb3124e 100644 --- a/src/main/kotlin/com/routebox/routebox/controller/route/RouteController.kt +++ b/src/main/kotlin/com/routebox/routebox/controller/route/RouteController.kt @@ -105,7 +105,12 @@ class RouteController( ) @ApiResponses( ApiResponse(responseCode = "200"), - ApiResponse(responseCode = "400", description = "[3003] (쿠폰으로 구매 시) 이용 가능한 쿠폰이 없는 경우", content = [Content()]), + ApiResponse( + responseCode = "400", + description = "

[3003] (쿠폰으로 구매 시) 이용 가능한 쿠폰이 없는 경우" + + "

[3005] (포인트로 구매 시) 루트를 구매하기에 포인트가 부족한 경우", + content = [Content()], + ), ) @PostMapping("/v1/routes/{routeId}/purchase") fun purchaseRoute( diff --git a/src/main/kotlin/com/routebox/routebox/domain/user/User.kt b/src/main/kotlin/com/routebox/routebox/domain/user/User.kt index 9c34891..b5193b2 100644 --- a/src/main/kotlin/com/routebox/routebox/domain/user/User.kt +++ b/src/main/kotlin/com/routebox/routebox/domain/user/User.kt @@ -124,4 +124,6 @@ class User( fun rejoin() { this.deletedAt = LocalDateTime.now() } + + fun canPurchase(point: Int): Boolean = this.point >= point } diff --git a/src/main/kotlin/com/routebox/routebox/domain/user/UserService.kt b/src/main/kotlin/com/routebox/routebox/domain/user/UserService.kt index f6ae5ae..5763cd3 100644 --- a/src/main/kotlin/com/routebox/routebox/domain/user/UserService.kt +++ b/src/main/kotlin/com/routebox/routebox/domain/user/UserService.kt @@ -3,6 +3,7 @@ package com.routebox.routebox.domain.user import com.routebox.routebox.domain.common.FileManager import com.routebox.routebox.domain.user.constant.Gender import com.routebox.routebox.domain.user.constant.LoginType +import com.routebox.routebox.exception.user.InsufficientPointException import com.routebox.routebox.exception.user.UserNicknameDuplicationException import com.routebox.routebox.exception.user.UserNotFoundException import com.routebox.routebox.exception.user.UserSocialLoginUidDuplicationException @@ -139,8 +140,8 @@ class UserService( @Transactional fun usePoint(userId: Long, point: Int): User { val user = getUserById(userId) - if (user.point < point) { - TODO("잔여 포인트가 부족할 경우 예외 발생") + if (user.canPurchase(point)) { + throw InsufficientPointException() } user.usePoint(point) return user diff --git a/src/main/kotlin/com/routebox/routebox/exception/CustomExceptionType.kt b/src/main/kotlin/com/routebox/routebox/exception/CustomExceptionType.kt index 19863b7..1a86d1f 100644 --- a/src/main/kotlin/com/routebox/routebox/exception/CustomExceptionType.kt +++ b/src/main/kotlin/com/routebox/routebox/exception/CustomExceptionType.kt @@ -27,6 +27,7 @@ enum class CustomExceptionType( USER_NICKNAME_DUPLICATION(3002, "이미 사용중인 닉네임입니다."), NO_AVAILABLE_COUPON(3003, "이용 가능한 쿠폰이 없습니다."), USER_WITHDRAWN(3004, "탈퇴한 유저입니다."), + INSUFFICIENT_POINT(3005, "포인트가 부족합니다."), /** * 루트 관련 예외 diff --git a/src/main/kotlin/com/routebox/routebox/exception/user/InsufficientPointException.kt b/src/main/kotlin/com/routebox/routebox/exception/user/InsufficientPointException.kt new file mode 100644 index 0000000..6b5a40f --- /dev/null +++ b/src/main/kotlin/com/routebox/routebox/exception/user/InsufficientPointException.kt @@ -0,0 +1,6 @@ +package com.routebox.routebox.exception.user + +import com.routebox.routebox.exception.CustomExceptionType +import com.routebox.routebox.exception.common.BadRequestException + +class InsufficientPointException : BadRequestException(exceptionType = CustomExceptionType.INSUFFICIENT_POINT)