Skip to content

Commit

Permalink
[BE] 도메인 연관관계 재설정 (#97)
Browse files Browse the repository at this point in the history
* feat: 깃허브 아이디 원시값 포장

Co-authored-by: nayonsoso <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: hyeonjilee <[email protected]>

* feat: 회원 `GithubId` 사용

Co-authored-by: nayonsoso <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: hyeonjilee <[email protected]>

* refactor: 키워드 내 컬럼 수정 (content)

Co-authored-by: nayonsoso <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: hyeonjilee <[email protected]>

* refactor: 일급 컬렉션 이름 변경

Co-authored-by: nayonsoso <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: hyeonjilee <[email protected]>

* feat: 질문 엔티티

Co-authored-by: nayonsoso <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: hyeonjilee <[email protected]>

* refactor: 답변 구조 변경, 길이 검증

Co-authored-by: nayonsoso <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: hyeonjilee <[email protected]>

* refactor: 키워드 연관관계 없이 참조하도록 설정

Co-authored-by: nayonsoso <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: hyeonjilee <[email protected]>

* test: 답변 길이 테스트

Co-authored-by: nayonsoso <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: hyeonjilee <[email protected]>

* feat: 리뷰 생성 시 키워드 받아서 생성

Co-authored-by: nayonsoso <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: hyeonjilee <[email protected]>

* test: 리뷰어와 리뷰이 같은 경우의 예외 테스트

Co-authored-by: nayonsoso <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: hyeonjilee <[email protected]>

* chore: 리뷰-키워드 매핑 테이블 삭제

Co-authored-by: nayonsoso <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: hyeonjilee <[email protected]>

* fix: Fixture 사용해 컴파일 에러 해결

Co-authored-by: nayonsoso <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: hyeonjilee <[email protected]>

* refactor: 일대다 편의 메소드 작성,

Co-authored-by: nayonsoso <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: hyeonjilee <[email protected]>

* feat: 깃허브 아이디 그룹, 리뷰어 연관관계

Co-authored-by: nayonsoso <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: hyeonjilee <[email protected]>

* feat: 리뷰그룹 - 리뷰 일대다 단방향 연관관계 적용

Co-authored-by: nayonsoso <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: hyeonjilee <[email protected]>

* feat: 리뷰그룹 - 리뷰 일대다 양방향 연관관계 적용

Co-authored-by: nayonsoso <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: hyeonjilee <[email protected]>

* feat: 리뷰어 그룹 깃허브 아이디 검증

Co-authored-by: nayonsoso <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: hyeonjilee <[email protected]>

* feat: 셀프리뷰 검증

Co-authored-by: nayonsoso <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: hyeonjilee <[email protected]>

* chore: 사용하지 않는 파일 삭제

Co-authored-by: nayonsoso <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: hyeonjilee <[email protected]>

* feat: 리뷰 추가 검증

Co-authored-by: nayonsoso <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: hyeonjilee <[email protected]>

* fix: 순환 참조 NPE 해결

Co-authored-by: nayonsoso <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: hyeonjilee <[email protected]>

* chore: 사용하지 않는 import 제거

Co-authored-by: nayonsoso <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: hyeonjilee <[email protected]>

* chore: Github ID 패키지 이동

Co-authored-by: nayonsoso <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: hyeonjilee <[email protected]>

* feat: 리뷰 - 리뷰 답변 연관관계 설정

Co-authored-by: nayonsoso <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: hyeonjilee <[email protected]>

* chore: 사용하지 않는 코드 제거

* refactor: 내가 받은 리뷰 상세 보기 구현

---------

Co-authored-by: nayonsoso <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: hyeonjilee <[email protected]>
  • Loading branch information
4 people authored Jul 24, 2024
1 parent aa7589a commit 5d0b953
Show file tree
Hide file tree
Showing 41 changed files with 502 additions and 526 deletions.
16 changes: 0 additions & 16 deletions backend/src/main/java/reviewme/keyword/contoller/KeywordApi.java

This file was deleted.

This file was deleted.

17 changes: 6 additions & 11 deletions backend/src/main/java/reviewme/keyword/domain/Keyword.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,11 @@ public class Keyword {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "detail", nullable = false)
private String detail;
@Column(name = "content", nullable = false)
private String content;

Keyword(Long id, String detail) {
this.id = id;
this.detail = detail;
}

public Keyword(String detail) {
this(null, detail);
public Keyword(String content) {
this.content = content;
}

@Override
Expand All @@ -42,15 +37,15 @@ public boolean equals(Object o) {
return false;
}
if (id == null) {
return Objects.equals(detail, keyword.detail);
return Objects.equals(content, keyword.content);
}
return Objects.equals(id, keyword.id);
}

@Override
public int hashCode() {
if (id == null) {
return Objects.hash(detail);
return Objects.hash(content);
}
return Objects.hash(id);
}
Expand Down
50 changes: 50 additions & 0 deletions backend/src/main/java/reviewme/keyword/domain/Keywords.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package reviewme.keyword.domain;

import jakarta.persistence.CollectionTable;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Embeddable;
import jakarta.persistence.JoinColumn;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import reviewme.keyword.domain.exception.DuplicateKeywordException;
import reviewme.keyword.domain.exception.KeywordLimitExceedException;

@Embeddable
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class Keywords {

private static final int MAX_KEYWORD_COUNT = 5;

@ElementCollection
@CollectionTable(name = "review_keyword", joinColumns = @JoinColumn(name = "review_id"))
private Set<Long> keywordIds;

public Keywords(List<Keyword> selectedKeywords) {
if (selectedKeywords.size() > MAX_KEYWORD_COUNT) {
throw new KeywordLimitExceedException(MAX_KEYWORD_COUNT);
}
if (hasDuplicateKeywords(selectedKeywords)) {
throw new DuplicateKeywordException();
}
this.keywordIds = selectedKeywords.stream()
.map(Keyword::getId)
.collect(Collectors.toSet());
}

private boolean hasDuplicateKeywords(List<Keyword> selectedKeywords) {
long distinctKeywordCount = selectedKeywords.stream()
.distinct()
.count();
return selectedKeywords.size() != distinctKeywordCount;
}

public Set<Long> getKeywordIds() {
return Collections.unmodifiableSet(keywordIds);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class KeywordService {
public KeywordsResponse findAllKeywords() {
List<KeywordResponse> responses = keywordRepository.findAll()
.stream()
.map(keyword -> new KeywordResponse(keyword.getId(), keyword.getDetail()))
.map(keyword -> new KeywordResponse(keyword.getId(), keyword.getContent()))
.toList();
return new KeywordsResponse(responses);
}
Expand Down
20 changes: 20 additions & 0 deletions backend/src/main/java/reviewme/member/domain/GithubId.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package reviewme.member.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Embeddable;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Embeddable
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class GithubId {

@Column(name = "github_id", nullable = false)
private long id;

public GithubId(long id) {
this.id = id;
}
}
Original file line number Diff line number Diff line change
@@ -1,35 +1,31 @@
package reviewme.member.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
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.Getter;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "github_reviewer_group")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class GithubReviewerGroup {
public class GithubIdReviewerGroup {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name = "github_id", nullable = false)
private String githubId;
@Embedded
private GithubId githubId;

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

public GithubReviewerGroup(String githubId, ReviewerGroup reviewerGroup) {
public GithubIdReviewerGroup(GithubId githubId, ReviewerGroup reviewerGroup) {
this.githubId = githubId;
this.reviewerGroup = reviewerGroup;
}
Expand Down
11 changes: 7 additions & 4 deletions backend/src/main/java/reviewme/member/domain/Member.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
package reviewme.member.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AccessLevel;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Table(name = "member")
@EqualsAndHashCode(of = "id")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Getter
public class Member {
Expand All @@ -23,11 +26,11 @@ public class Member {
@Column(name = "name", nullable = false)
private String name;

@Column(name = "github_id", nullable = false)
private String githubId;
@Embedded
private GithubId githubId;

public Member(String name, String githubId) {
public Member(String name, long githubId) {
this.name = name;
this.githubId = githubId;
this.githubId = new GithubId(githubId);
}
}
62 changes: 55 additions & 7 deletions backend/src/main/java/reviewme/member/domain/ReviewerGroup.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
package reviewme.member.domain;

import jakarta.persistence.Column;
import jakarta.persistence.Embedded;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import reviewme.member.domain.exception.DescriptionLengthExceededException;
import reviewme.member.domain.exception.InvalidGroupNameLengthException;
import reviewme.member.domain.exception.SelfReviewException;
import reviewme.review.domain.Review;
import reviewme.review.domain.exception.DeadlineExpiredException;
import reviewme.review.domain.exception.RevieweeMismatchException;
import reviewme.review.exception.GithubReviewerGroupUnAuthorizedException;
import reviewme.review.exception.ReviewAlreadySubmittedException;

@Entity
@Table(name = "reviewer_group")
Expand All @@ -30,37 +40,75 @@ public class ReviewerGroup {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Embedded
private ReviewerGroupGithubIds reviewerGithubIds;

@ManyToOne
@JoinColumn(name = "reviewee_id", nullable = false)
private Member reviewee;

@OneToMany(mappedBy = "reviewerGroup")
private List<Review> reviews;

@Column(name = "group_name", nullable = false)
private String groupName;

@Column(name = "description", nullable = false)
private String description;

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

@Column(name = "thumbnail_url", nullable = false)
private String thumbnailUrl;

public ReviewerGroup(Member reviewee, String groupName, String description, LocalDateTime createdAt) {
public ReviewerGroup(Member reviewee, List<GithubId> reviewerGithubIds,
String groupName, String description, LocalDateTime deadline) {
if (groupName.isBlank() || groupName.length() > MAX_GROUP_NAME_LENGTH) {
throw new InvalidGroupNameLengthException(MAX_GROUP_NAME_LENGTH);
}
if (description.length() > MAX_DESCRIPTION_LENGTH) {
throw new DescriptionLengthExceededException(MAX_DESCRIPTION_LENGTH);
}
if (reviewerGithubIds.contains(reviewee.getGithubId())) {
throw new SelfReviewException();
}
this.reviewee = reviewee;
this.reviewerGithubIds = new ReviewerGroupGithubIds(this, reviewerGithubIds);
this.groupName = groupName;
this.description = description;
this.createdAt = createdAt;
this.deadline = deadline;
this.reviews = new ArrayList<>();
this.thumbnailUrl = "https://github.com/octocat.png";
}

public boolean isDeadlineExceeded(LocalDateTime now) {
return now.isAfter(getDeadline());
return now.isAfter(deadline);
}

public void addReview(Review review) {
Member reviewer = review.getReviewer();
if (isDeadlineExceeded(review.getCreatedAt())) {
throw new DeadlineExpiredException();
}
if (hasSubmittedReviewBy(reviewer)) {
throw new ReviewAlreadySubmittedException();
}
if (reviewerGithubIds.doesNotContain(reviewer)) {
throw new GithubReviewerGroupUnAuthorizedException();
}
if (!review.getReviewee().equals(reviewee)) {
throw new RevieweeMismatchException();
}
reviews.add(review);
}

private boolean hasSubmittedReviewBy(Member reviewer) {
return reviews.stream()
.anyMatch(review -> review.isSubmittedBy(reviewer));
}

public LocalDateTime getDeadline() {
return createdAt.plus(DEADLINE_DURATION);
public void addReviewerGithubId(GithubIdReviewerGroup githubIdReviewerGroup) {
reviewerGithubIds.add(githubIdReviewerGroup);
}
}
Loading

0 comments on commit 5d0b953

Please sign in to comment.