Skip to content

Commit

Permalink
[BE] feat: 리뷰 작성 API 구현 (#102)
Browse files Browse the repository at this point in the history
* refactor: 리뷰 요청 dto 수정

* refactor: 리뷰 콘텐츠 생성 시, 리뷰에 자신을 추가하도록 변경

* feat: QuestionRepository 추가

* feat: 리뷰 작성 기능 추가

* test: 리뷰 작성 테스트 추가

* refactor: ReviewGroup 생성 시, GithubIdReviewerGroup도 같이 저장되도록 변경

* refactor: GithubId equals 및 hashcode 재정의

* refactor: review 생성 시, reviewGroup이 null이 아니도록 변경

* refactor: EqualsAndHashCode에 id 명시

* refactor: reviewee를 reviewerGroup 통해서 받아오도록 변경

* refactor: 파라미터 long 타입으로 변경

* test: 사용하지 않는 변수 제거

* test: 파라미터별로 개행하도록 변경

* refactor: ReviewerGroupGithubIds의 reviewerGithubIds를 CascadeType.PERSIST로 변경

* chore: 다른 작업에서 진행될 사항으로 사용하지 않는 테스트 삭제
  • Loading branch information
Kimprodp authored Jul 25, 2024
1 parent 21447e1 commit a9b409f
Show file tree
Hide file tree
Showing 11 changed files with 97 additions and 159 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.AccessLevel;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "github_id_reviewer_group")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@EqualsAndHashCode(of = "id")
@Getter
Expand All @@ -25,6 +28,7 @@ public class GithubIdReviewerGroup {
private GithubId githubId;

@ManyToOne
@JoinColumn(name = "reviewer_group_id", nullable = false)
private ReviewerGroup reviewerGroup;

public GithubIdReviewerGroup(GithubId githubId, ReviewerGroup reviewerGroup) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package reviewme.member.domain;

import jakarta.persistence.CascadeType;
import jakarta.persistence.Embeddable;
import jakarta.persistence.OneToMany;
import java.util.List;
Expand All @@ -14,7 +15,7 @@
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class ReviewerGroupGithubIds {

@OneToMany(mappedBy = "reviewerGroup")
@OneToMany(mappedBy = "reviewerGroup", cascade = CascadeType.PERSIST)
private Set<GithubIdReviewerGroup> reviewerGithubIds;

public ReviewerGroupGithubIds(ReviewerGroup reviewerGroup, List<GithubId> githubIds) {
Expand Down
11 changes: 11 additions & 0 deletions backend/src/main/java/reviewme/review/domain/Review.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import lombok.AccessLevel;
import lombok.Getter;
Expand Down Expand Up @@ -42,6 +44,9 @@ public class Review {
@JoinColumn(name = "reviewer_group_id", nullable = false)
private ReviewerGroup reviewerGroup;

@OneToMany(mappedBy = "review")
private List<ReviewContent> reviewContents;

@Embedded
private Keywords keywords;

Expand All @@ -58,9 +63,11 @@ public Review(Member reviewer, Member reviewee, ReviewerGroup reviewerGroup,
}
this.reviewer = reviewer;
this.reviewee = reviewee;
this.reviewContents = new ArrayList<>();
this.keywords = new Keywords(keywords);
this.createdAt = createdAt;
reviewerGroup.addReview(this);
this.reviewerGroup = reviewerGroup;
this.isPublic = false;
}

Expand All @@ -71,4 +78,8 @@ public boolean isSubmittedBy(Member member) {
public boolean isForReviewee(Member member) {
return reviewee.equals(member);
}

public void addReviewContents(ReviewContent reviewContent) {
reviewContents.add(reviewContent);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public ReviewContent(Review review, Question question, String answer) {
this.review = review;
this.question = question;
this.answer = answer;
review.addReviewContents(this);
}

private void validateAnswerLength(String answer) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,16 @@

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;

@Schema(description = "리뷰 내용 등록 요청")
public record CreateReviewContentRequest(
@NotNull(message = "리뷰 항목 순서를 입력해주세요.")
@Schema(description = "리뷰 항목 순서")
Long order,

@NotBlank(message = "질문을 입력해주세요.")
@Schema(description = "리뷰 문항")
String question,
@NotBlank(message = "질문을 입력해주세요.")
Long questionId,

@NotBlank(message = "답변을 입력해주세요.")
@Schema(description = "리뷰 문항에 대한 답변")
@NotBlank(message = "답변을 입력해주세요.")
String answer
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,22 @@

@Schema(description = "리뷰 등록 요청")
public record CreateReviewRequest(
@NotNull(message = "리뷰어 아이디를 입력해주세요.")

@Schema(description = "리뷰어 ID")
@NotNull(message = "리뷰어 아이디를 입력해주세요.")
Long reviewerId,

@NotNull(message = "리뷰어 그룹 아이디를 입력해주세요.")
@Schema(description = "리뷰어 그룹 ID")
@NotNull(message = "리뷰어 그룹 아이디를 입력해주세요.")
Long reviewerGroupId,

@Schema(description = "리뷰 내용 목록")
@Valid
@NotNull(message = "리뷰 내용을 입력해주세요.")
@Schema(description = "리뷰 내용 목록")
List<CreateReviewContentRequest> contents,
List<CreateReviewContentRequest> reviewContents,

@NotNull(message = "키워드를 입력해주세요.")
@Schema(description = "선택된 키워드 ID 목록")
List<Long> selectedKeywordIds
@NotNull(message = "키워드를 입력해주세요.")
List<Long> keywords
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package reviewme.review.exception;

import reviewme.global.exception.NotFoundException;

public class QuestionNotFoundException extends NotFoundException {

public QuestionNotFoundException() {
super("질문이 존재하지 않습니다.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package reviewme.review.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import reviewme.review.domain.Question;
import reviewme.review.exception.QuestionNotFoundException;

@Repository
public interface QuestionRepository extends JpaRepository<Question, Long> {

default Question getQuestionById(long id) {
return findById(id).orElseThrow(QuestionNotFoundException::new);
}
}
27 changes: 26 additions & 1 deletion backend/src/main/java/reviewme/review/service/ReviewService.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package reviewme.review.service;

import java.time.LocalDateTime;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
Expand All @@ -11,13 +12,15 @@
import reviewme.member.domain.ReviewerGroup;
import reviewme.member.repository.MemberRepository;
import reviewme.member.repository.ReviewerGroupRepository;
import reviewme.review.domain.Question;
import reviewme.review.domain.Review;
import reviewme.review.domain.ReviewContent;
import reviewme.review.dto.request.CreateReviewRequest;
import reviewme.review.dto.response.ReviewDetailResponse;
import reviewme.review.dto.response.ReviewDetailReviewContentResponse;
import reviewme.review.dto.response.ReviewDetailReviewerGroupResponse;
import reviewme.review.exception.ReviewUnAuthorizedException;
import reviewme.review.repository.QuestionRepository;
import reviewme.review.repository.ReviewContentRepository;
import reviewme.review.repository.ReviewRepository;

Expand All @@ -29,11 +32,33 @@ public class ReviewService {
private final MemberRepository memberRepository;
private final ReviewerGroupRepository reviewerGroupRepository;
private final ReviewContentRepository reviewContentRepository;
private final QuestionRepository questionRepository;
private final KeywordRepository keywordRepository;

@Transactional
public Long createReview(CreateReviewRequest request) {
return null;
ReviewerGroup reviewerGroup = reviewerGroupRepository.getReviewerGroupById(request.reviewerGroupId());
Member reviewer = memberRepository.getMemberById(request.reviewerId());

List<Keyword> keywordList = request.keywords()
.stream()
.map(keywordRepository::getKeywordById)
.toList();

Review review = new Review(reviewer, reviewerGroup.getReviewee(),
reviewerGroup, keywordList, LocalDateTime.now());
Review savedReview = reviewRepository.save(review);

request.reviewContents()
.forEach(contentsRequest -> {
Question question = questionRepository.getQuestionById(contentsRequest.questionId());
String answer = contentsRequest.answer();

ReviewContent reviewContent = new ReviewContent(savedReview, question, answer);
reviewContentRepository.save(reviewContent);
});

return savedReview.getId();
}

@Transactional(readOnly = true)
Expand Down

This file was deleted.

Loading

0 comments on commit a9b409f

Please sign in to comment.