개발 기록/도서관 관리 시스템

[Library Management System] 25.09.18 (49일)

dev.jelee 2025. 9. 18. 15:04

[ 작업한 내용 ]

< 사용자: 책 리뷰 상세 조회 >

1. messages.properties

- 사용자 책 리뷰 상세 관련 성공/에러 메시지 정의

success.review.detail=리뷰 상세 정보가 성공적으로 조회되었습니다.
error.review.user_not_same=로그인한 사용자와 리뷰 작성자가 일치하지 않습니다.

2. ReviewSuccessCode

- 사용자 책 리뷰 성공 코드 정의

REVIEW_DETAIL(HttpStatus.OK, "REVIEW_202", "success.review.detail");

3. ReviewErorrCode

- 사용자 책 리뷰 에러 코드 정의

REVIEW_USER_NOT_SAME(HttpStatus.BAD_REQUEST, "REVIEW_402", "error.review.user_not_same");

4. UserReviewDetailResDTO

- 사용자 책 리뷰 상세 응답 DTO 정의

- 책 제목, 저자, 출판사, 리뷰 내용, 작성일, 수정일 (bookTitle, author, publisher, content, createdDate, updatedDate)

@Getter
public class UserReviewDetailResDTO {
  private String bookTitle;
  private String author;
  private String publisher;
  private String content;
  private LocalDateTime createdDate;
  private LocalDateTime updatedDate;

  public UserReviewDetailResDTO(Review review) {
    this.bookTitle = review.getBook().getTitle();
    this.author = review.getBook().getAuthor();
    this.publisher = review.getBook().getPublisher();
    this.content = review.getContent();
    this.createdDate = review.getCreatedDate();
    this.updatedDate = review.getUpdatedDate();
  }
}

5. UserReviewController

- PathVariable로 reviewId를 파라미터로 전달받습니다.

- @AuthenticationPrincipal을 사용하여 로그인한 사용자의 정보를 User 엔티티형태로 저장합니다.

- Service 계층으로 reviewId와 user.getId()를 전달합니다.

- 결과는 UserReviewDetailResDTO형태로 저장됩니다.

- 클라이언트 측으로 결과와 성공 메시지를 ApiResponse.success()로 감싸서 반환합니다.

@GetMapping("/me/reviews/{reviewId}")
public ResponseEntity<?> detailReview(
  @PathVariable("reviewId") Long reviewId, 
  @AuthenticationPrincipal User user) {
  
    // 서비스로직
    UserReviewDetailResDTO responseDTO = userReviewService.detailReview(reviewId, user.getId());

    // 성공메시지
    String message = messageProvider.getMessage(ReviewSuccessCode.REVIEW_DETAIL.getMessage());

    // 반환
    return ResponseEntity
        .status(ReviewSuccessCode.REVIEW_DETAIL.getHttpStatus())
        .body(ApiResponse.success(
          ReviewSuccessCode.REVIEW_DETAIL, 
          message, 
          responseDTO));
}

6. UserReviewService

- userRepository.findById(usrId)로 사용자 조회를 하여 유효한 사용자라면 User 객체를 생성하고 유효하지 않은 사용자라면 UserErrorCode.USER_NOT_FOUND 예외를 던집니다.

- reviewRepository.findById(reviewId)로 리뷰 조회를 하여 유효한 리뷰라면 Review 객체를 생성하고 유효하지 않은 리뷰라면 ReviewErrorCode.REVIEW_NOT_FOUND 예외를 던집니다.

- 로그인한 사용자와 리뷰 작성자가 동일한지 검증을 합니다. 만약에 동일하지 않다면 ReviewErrorCode.REVIEW_USER_NOT_SAME 예외를 던집니다.

public UserReviewDetailResDTO detailReview(Long reviewId, Long userId) {

  // 사용자 조회 + 예외 처리
  User user = userRepository.findById(userId)
      .orElseThrow(() -> new BaseException(UserErrorCode.USER_NOT_FOUND));

  // 리뷰 조회 + 예외 처리
  Review review = reviewRepository.findById(reviewId)
      .orElseThrow(() -> new BaseException(ReviewErrorCode.REVIEW_NOT_FOUND));

  // 로그인한 사용자와 리뷰 작성자 검증 (본인 리뷰만 조회 가능)
  if (!user.getId().equals(review.getUser().getId())) {
    throw new BaseException(ReviewErrorCode.REVIEW_USER_NOT_SAME);
  }

  // UserReviewDetailResDTO 객체로 반환
  return new UserReviewDetailResDTO(review);
}

commit
상세 리뷰 조회 성공(좌), 실패 - 작성자와 일치하지 않음(가운데), 실패 - 없는 리뷰