Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

수정: 로그인 예외 핸들링, 관리자 api 엔드 포인트 수정 #114

Merged
merged 9 commits into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion front/src/apis/ApiController.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ const JwtInterceptor = () => {
},
);

// todo: response interceptor
return { instance };
};

Expand Down
1 change: 0 additions & 1 deletion front/src/pages/Favorite.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ function Favorite() {

return (
<div className="App">
{/*TODO: 갯수 넣기*/}
<h1>찜한 상품({items.length})</h1>
<table border="1" width="500" height="300" align="center">
<thead>
Expand Down
9 changes: 2 additions & 7 deletions front/src/pages/MyPage.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useNavigate } from 'react-router-dom';

const MyPage = () => {
// todo: 인증된 유저만 접근할 수 있게
const navigate = useNavigate();

return (
Expand All @@ -11,9 +10,7 @@ const MyPage = () => {
onClick={() => {
navigate(`/mypage/order`);
}}
>
주문 내역 {/* todo */}
</button>
></button>
<button
onClick={() => {
navigate(`/mypage/review`);
Expand All @@ -39,9 +36,7 @@ const MyPage = () => {
onClick={() => {
navigate(`/mypage/inquiry/products`);
}}
>
상품 문의 {/* todo */}
</button>
></button>
<button
onClick={() => {
navigate(`/mypage/inquiry`);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.devcourse.kurlymurly.api.admin;

import com.devcourse.kurlymurly.application.product.ProductFacade;
import com.devcourse.kurlymurly.auth.AuthUser;
import com.devcourse.kurlymurly.domain.service.OrderService;
import com.devcourse.kurlymurly.domain.service.OrderSupportService;
import com.devcourse.kurlymurly.domain.service.ProductCommand;
import com.devcourse.kurlymurly.domain.service.ReviewCommand;
import com.devcourse.kurlymurly.web.common.KurlyResponse;
import com.devcourse.kurlymurly.web.order.AnswerOrderSupport;
Expand All @@ -13,7 +13,6 @@
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
Expand All @@ -33,31 +32,33 @@
@RequestMapping("/admin")
public class AdminController {
private final ProductFacade productFacade;
private final ProductCommand productCommand;
private final ReviewCommand reviewCommand;
private final OrderService orderService;
private final OrderSupportService orderSupportService;

public AdminController(
ProductFacade productFacade,
ProductCommand productCommand,
ReviewCommand reviewCommand,
OrderService orderService,
OrderSupportService orderSupportService
) {
this.productFacade = productFacade;
this.productCommand = productCommand;
this.reviewCommand = reviewCommand;
this.orderService = orderService;
this.orderSupportService = orderSupportService;
}

@Tag(name = "admin")
@Operation(description = "[관리자 토큰 필요] 새로운 상품을 등록한다.", responses = {
@Operation(summary = "[관리자 토큰 필요] 새로운 상품을 등록한다.", responses = {
@ApiResponse(responseCode = "200", description = "성공적으로 상품을 등록했습니다."),
@ApiResponse(responseCode = "401", description = "권한이 없는 토큰이거나 토큰을 보내지 않은 경우")
})
@PostMapping("/products")
@ResponseStatus(OK)
public KurlyResponse<Void> createProduct(
@AuthenticationPrincipal AuthUser admin,
@RequestPart MultipartFile image,
@RequestPart ProductRequest.Create request
) {
Expand All @@ -66,122 +67,109 @@ public KurlyResponse<Void> createProduct(
}

@Tag(name = "admin")
@Operation(description = "[관리자 토큰 필요] 상품을 품절로 처리하는 API")
@ApiResponses({
@Operation(summary = "[관리자 토큰 필요] 상품을 품절로 처리하는 API", responses = {
@ApiResponse(responseCode = "200", description = "성공적으로 상품을 품절시켰습니다."),
@ApiResponse(responseCode = "401", description = "권한이 없는 토큰이거나 토큰을 보내지 않은 경우"),
@ApiResponse(responseCode = "404", description = "존재하지 않는 상품입니다.")
})
@PutMapping("/products/{productId}/sold-out")
@ResponseStatus(OK)
public KurlyResponse<Void> soldOutProduct(
@AuthenticationPrincipal AuthUser admin,
@PathVariable Long productId
) {
// productFacade.soldOutProduct(productId);
productCommand.soldOutProduct(productId);
return KurlyResponse.noData();
}

@Tag(name = "admin")
@Operation(description = "[관리자 토큰 필요] 상품을 삭제한다.")
@ApiResponses({
@Operation(summary = "[관리자 토큰 필요] 상품을 삭제한다.", responses = {
@ApiResponse(responseCode = "200", description = "성공적으로 상품을 삭제했습니다."),
@ApiResponse(responseCode = "401", description = "권한이 없는 토큰이거나 토큰을 보내지 않은 경우"),
@ApiResponse(responseCode = "404", description = "존재하지 않는 상품입니다.")
})
@DeleteMapping("/products/{productId}")
@ResponseStatus(OK)
public KurlyResponse<Void> deleteProduct(
@AuthenticationPrincipal AuthUser admin,
@PathVariable Long productId
) {
// productFacade.deleteProduct(productId);
productCommand.deleteProduct(productId);
return KurlyResponse.noData();
}

@Tag(name = "admin")
@Operation(description = "[관리자 토큰 필요] BANNED 리뷰로 변환 API")
@ApiResponses({
@Operation(summary = "[관리자 토큰 필요] BANNED 리뷰로 변환 API", responses = {
@ApiResponse(responseCode = "200", description = "review 상태를 BANNED로 변경한 경우"),
@ApiResponse(responseCode = "400", description = "리뷰 id가 명시되지 않은 경우"),
@ApiResponse(responseCode = "401", description = "토큰을 넣지 않은 경우")
})
@PatchMapping("/reviews/{reviewId}/ban")
@ResponseStatus(OK)
public KurlyResponse<Void> updateToBanned(
@AuthenticationPrincipal AuthUser admin,
@PathVariable Long reviewId
) {
reviewCommand.banned(reviewId);
return KurlyResponse.noData();
}

@Tag(name = "admin")
@Operation(description = "[관리자 토큰 필요] BEST 리뷰로 변환 API")
@ApiResponses({
@Operation(summary = "[관리자 토큰 필요] BEST 리뷰로 변환 API", responses = {
@ApiResponse(responseCode = "200", description = "review 상태를 BEST로 변경한 경우"),
@ApiResponse(responseCode = "400", description = "리뷰 id가 명시되지 않은 경우"),
@ApiResponse(responseCode = "401", description = "토큰을 넣지 않은 경우")
})
@PatchMapping("/reviews/{reviewId}/best")
@ResponseStatus(OK)
public KurlyResponse<Void> updateToBest(
@AuthenticationPrincipal AuthUser admin,
@PathVariable Long reviewId
) {
reviewCommand.toBestReview(reviewId);
return KurlyResponse.noData();
}

@Tag(name = "admin")
@Operation(description = "[관리자 토큰 필요] 주문을 다음 단계 상태로 변환 API")
@ApiResponses({
@Operation(summary = "[관리자 토큰 필요] 주문을 다음 단계 상태로 변환 API", responses = {
@ApiResponse(responseCode = "200", description = "order 상태를 PRODCESSING로 변경한 경우"),
@ApiResponse(responseCode = "400", description = "주문 id가 명시되지 않은 경우"),
@ApiResponse(responseCode = "401", description = "토큰을 넣지 않은 경우")
})
@PatchMapping("/orders/{orderId}/processing")
@ResponseStatus(OK)
public KurlyResponse<Void> changeToProcessing(
@AuthenticationPrincipal AuthUser admin,
@PathVariable Long orderId
) {
orderService.toNextState(orderId);
orderService.progressOrder(orderId);
return KurlyResponse.noData();
}

@Tag(name = "admin")
@Operation(description = "[관리자 토큰 필요] 주문을 취소하는 API")
@ApiResponses({
@Operation(summary = "[관리자 토큰 필요] 주문을 취소하는 API", responses = {
@ApiResponse(responseCode = "200", description = "order 상태를 CANCLED로 변경한 경우"),
@ApiResponse(responseCode = "400", description = "주문 id가 명시되지 않은 경우"),
@ApiResponse(responseCode = "401", description = "토큰을 넣지 않은 경우")
})
@PostMapping("/orders/{orderId}/cancel")
@ResponseStatus(OK)
public KurlyResponse<Void> changeToDone(
@AuthenticationPrincipal AuthUser admin,
@PathVariable Long orderId
) {
orderService.toCancel(orderId);
orderService.cancelOrder(orderId);
return KurlyResponse.noData();
}

@Tag(name = "admin")
@Operation(description = "[관리자 토큰 필요] 1:1 문의 답변 처리 API")
@ApiResponses({
@Operation(summary = "[관리자 토큰 필요] 1:1 문의 답변 처리 API", responses = {
@ApiResponse(responseCode = "200", description = "성공적으로 1:1 문의에 답변 해준 경우"),
@ApiResponse(responseCode = "400", description = "1:1 문의 id가 명시되지 않은 경우"),
@ApiResponse(responseCode = "401", description = "권한이 없는 토큰이거나 토큰을 보내지 않은 경우"),
@ApiResponse(responseCode = "404", description = "존재하지 않는 1:1 문의인 경우"),
})
@PostMapping("/orderSupports/answer")
@PostMapping("/orders/inquiries/{supportId}/answer")
@ResponseStatus(OK)
public KurlyResponse<Void> changeToAnswered(
@AuthenticationPrincipal AuthUser admin,
@PathVariable("supportId") Long orderSupportId,
@RequestBody @Valid AnswerOrderSupport.Request answerRequest
) {
orderSupportService.answered(answerRequest.orderSupportId(), answerRequest.content());
orderSupportService.answered(orderSupportId, answerRequest.content());
return KurlyResponse.noData();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public KurlyResponse<Page<ProductResponse.GetSimple>> getProductPagingOfCategory
@PathVariable Long categoryId,
@ModelAttribute KurlyPagingRequest request
) {
Page<ProductResponse.GetSimple> responses = productFacade.loadProductPageResponse(categoryId, request.toPageable());
Page<ProductResponse.GetSimple> responses = productFacade.loadProductPageResponse(categoryId, request);
return KurlyResponse.ok(responses);
}

Expand All @@ -71,7 +71,7 @@ public KurlyResponse<Page<ProductResponse.GetSimple>> getProductPagingOfCategory
public KurlyResponse<Page<ProductResponse.GetSimple>> getProductPagingOfNewProducts(
@ModelAttribute KurlyPagingRequest request
) {
Page<ProductResponse.GetSimple> responses = productFacade.loadNewProductPageResponse(request.toPageable());
Page<ProductResponse.GetSimple> responses = productFacade.loadNewProductPageResponse(request);
return KurlyResponse.ok(responses);
}

Expand All @@ -82,7 +82,7 @@ public KurlyResponse<Page<ProductResponse.GetSimple>> getProductPagingOfNewProdu
public KurlyResponse<Page<ProductResponse.GetSimple>> getProductPagingOfBestProducts(
@ModelAttribute KurlyPagingRequest request
) {
Page<ProductResponse.GetSimple> responses = productFacade.loadBestProductPageResponse(request.toPageable());
Page<ProductResponse.GetSimple> responses = productFacade.loadBestProductPageResponse(request);
return KurlyResponse.ok(responses);
}

Expand Down Expand Up @@ -118,6 +118,24 @@ public KurlyResponse<Void> createProductSupport(
return KurlyResponse.noData();
}

@Tag(name = "product")
@Operation(summary = "[토큰] 상품 리뷰 등록", description = "[토큰 필요] 리뷰 등록 API", responses = {
@ApiResponse(responseCode = "200", description = "성공적으로 review를 등록한 경우"),
@ApiResponse(responseCode = "400", description = "삭제된 상품에 후기를 작성해서 발생하는 에러"),
@ApiResponse(responseCode = "401", description = "토큰을 넣지 않아서 발생하는 에러"),
@ApiResponse(responseCode = "404", description = "주문 정보를 읽어오지 못해서 발생하는 에러")
})
@PostMapping("/{id}/review")
@ResponseStatus(OK)
public KurlyResponse<Void> registerReview(
@AuthenticationPrincipal AuthUser user,
@PathVariable("id") Long productId,
@RequestBody ReviewRequest.Create request
) {
productFacade.registerReview(user.getId(), productId, request);
return KurlyResponse.noData();
}

@Tag(name = "product")
@Operation(summary = "상품 찜하기", description = "[토큰 필요] 상품을 찜 목록에 등록한다.", responses = {
@ApiResponse(responseCode = "204", description = "성공적으로 찜 목록에 등록했습니다."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,6 @@ public ReviewController(ProductFacade productFacade) {
this.productFacade = productFacade;
}

@Tag(name = "review")
@Operation(summary = "[토큰] 리뷰 등록", description = "[토큰 필요] 리뷰 등록 API", responses = {
@ApiResponse(responseCode = "200", description = "성공적으로 review를 등록한 경우"),
@ApiResponse(responseCode = "400", description = "삭제된 상품에 후기를 작성해서 발생하는 에러"),
@ApiResponse(responseCode = "401", description = "토큰을 넣지 않아서 발생하는 에러"),
@ApiResponse(responseCode = "404", description = "주문 정보를 읽어오지 못해서 발생하는 에러")
})
@PostMapping
@ResponseStatus(OK) // todo: POST /products/1/review
public KurlyResponse<Void> registerReview(
@AuthenticationPrincipal AuthUser user,
@RequestBody ReviewRequest.Create request
) {
productFacade.registerReview(user.getId(), request);
return KurlyResponse.noData();
}

@Tag(name = "review")
@Operation(summary = "특정 리뷰 조회", description = "리뷰 ID로 특정 리뷰 조회 API", responses = {
@ApiResponse(responseCode = "200", description = "성공적으로 특정한 후기를 조회한 경우"),
Expand All @@ -62,20 +45,6 @@ public KurlyResponse<ReviewResponse.Reviewed> getSpecificReview(@PathVariable Lo
return KurlyResponse.ok(response);
}

@Tag(name = "review")
@Operation(summary = "[토큰] 사용자 리뷰 조회", description = "[토큰 필요] 사용자가 작성한 리뷰 조회 API", responses = {
@ApiResponse(responseCode = "200", description = "성공적으로 상품의 후기를 가져온 상태"),
@ApiResponse(responseCode = "401", description = "토큰을 넣지 않아서 발생하는 에러")
})
@GetMapping // todo: GET /users/reviews
@ResponseStatus(OK)
public KurlyResponse<List<ReviewResponse.Reviewed>> getAllReviewsOnMyPage(
@AuthenticationPrincipal AuthUser user
) {
List<ReviewResponse.Reviewed> response = productFacade.loadReviewsOfUser(user.getId());
return KurlyResponse.ok(response);
}

@Tag(name = "review")
@Operation(summary = "[토큰] 리뷰 수정", description = "[토큰 필요] 작성한 리뷰 수정 API", responses = {
@ApiResponse(responseCode = "200", description = "성공적으로 상품 후기를 수정한 경우"),
Expand Down
Loading