Skip to content

Commit

Permalink
FIX: (#145) 리뷰 도메인 도메인 계층을 재정의한다
Browse files Browse the repository at this point in the history
  • Loading branch information
anxi01 committed Feb 20, 2025
1 parent 4385cff commit 943d210
Show file tree
Hide file tree
Showing 7 changed files with 246 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.zerozero.review.domain.repository;

import com.zerozero.review.domain.model.ReviewLike;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.UUID;

public interface ReviewLikeRepository extends JpaRepository<ReviewLike, Long> {

ReviewLike findByReviewIdAndUserIdAndDeleted(UUID reviewId, UUID userId, Boolean deleted);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.zerozero.review.domain.repository;

import com.zerozero.review.domain.model.Review;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;
import java.util.UUID;

public interface ReviewRepository extends JpaRepository<Review, UUID> {

Boolean existsByUserIdAndStoreIdAndDeleted(UUID userId, UUID storeId, boolean deleted);

Optional<Review> findByIdAndDeleted(UUID id, Boolean deleted);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.zerozero.review.domain.response;

import com.zerozero.core.util.TimeUtil;
import com.zerozero.review.domain.model.Review;
import com.zerozero.review.domain.model.ZeroDrink;
import com.zerozero.user.domain.model.User;
import io.swagger.v3.oas.annotations.media.Schema;

import java.util.Set;
import java.util.UUID;

public record ReviewResponse(

@Schema(description = "리뷰 ID", example = "8e3006f4-3a16-11ef-9454-0242ac120002")
UUID id,

@Schema(description = "리뷰 내용", example = "제로 음료 판매중!")
String content,

@Schema(description = "제로 음료수 목록", example = "[\"COCA_COLA_ZERO\", \"PEPSI_ZERO\", \"SPRITE_ZERO\"]")
Set<ZeroDrink> zeroDrinks,

@Schema(description = "리뷰 작성일자, YYYY.MM.DD", example = "2024.08.27")
String createdAt,

@Schema(description = "좋아요 개수", example = "10")
int likeCount,

@Schema(description = "사용자가 좋아요를 눌렀는지 여부", example = "true")
boolean isLiked,

@Schema(description = "작성한 사용자 ID")
UUID userId,

@Schema(description = "닉네임", example = "제로")
String nickname
) {
public static ReviewResponse of(Review review, User user, int likeCount, boolean isLiked) {
return new ReviewResponse(
review.getId(),
review.getContent(),
review.getZeroDrinks(),
TimeUtil.toDotFormattedString(review.getCreatedAt().toLocalDate()),
likeCount,
isLiked,
user.getId(),
user.getNickname()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.zerozero.review.domain.service;

import com.zerozero.review.domain.model.Review;
import com.zerozero.review.domain.repository.ReviewRepository;
import com.zerozero.review.exception.ReviewErrorType;
import com.zerozero.review.exception.ReviewException;
import com.zerozero.user.domain.model.User;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.UUID;

@Log4j2
@Service
@RequiredArgsConstructor
@Transactional
public class DeleteStoreReviewUseCase {

private final ReviewRepository reviewRepository;

public void execute(UUID reviewId, User user) {
Review review = reviewRepository.findByIdAndDeleted(reviewId, false)
.orElseThrow(() -> new ReviewException(ReviewErrorType.NOT_EXIST_DELETABLE_REVIEW));
if (!review.isWrittenBy(user.getId())) {
log.error("[DeleteStoreReviewUseCase] User does not have review with id {}", reviewId);
throw new ReviewException(ReviewErrorType.USER_VALIDATION_FAILED);
}
review.getReviewLikes().clear();
review.getZeroDrinks().clear();
review.deleted(true);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.zerozero.review.domain.service;

import com.zerozero.review.domain.model.Review;
import com.zerozero.review.domain.model.ReviewLike;
import com.zerozero.review.domain.repository.ReviewLikeRepository;
import com.zerozero.review.domain.repository.ReviewRepository;
import com.zerozero.review.exception.ReviewErrorType;
import com.zerozero.review.exception.ReviewException;
import com.zerozero.user.domain.model.User;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.UUID;

@Service
@RequiredArgsConstructor
@Transactional
@Log4j2
public class LikeStoreReviewUseCase {

private final ReviewRepository reviewRepository;

private final ReviewLikeRepository reviewLikeRepository;

public void execute(UUID reviewId, User user) {
Review review = reviewRepository.findByIdAndDeleted(reviewId, false)
.orElseThrow(() -> new ReviewException(ReviewErrorType.NOT_EXIST_DELETABLE_REVIEW));
ReviewLike reviewLike = reviewLikeRepository.findByReviewIdAndUserIdAndDeleted(review.getId(), user.getId(), false);
if (reviewLike == null) {
log.info("[Like] User {} liked Review {}", user.getId(), review.getId());
reviewLike = new ReviewLike(review.getId(), user.getId());
reviewLikeRepository.save(reviewLike);
} else {
log.info("[Unlike] User {} unliked Review {}", user.getId(), review.getId());
reviewLikeRepository.delete(reviewLike);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.zerozero.review.domain.service;

import com.zerozero.review.domain.model.Review;
import com.zerozero.review.domain.response.ReviewResponse;
import com.zerozero.review.infrastructure.querydsl.ReviewQueryRepository;
import com.zerozero.store.presentation.request.ReadStoreRequest;
import com.zerozero.user.domain.model.User;
import com.zerozero.user.domain.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
@Log4j2
public class ReadStoreReviewUseCase {

private final ReviewQueryRepository reviewQueryRepository;

private final UserRepository userRepository;

public List<ReviewResponse> execute(ReadStoreRequest readStoreRequest, User user) {
List<Review> reviews = reviewQueryRepository.findByStoreIdAndFilter(readStoreRequest.storeId(), readStoreRequest.filter());
Map<UUID, User> reviewAuthorMap = getReviewAuthors(reviews);
return convertReviewResponse(user, reviews, reviewAuthorMap);
}

private List<ReviewResponse> convertReviewResponse(User user, List<Review> reviews, Map<UUID, User> reviewAuthorMap) {
if (user == null || reviews.isEmpty() || reviewAuthorMap.isEmpty()) {
return Collections.emptyList();
}
return reviews.stream()
.map(review -> {
User reviewAuthor = reviewAuthorMap.get(review.getUserId());
return ReviewResponse.of(review, reviewAuthor, review.getReviewLikes().size(), review.getReviewLikes().stream()
.anyMatch(like -> user.getId().equals(like.getUserId())));
})
.collect(Collectors.toList());
}

private Map<UUID, User> getReviewAuthors(List<Review> reviews) {
return userRepository.findAllByIdInAndDeleted(
reviews.stream()
.map(Review::getUserId)
.distinct()
.collect(Collectors.toList()),
false
).stream().collect(Collectors.toMap(User::getId, reviewAuthor -> reviewAuthor));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.zerozero.review.domain.service;

import com.zerozero.review.domain.model.Review;
import com.zerozero.review.domain.repository.ReviewRepository;
import com.zerozero.review.exception.ReviewErrorType;
import com.zerozero.review.exception.ReviewException;
import com.zerozero.review.presentation.request.ReviewRequest;
import com.zerozero.user.domain.model.User;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.UUID;

@Service
@RequiredArgsConstructor
@Transactional
@Log4j2
public class UpdateStoreReviewUseCase {

private final ReviewRepository reviewRepository;

public void execute(UUID reviewId, ReviewRequest reviewRequest, User user) {
Review review = reviewRepository.findByIdAndDeleted(reviewId, false).orElseThrow(() -> new ReviewException(ReviewErrorType.NOT_EXIST_REVIEW));
if (!review.isWrittenBy(user.getId())) {
log.error("[UpdateStoreReviewUseCase] User does not have review with id {}", reviewId);
throw new ReviewException(ReviewErrorType.USER_VALIDATION_FAILED);
}
review.updateContent(reviewRequest.content());
review.updateZeroDrinks(reviewRequest.zeroDrinks());
}

}

0 comments on commit 943d210

Please sign in to comment.