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

[BE] feat: 리뷰 목록 재구현 #293

Merged
merged 14 commits into from
Aug 11, 2024
Merged
Show file tree
Hide file tree
Changes from 12 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
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 @@ -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;
}
}
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
Expand Up @@ -16,7 +16,7 @@ public record ReceivedReviewResponse(
@Schema(description = "응답 내용 미리보기")
String contentPreview,

@Schema(description = "선택된 키워드 목록")
List<ReceivedReviewKeywordsResponse> keywords
@Schema(description = "선택된 카테고리 목록")
List<ReceivedReviewCategoryResponse> categories
) {
}
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
@@ -1,17 +1,17 @@
package reviewme.review.service;

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

public class ReviewPreviewGenerator {

private static final int PREVIEW_LENGTH = 150;

public String generatePreview(List<ReviewContent> reviewContents) {
if (reviewContents.isEmpty()) {
public String generatePreview2(List<TextAnswer> reviewTextAnswers) {
if (reviewTextAnswers.isEmpty()) {
return "";
}
String answer = reviewContents.get(0).getAnswer();
String answer = reviewTextAnswers.get(0).getText();
if (answer.length() > PREVIEW_LENGTH) {
return answer.substring(0, PREVIEW_LENGTH);
}
Expand Down
47 changes: 32 additions & 15 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,30 @@
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.ReceivedReviewKeywordsResponse;
import reviewme.review.dto.response.ReceivedReviewCategoryResponse;
import reviewme.review.dto.response.ReceivedReviewResponse;
import reviewme.review.dto.response.ReceivedReviewsResponse;
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 +44,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 @@ -147,26 +155,35 @@ private ReviewDetailResponse createReviewDetailResponse(Review review, ReviewGro
public ReceivedReviewsResponse findReceivedReviews(String groupAccessCode) {
ReviewGroup reviewGroup = reviewGroupRepository.findByGroupAccessCode(groupAccessCode)
.orElseThrow(() -> new ReviewGroupNotFoundByGroupAccessCodeException(groupAccessCode));
List<ReceivedReviewResponse> reviewResponses =
reviewRepository.findReceivedReviewsByGroupId(reviewGroup.getId())
.stream()
.map(this::createReceivedReviewResponse)
.toList();

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

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

private ReceivedReviewResponse createReceivedReviewResponse(Review review) {
List<ReceivedReviewKeywordsResponse> keywordsResponses =
reviewKeywordRepository.findAllByReviewId(review.getId())
.stream()
.map(reviewKeyword -> keywordRepository.getKeywordById(reviewKeyword.getKeywordId()))
.map(keyword -> new ReceivedReviewKeywordsResponse(keyword.getId(), keyword.getContent()))
.toList();
private ReceivedReviewResponse createReceivedReviewResponse(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 ReceivedReviewResponse(
review.getId(),
review.getCreatedAt().toLocalDate(),
reviewPreviewGenerator.generatePreview(review.getReviewContents()),
keywordsResponses
reviewPreviewGenerator.generatePreview2(review.getTextAnswers()),
categoryResponses
);
}
}
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;
}
}
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> {
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import reviewme.review.domain.ReviewContent;
import reviewme.review.domain.TextAnswer;

class ReviewPreviewGeneratorTest {

Expand All @@ -15,10 +15,10 @@ class ReviewPreviewGeneratorTest {
// given
ReviewPreviewGenerator reviewPreviewGenerator = new ReviewPreviewGenerator();
String answer = "*".repeat(151);
ReviewContent reviewContent = new ReviewContent(1L, answer);
TextAnswer textAnswer = new TextAnswer(1, answer);

// when
String actual = reviewPreviewGenerator.generatePreview(List.of(reviewContent));
String actual = reviewPreviewGenerator.generatePreview2(List.of(textAnswer));

// then
assertThat(actual).hasSize(150);
Expand All @@ -30,10 +30,10 @@ class ReviewPreviewGeneratorTest {
// given
ReviewPreviewGenerator reviewPreviewGenerator = new ReviewPreviewGenerator();
String answer = "*".repeat(length);
ReviewContent reviewContent = new ReviewContent(1L, answer);
TextAnswer textAnswer = new TextAnswer(1, answer);

// when
String actual = reviewPreviewGenerator.generatePreview(List.of(reviewContent));
String actual = reviewPreviewGenerator.generatePreview2(List.of(textAnswer));

// then
assertThat(actual).hasSize(length);
Expand Down
Loading