Skip to content

Commit

Permalink
[BE] feat: 리뷰 목록 재구현 (#293)
Browse files Browse the repository at this point in the history
* refactor: 앤티티에 생성자 추가

* refactor: 리뷰 엔티티에 생성시간 추가

* refactor: 리뷰 목록에 보일 응답 생성

* refactor: 리뷰 목록 조회 로직 구현

* test: 테스트를 위한 레포지토리 생성

* test: 리뷰 목록 조회 테스트 추가

* style: 개행 수정

* refator: 리뷰에 카테고리 옵션 없는 경우 예외 추가

* refator: 레포지토리명 변경

* refator: 사용하지 않는 컬럼 제거

* refator: 사용하지 않는 기존 미리보기 로직 제거 후 대체

* style: 개행 수정

* refactor: 버전 관리를 위해 기존 버전, v2 분리

* style: 개행 수정
  • Loading branch information
skylar1220 authored Aug 11, 2024
1 parent e77d7e8 commit 3f8deba
Show file tree
Hide file tree
Showing 23 changed files with 372 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,10 @@ public class OptionGroup {

@Column(name = "max_selection_count", nullable = false)
private int maxSelectionCount;

public OptionGroup(long questionId, int minSelectionCount, int maxSelectionCount) {
this.questionId = questionId;
this.minSelectionCount = minSelectionCount;
this.maxSelectionCount = maxSelectionCount;
}
}
13 changes: 13 additions & 0 deletions backend/src/main/java/reviewme/question/domain/OptionItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
Expand All @@ -28,4 +30,15 @@ public class OptionItem {

@Column(name = "position", nullable = false)
private int position;

@Column(name = "option_type", nullable = false)
@Enumerated(EnumType.STRING)
private OptionType optionType;

public OptionItem(String content, long optionGroupId, int position, OptionType optionType) {
this.content = content;
this.optionGroupId = optionGroupId;
this.position = position;
this.optionType = optionType;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package reviewme.question.domain;

public enum OptionType {
CATEGORY,
KEYWORD,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package reviewme.question.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import reviewme.question.domain.OptionGroup;

@Repository
public interface OptionGroupRepository extends JpaRepository<OptionGroup, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package reviewme.question.repository;

import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import reviewme.question.domain.OptionItem;
import reviewme.question.domain.OptionType;

@Repository
public interface OptionItemRepository extends JpaRepository<OptionItem, Long> {

List<OptionItem> findAllByOptionType(OptionType optionType);

boolean existsByOptionTypeAndId(OptionType optionType, long id);
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import reviewme.global.HeaderProperty;
import reviewme.review.dto.request.CreateReviewRequest;
import reviewme.review.dto.response.ReceivedReviewsResponse;
import reviewme.review.dto.response.ReceivedReviewsResponse2;
import reviewme.review.dto.response.ReviewDetailResponse;
import reviewme.review.dto.response.ReviewSetupResponse;
import reviewme.review.service.ReviewService;
Expand Down Expand Up @@ -45,6 +46,14 @@ public ResponseEntity<ReceivedReviewsResponse> findReceivedReviews(
return ResponseEntity.ok(response);
}

@GetMapping("/v2/reviews")
public ResponseEntity<ReceivedReviewsResponse2> findReceivedReviews2(
@HeaderProperty(GROUP_ACCESS_CODE_HEADER) String groupAccessCode
) {
ReceivedReviewsResponse2 response = reviewService.findReceivedReviews2(groupAccessCode);
return ResponseEntity.ok(response);
}

@GetMapping("/reviews/{id}")
public ResponseEntity<ReviewDetailResponse> findReceivedReviewDetail(
@PathVariable long id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,9 @@ public class CheckboxAnswer {
@ElementCollection
@CollectionTable(name = "selected_option_ids")
private List<Long> selectedOptionIds;

public CheckboxAnswer(long questionId, List<Long> selectedOptionIds) {
this.questionId = questionId;
this.selectedOptionIds = selectedOptionIds;
}
}
14 changes: 14 additions & 0 deletions backend/src/main/java/reviewme/review/domain/Review2.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import java.time.LocalDateTime;
import java.util.List;
import lombok.AccessLevel;
import lombok.Getter;
Expand Down Expand Up @@ -37,4 +38,17 @@ public class Review2 {
@OneToMany(cascade = CascadeType.PERSIST)
@JoinColumn(name = "review_id", nullable = false, updatable = false)
private List<CheckboxAnswer> checkboxAnswers;

@Column(name = "created_at", nullable = false)
private LocalDateTime createdAt;

public Review2(long templateId, long reviewGroupId,
List<TextAnswer> textAnswers, List<CheckboxAnswer> checkboxAnswers,
LocalDateTime createdAt) {
this.templateId = templateId;
this.reviewGroupId = reviewGroupId;
this.textAnswers = textAnswers;
this.checkboxAnswers = checkboxAnswers;
this.createdAt = createdAt;
}
}
5 changes: 5 additions & 0 deletions backend/src/main/java/reviewme/review/domain/TextAnswer.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,9 @@ public class TextAnswer {

@Column(name = "text", nullable = false, length = 1_000)
private String text;

public TextAnswer(long questionId, String text) {
this.questionId = questionId;
this.text = text;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package reviewme.review.domain.exception;

import lombok.extern.slf4j.Slf4j;
import reviewme.global.exception.NotFoundException;

@Slf4j
public class CategoryOptionByReviewNotFoundException extends NotFoundException {

public CategoryOptionByReviewNotFoundException(long reviewId) {
super("리뷰에 선택한 카테고리가 없어요.");
log.warn("CategoryOptionNotFoundException is occured - reviewId: {}", reviewId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package reviewme.review.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;

@Schema(name = "선택된 카테고리 응답")
public record ReceivedReviewCategoryResponse(

@Schema(description = "카테고리 ID")
long optionId,

@Schema(description = "카테고리 내용")
String content
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package reviewme.review.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;
import java.time.LocalDate;
import java.util.List;

@Schema(name = "리뷰 내용 응답")
public record ReceivedReviewResponse2(

@Schema(description = "리뷰 ID")
long id,

@Schema(description = "리뷰 작성일")
LocalDate createdAt,

@Schema(description = "응답 내용 미리보기")
String contentPreview,

@Schema(description = "선택된 카테고리 목록")
List<ReceivedReviewCategoryResponse> categories
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package reviewme.review.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;
import java.util.List;

@Schema(name = "내가 받은 리뷰 목록 응답")
public record ReceivedReviewsResponse2(

@Schema(description = "리뷰이 이름")
String revieweeName,

@Schema(description = "프로젝트 이름")
String projectName,

@Schema(description = "받은 리뷰 미리보기 목록")
List<ReceivedReviewResponse2> reviews
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package reviewme.review.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import reviewme.review.domain.CheckboxAnswer;

@Repository
public interface CheckboxAnswerRepository extends JpaRepository<CheckboxAnswer, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package reviewme.review.repository;

import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import reviewme.review.domain.Review2;

@Repository
public interface Review2Repository extends JpaRepository<Review2, Long> {

@Query("SELECT r FROM Review2 r WHERE r.reviewGroupId=:reviewGroupId ORDER BY r.createdAt DESC")
List<Review2> findReceivedReviewsByGroupId(long reviewGroupId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.util.List;
import reviewme.review.domain.ReviewContent;
import reviewme.review.domain.TextAnswer;

public class ReviewPreviewGenerator {

Expand All @@ -17,4 +18,15 @@ public String generatePreview(List<ReviewContent> reviewContents) {
}
return answer;
}

public String generatePreview2(List<TextAnswer> reviewTextAnswers) {
if (reviewTextAnswers.isEmpty()) {
return "";
}
String answer = reviewTextAnswers.get(0).getText();
if (answer.length() > PREVIEW_LENGTH) {
return answer.substring(0, PREVIEW_LENGTH);
}
return answer;
}
}
50 changes: 50 additions & 0 deletions backend/src/main/java/reviewme/review/service/ReviewService.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,33 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import reviewme.keyword.repository.KeywordRepository;
import reviewme.question.domain.OptionType;
import reviewme.question.domain.Question;
import reviewme.question.repository.OptionItemRepository;
import reviewme.review.domain.CheckboxAnswer;
import reviewme.review.domain.Review;
import reviewme.review.domain.Review2;
import reviewme.review.domain.ReviewContent;
import reviewme.review.domain.ReviewKeyword;
import reviewme.review.domain.exception.CategoryOptionByReviewNotFoundException;
import reviewme.review.domain.exception.ReviewGroupNotFoundByGroupAccessCodeException;
import reviewme.review.domain.exception.ReviewGroupNotFoundByRequestReviewCodeException;
import reviewme.review.domain.exception.ReviewIsNotInReviewGroupException;
import reviewme.review.dto.request.CreateReviewContentRequest;
import reviewme.review.dto.request.CreateReviewRequest;
import reviewme.review.dto.response.KeywordResponse;
import reviewme.review.dto.response.QuestionSetupResponse;
import reviewme.review.dto.response.ReceivedReviewCategoryResponse;
import reviewme.review.dto.response.ReceivedReviewKeywordsResponse;
import reviewme.review.dto.response.ReceivedReviewResponse;
import reviewme.review.dto.response.ReceivedReviewResponse2;
import reviewme.review.dto.response.ReceivedReviewsResponse;
import reviewme.review.dto.response.ReceivedReviewsResponse2;
import reviewme.review.dto.response.ReviewContentResponse;
import reviewme.review.dto.response.ReviewDetailResponse;
import reviewme.review.dto.response.ReviewSetupResponse;
import reviewme.review.repository.QuestionRepository;
import reviewme.review.repository.Review2Repository;
import reviewme.review.repository.ReviewKeywordRepository;
import reviewme.review.repository.ReviewRepository;
import reviewme.reviewgroup.domain.ReviewGroup;
Expand All @@ -38,6 +47,8 @@ public class ReviewService {
private final ReviewGroupRepository reviewGroupRepository;
private final QuestionRepository questionRepository;
private final KeywordRepository keywordRepository;
private final OptionItemRepository optionItemRepository;
private final Review2Repository review2Repository;

private final ReviewCreationQuestionValidator reviewCreationQuestionValidator;
private final ReviewCreationKeywordValidator reviewCreationKeywordValidator;
Expand Down Expand Up @@ -143,6 +154,45 @@ private ReviewDetailResponse createReviewDetailResponse(Review review, ReviewGro
);
}

@Transactional(readOnly = true)
public ReceivedReviewsResponse2 findReceivedReviews2(String groupAccessCode) {
ReviewGroup reviewGroup = reviewGroupRepository.findByGroupAccessCode(groupAccessCode)
.orElseThrow(() -> new ReviewGroupNotFoundByGroupAccessCodeException(groupAccessCode));

List<ReceivedReviewResponse2> reviewResponses =
review2Repository.findReceivedReviewsByGroupId(reviewGroup.getId())
.stream()
.map(this::createReceivedReviewResponse2)
.toList();

return new ReceivedReviewsResponse2(reviewGroup.getReviewee(), reviewGroup.getProjectName(), reviewResponses);
}

private ReceivedReviewResponse2 createReceivedReviewResponse2(Review2 review) {
CheckboxAnswer checkboxAnswer = review.getCheckboxAnswers()
.stream()
.filter(answer -> optionItemRepository.existsByOptionTypeAndId(
OptionType.CATEGORY, answer.getSelectedOptionIds().get(0)
))
.findFirst()
.orElseThrow(() -> new CategoryOptionByReviewNotFoundException(review.getId()));

List<ReceivedReviewCategoryResponse> categoryResponses =
optionItemRepository.findAllById(checkboxAnswer.getSelectedOptionIds())
.stream()
.map(optionItem -> new ReceivedReviewCategoryResponse(
optionItem.getId(), optionItem.getContent()
))
.toList();

return new ReceivedReviewResponse2(
review.getId(),
review.getCreatedAt().toLocalDate(),
reviewPreviewGenerator.generatePreview2(review.getTextAnswers()),
categoryResponses
);
}

@Transactional(readOnly = true)
public ReceivedReviewsResponse findReceivedReviews(String groupAccessCode) {
ReviewGroup reviewGroup = reviewGroupRepository.findByGroupAccessCode(groupAccessCode)
Expand Down
9 changes: 9 additions & 0 deletions backend/src/main/java/reviewme/template/domain/Section.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,13 @@ public class Section {

@Column(name = "position", nullable = false)
private int position;

public Section(VisibleType visibleType, List<Long> questionIds,
Long onSelectedOptionId, String header, int position) {
this.visibleType = visibleType;
this.questionIds = questionIds;
this.onSelectedOptionId = onSelectedOptionId;
this.header = header;
this.position = position;
}
}
4 changes: 4 additions & 0 deletions backend/src/main/java/reviewme/template/domain/Template.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,8 @@ public class Template {
@ElementCollection
@CollectionTable(name = "section_ids", joinColumns = @JoinColumn(name = "template_id"))
List<Long> sectionIds;

public Template(List<Long> sectionIds) {
this.sectionIds = sectionIds;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package reviewme.template.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import reviewme.template.domain.Section;

@Repository
public interface SectionRepository extends JpaRepository<Section, Long> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package reviewme.template.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import reviewme.template.domain.Template;

@Repository
public interface TemplateRepository extends JpaRepository<Template, Long> {
}
Loading

0 comments on commit 3f8deba

Please sign in to comment.