Skip to content

Commit

Permalink
refactor: 경매 구매 요청 시 경매 재고가 부족하다면 200응답을 주도록 변경한다. (#321)
Browse files Browse the repository at this point in the history
* feat: 성공 상태를 반환하는 커스텀 예외 추가 및 핸들링

* feat: 경매 재고가 부족한 요청과, 구매 불가능한 수량을 요청했을때의 상황을 분리하여 처리합니다.

- 경매 재고가 부족하면 200으로 반환 처리되는 예외를 발생
- 구매 불가능한 수량을 요청한 경우 BadReqeustException을 발생시킵니다.

* docs: api docs 에러코드 업데이트
  • Loading branch information
HiiWee authored Aug 27, 2024
1 parent a2771af commit 63eebfb
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 63 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Team7-ELEVEN

[API-DOCS](https://woowa-techcamp-2024.github.io/Team7-ELEVEN/src/main/resources/static/index.html)
[API-DOCS](https://woowa-techcamp-2024.github.io/Team7-ELEVEN/src/main/resources/docs/index.html)
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.wootecam.luckyvickyauction.global.exception.BadRequestException;
import com.wootecam.luckyvickyauction.global.exception.ErrorCode;
import com.wootecam.luckyvickyauction.global.exception.SuccessfulOperationException;
import java.time.Duration;
import java.time.LocalDateTime;
import lombok.Builder;
Expand Down Expand Up @@ -179,29 +180,22 @@ private void verifyCurrentPrice(long inputPrice, LocalDateTime requestTime) {
}

private void verifyPurchaseQuantity(long quantity) {
if (!canPurchase(quantity)) {
String message = String.format(
"해당 수량만큼 구매할 수 없습니다. 재고: %d, 요청: %d, 인당구매제한: %d", currentStock, quantity,
if (isOutOfBoundQuantity(quantity)) {
String message = String.format("구매 가능 갯수를 초과하거나 0이하의 갯수만큼 구매할 수 없습니다. 요청: %d, 인당구매제한: %d", quantity,
maximumPurchaseLimitCount);
throw new BadRequestException(message, ErrorCode.A012);
throw new BadRequestException(message, ErrorCode.A030);
}
if (!hasEnoughStock(quantity)) {
String message = String.format("재고가 부족합니다. 현재 재고: %d, 요청 구매 수량: %d", currentStock, quantity);
throw new SuccessfulOperationException(message, ErrorCode.A012);
}
}

/**
* 해당 수량만큼 구매가 가능한지 확인한다. <br> 1. 구매 요청이 0보다 작은지 확인합니다. <br> 2. 인당 구매 수량 제한을 넘기지 않는지 확인합니다. <br> 3. 구매 요청 수량보다 햔재
* 재고가 많은지 확인합니다.
*
* @param quantity 구매를 원하는 수량
* @return 구매가 가능한 경우 True, 구매가 불가능한 경우 False를 반환한다.
*/
private boolean canPurchase(long quantity) {
if (quantity <= 0) {
return false;
}
if (quantity > maximumPurchaseLimitCount) {
return false;
}
private boolean isOutOfBoundQuantity(long quantity) {
return quantity > maximumPurchaseLimitCount || quantity <= 0;
}

private boolean hasEnoughStock(long quantity) {
return currentStock >= quantity;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public enum ErrorCode {
A009("경매 생성 시, 할인율이 0퍼센트 미만이거나 50 퍼센트를 초과한 경우 예외가 발생합니다."),
A010("경매 조회 시, 경매를 찾을 수 없는 경우 예외가 발생합니다."),
A011("경매 정보 생성 시, 현재 가격은 0과 같거나 작을 경우 예외가 발생합니다."),
A012("요청 수량만큼 경매 상품 구입이 불가능 할 때 예외가 발생합니다."),
A012("경매 입찰 시, 최대 가능 수량은 넘지 않지만, 남아있는 재고가 부족한 경우 예외가 발생합니다. (비즈니스적 예외가 아니라 200응답으로 반환됩니다."),
A013("진행 중이지 않은 경매를 입찰하려고 할 때, 예외가 발생합니다."),
A014("경매 생성 시, 경매 시작 시간이 현재 시간보다 이른 경우 예외가 발생합니다."),
A015("환불로 인한 재고 변경 시, 추가 및 삭제하는 재고량이 1 미만일 경우 예외가 발생합니다."),
Expand All @@ -32,6 +32,7 @@ public enum ErrorCode {
A027("경매 입찰 요청 시, 요청 수량이 1 미만일 경우 예외가 발생합니다."),
A028("경매 생성 시, 경매 지속 시간에서 경매 할인 주기 시간을 나누었을때, 나누어 떨어지지 않는 경우 예외가 발생합니다."),
A029("경매 생성 시, 경매 지속 시간이 정확히 분 단위가 아닌 경우 예외가 발생합니다."),
A030("경매 입찰 요청 시, 최대 가능 수량을 넘기거나 0이하의 수량을 구매하려고 할때 예외가 발생합니다."),

// Receipt 관련 예외 코드
R000("거래 내역 조회 시, 거래 내역을 찾을 수 없을 경우 예외가 발생합니다."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@ public ResponseEntity<ErrorResponse> handleInfraStructure(final InfraStructureEx
.body(ErrorResponse.of(e.getMessage(), e.getErrorCode().name()));
}

@ExceptionHandler(SuccessfulOperationException.class)
public ResponseEntity<ErrorResponse> handleSuccessfulOperationException(final SuccessfulOperationException e) {
log.warn("SUCCESS RESULT CODE {} : {}", e.getErrorCode(), e.getMessage());
return ResponseEntity.ok()
.body(ErrorResponse.of(e.getMessage(), e.getErrorCode().name()));
}

@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleInternalServerError(final Exception e) {
StringWriter out = new StringWriter();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.wootecam.luckyvickyauction.global.exception;

public class SuccessfulOperationException extends CustomException {

public SuccessfulOperationException(String message, ErrorCode errorCode) {
super(message, errorCode);
}
}
76 changes: 38 additions & 38 deletions src/main/resources/docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -829,20 +829,20 @@ <h4 id="_경매_목록_조회_http_response"><a class="link" href="#_경매_목
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
Content-Length: 329
Content-Length: 330

[ {
"id" : 1,
"title" : "쓸만한 경매품 1",
"price" : 2000,
"startedAt" : "2024-08-26T21:18:34.51341",
"finishedAt" : "2024-08-26T21:48:34.513414"
"startedAt" : "2024-08-27T14:44:34.150396",
"finishedAt" : "2024-08-27T15:14:34.150405"
}, {
"id" : 2,
"title" : "쓸만한 경매품 2",
"price" : 4000,
"startedAt" : "2024-08-26T21:18:34.513429",
"finishedAt" : "2024-08-26T21:48:34.513431"
"startedAt" : "2024-08-27T14:44:34.150427",
"finishedAt" : "2024-08-27T15:14:34.150429"
} ]</code></pre>
</div>
</div>
Expand Down Expand Up @@ -1322,7 +1322,7 @@ <h4 id="_경매_등록고정_할인_정책_http_request"><a class="link" href="#
<div class="content">
<pre class="highlightjs highlight nowrap"><code class="language-http hljs" data-lang="http">POST /auctions HTTP/1.1
Content-Type: application/json;charset=UTF-8
Content-Length: 340
Content-Length: 338
Host: localhost:8080
Cookie: JSESSIONID=sessionId

Expand All @@ -1336,8 +1336,8 @@ <h4 id="_경매_등록고정_할인_정책_http_request"><a class="link" href="#
"variationWidth" : 100
},
"variationDuration" : "PT10M",
"startedAt" : "2024-08-26T22:18:34.772453",
"finishedAt" : "2024-08-26T23:18:34.772453",
"startedAt" : "2024-08-27T15:44:34.42135",
"finishedAt" : "2024-08-27T16:44:34.42135",
"isShowStock" : true
}</code></pre>
</div>
Expand Down Expand Up @@ -1505,8 +1505,8 @@ <h4 id="_경매_등록퍼센트_할인_정책_http_request"><a class="link" href
"discountRate" : 10.0
},
"variationDuration" : "PT10M",
"startedAt" : "2024-08-26T22:18:34.753005",
"finishedAt" : "2024-08-26T23:18:34.753005",
"startedAt" : "2024-08-27T15:44:34.398981",
"finishedAt" : "2024-08-27T16:44:34.398981",
"isShowStock" : true
}</code></pre>
</div>
Expand Down Expand Up @@ -1741,7 +1741,7 @@ <h4 id="_경매_목록_조회_2_http_response"><a class="link" href="#_경매_
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
Content-Length: 500
Content-Length: 502

[ {
"id" : 1,
Expand All @@ -1750,17 +1750,17 @@ <h4 id="_경매_목록_조회_2_http_response"><a class="link" href="#_경매_
"currentPrice" : 1500,
"totalStock" : 100,
"currentStock" : 30,
"startedAt" : "2024-08-26T21:18:34.716375",
"finishedAt" : "2024-08-26T21:48:34.716379"
"startedAt" : "2024-08-27T14:44:34.360629",
"finishedAt" : "2024-08-27T15:14:34.360633"
}, {
"id" : 2,
"title" : "내가 판매하는 경매품 2",
"originPrice" : 4000,
"currentPrice" : 3500,
"totalStock" : 200,
"currentStock" : 60,
"startedAt" : "2024-08-26T21:18:34.716398",
"finishedAt" : "2024-08-26T21:48:34.7164"
"startedAt" : "2024-08-27T14:44:34.360652",
"finishedAt" : "2024-08-27T15:14:34.360654"
} ]</code></pre>
</div>
</div>
Expand Down Expand Up @@ -1928,8 +1928,8 @@ <h4 id="_경매_상세_조회고정_할인_정책_조회_2_http_response"><a cla
"variationWidth" : 10
},
"variationDuration" : "PT10M",
"startedAt" : "2024-08-26T21:18:34.677127",
"finishedAt" : "2024-08-26T22:18:34.677132",
"startedAt" : "2024-08-27T14:44:34.322866",
"finishedAt" : "2024-08-27T15:44:34.322869",
"isShowStock" : true
}</code></pre>
</div>
Expand Down Expand Up @@ -2115,7 +2115,7 @@ <h4 id="_경매_상세_조회퍼센트_할인_정책_조회_2_http_response"><a
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
Content-Length: 421
Content-Length: 422

{
"auctionId" : 1,
Expand All @@ -2130,8 +2130,8 @@ <h4 id="_경매_상세_조회퍼센트_할인_정책_조회_2_http_response"><a
"discountRate" : 10.0
},
"variationDuration" : "PT10M",
"startedAt" : "2024-08-26T21:18:34.696537",
"finishedAt" : "2024-08-26T22:18:34.696543",
"startedAt" : "2024-08-27T14:44:34.340307",
"finishedAt" : "2024-08-27T15:44:34.340312",
"isShowStock" : true
}</code></pre>
</div>
Expand Down Expand Up @@ -2331,7 +2331,7 @@ <h4 id="_경매_입찰_http_response"><a class="link" href="#_경매_입찰_http
Content-Length: 58

{
"receiptId" : "3eacd742-a495-4c9c-b3eb-824fd5af9bc2"
"receiptId" : "998e6fcb-74bf-4e7b-8752-2d09686bca89"
}</code></pre>
</div>
</div>
Expand Down Expand Up @@ -2453,7 +2453,7 @@ <h3 id="_경매_환불"><a class="link" href="#_경매_환불">경매 환불</a>
<h4 id="_경매_환불_http_request"><a class="link" href="#_경매_환불_http_request">HTTP request</a></h4>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code class="language-http hljs" data-lang="http">PUT /receipts/6fc8be44-d654-41fa-91fe-247de393ca88/refund HTTP/1.1
<pre class="highlightjs highlight nowrap"><code class="language-http hljs" data-lang="http">PUT /receipts/4a8e6fb5-6dc9-4fbd-9d03-5098c4e24f26/refund HTTP/1.1
Content-Type: application/json;charset=UTF-8
Accept: application/json
Host: localhost:8080
Expand Down Expand Up @@ -2546,21 +2546,21 @@ <h4 id="_구매자_거래_목록_조회구매자_권한_필요_http_response"><a
Content-Length: 536

[ {
"id" : "60879b91-be01-44cf-917f-4469031acd35",
"id" : "fd6017f1-90dd-460f-a498-999cbf28951d",
"auctionId" : 1,
"type" : "PURCHASED",
"productName" : "내가 구매한 상품1",
"quantity" : 10,
"price" : 1000
}, {
"id" : "8972765b-03e1-4dbe-a595-2c0c659c73af",
"id" : "11481b00-0a5a-4fb7-9aad-c3216f9fb9fd",
"auctionId" : 2,
"type" : "REFUND",
"productName" : "내가 구매한 상품2",
"quantity" : 20,
"price" : 2000
}, {
"id" : "79d48b5c-932b-4ad5-ad15-dd7dab65b5be",
"id" : "391fc8ad-79fd-4a6b-8616-f63ec7b8e182",
"auctionId" : 3,
"type" : "PURCHASED",
"productName" : "내가 구매한 상품3",
Expand Down Expand Up @@ -2707,21 +2707,21 @@ <h4 id="_판매자_거래_목록_조회판매자_권한_필요_http_response"><a
Content-Length: 533

[ {
"id" : "03a456a1-5877-4d4c-a4c2-63366b174778",
"id" : "16d9a1c9-ea02-4111-9c6d-01f5f9ab675e",
"auctionId" : 1,
"type" : "REFUND",
"productName" : "내가 판매한 상품1",
"price" : 1000,
"quantity" : 10
}, {
"id" : "9e83ad0b-1065-4fdb-b542-ed7d5d1b0905",
"id" : "948b82a3-6555-4a64-924c-c40405b2bfcb",
"auctionId" : 2,
"type" : "PURCHASED",
"productName" : "내가 판매한 상품2",
"price" : 2000,
"quantity" : 20
}, {
"id" : "e326d034-7a50-411a-b0da-49221ec4d04f",
"id" : "5979f98d-142d-4d54-8429-13a62e84f4e3",
"auctionId" : 3,
"type" : "REFUND",
"productName" : "내가 판매한 상품3",
Expand Down Expand Up @@ -2849,7 +2849,7 @@ <h3 id="_거래_상세_조회판매자_구매자_권한_필요"><a class="link"
<h4 id="_거래_상세_조회판매자_구매자_권한_필요_http_request"><a class="link" href="#_거래_상세_조회판매자_구매자_권한_필요_http_request">HTTP request</a></h4>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code class="language-http hljs" data-lang="http">GET /receipts/06fd3300-1726-4097-a9ec-a90369df55a4 HTTP/1.1
<pre class="highlightjs highlight nowrap"><code class="language-http hljs" data-lang="http">GET /receipts/d9a5afeb-4154-4c54-9592-30cf33265ca3 HTTP/1.1
Content-Type: application/json;charset=UTF-8
Host: localhost:8080
Cookie: JSESSIONID=sessionId</code></pre>
Expand All @@ -2865,19 +2865,19 @@ <h4 id="_거래_상세_조회판매자_구매자_권한_필요_http_response"><a
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
Content-Length: 303
Content-Length: 304

{
"receiptId" : "06fd3300-1726-4097-a9ec-a90369df55a4",
"receiptId" : "d9a5afeb-4154-4c54-9592-30cf33265ca3",
"productName" : "상품명",
"price" : 1000,
"quantity" : 1,
"receiptStatus" : "PURCHASED",
"auctionId" : 1,
"sellerId" : 1,
"buyerId" : 2,
"createdAt" : "2024-08-26T21:18:34.618016",
"updatedAt" : "2024-08-26T22:18:34.618021"
"createdAt" : "2024-08-27T14:44:34.259177",
"updatedAt" : "2024-08-27T15:44:34.259182"
}</code></pre>
</div>
</div>
Expand Down Expand Up @@ -3080,15 +3080,15 @@ <h3 id="error-code_error_code"><a class="link" href="#error-code_error_code">Err
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>A010</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">경매ID를 기준으로 경매를 찾으려고 했지만 찾을 수 없습니다.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">경매 조회 시, 경매를 찾을 수 없는 경우 예외가 발생합니다.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>A011</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">경매 정보 생성 시, 현재 가격은 0과 같거나 작을 경우 예외가 발생합니다.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>A012</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">요청 수량만큼 경매 상품 구입이 불가능 할 때 예외가 발생합니다.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">경매 입찰 시, 최대 가능 수량은 넘지 않지만, 남아있는 재고가 부족한 경우 예외가 발생합니다. (비즈니스적 예외가 아니라 200응답으로 반환됩니다.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>A013</code></p></td>
Expand Down Expand Up @@ -3156,11 +3156,11 @@ <h3 id="error-code_error_code"><a class="link" href="#error-code_error_code">Err
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>A029</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">경매 생성 시, 경매 할인 주기 시간이 경매 지속 시간보다 크거나 같은 경우 예외가 발생합니다.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">경매 생성 시, 경매 지속 시간이 정확히 분 단위가 아닌 경우 예외가 발생합니다.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>A030</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">경매 생성 시, 경매 지속 시간이 정확히 분 단위가 아닌 경우 예외가 발생합니다.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">경매 입찰 요청 시, 최대 가능 수량을 넘기거나 0이하의 수량을 구매하려고 할때 예외가 발생합니다.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>R000</code></p></td>
Expand Down Expand Up @@ -3295,7 +3295,7 @@ <h3 id="error-code_error_code"><a class="link" href="#error-code_error_code">Err
<div id="footer">
<div id="footer-text">
Version 0.0.1-SNAPSHOT<br>
Last updated 2024-08-24 13:08:20 +0900
Last updated 2024-08-24 16:24:00 +0900
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.3/highlight.min.js"></script>
Expand Down
Loading

0 comments on commit 63eebfb

Please sign in to comment.