-
Notifications
You must be signed in to change notification settings - Fork 5
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] issue122: 스터디 참여 기능 #132
Changes from 16 commits
8de6562
40a88b4
593a4d3
b0dc328
0f79069
bbc410a
9f0a622
3df6cba
5b6a5c5
40a7434
47b49dd
63a4378
9291dd0
0634073
72274e1
b1ec72f
90e9ec5
e482a95
f7f8bd3
5822471
78aafb4
574b6ad
6d34aee
8786486
d9c0b25
eed9d4e
4875818
7b78036
4dce039
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,40 @@ | ||
package com.woowacourse.moamoa.study.controller; | ||
|
||
import com.woowacourse.moamoa.auth.config.AuthenticationPrincipal; | ||
import com.woowacourse.moamoa.study.service.request.CreateStudyRequest; | ||
import com.woowacourse.moamoa.study.domain.Study; | ||
import com.woowacourse.moamoa.study.service.CreateStudyService; | ||
import com.woowacourse.moamoa.study.service.StudyService; | ||
import com.woowacourse.moamoa.study.service.request.CreatingStudyRequest; | ||
import java.net.URI; | ||
import javax.validation.Valid; | ||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RestController | ||
@RequiredArgsConstructor | ||
@Getter | ||
@RequestMapping("/api/studies") | ||
public class StudyController { | ||
|
||
private final CreateStudyService createStudyService; | ||
private final StudyService studyService; | ||
|
||
@PostMapping("/api/studies") | ||
@PostMapping | ||
public ResponseEntity<Void> createStudy( | ||
@AuthenticationPrincipal final Long githubId, | ||
@Valid @RequestBody(required = false) final CreateStudyRequest createStudyRequest | ||
@Valid @RequestBody(required = false) final CreatingStudyRequest creatingStudyRequest | ||
) { | ||
final Study study = createStudyService.createStudy(githubId, createStudyRequest); | ||
final Study study = studyService.createStudy(githubId, creatingStudyRequest); | ||
return ResponseEntity.created(URI.create("/api/studies/" + study.getId())).build(); | ||
} | ||
|
||
@PostMapping("/{study-id}") | ||
public ResponseEntity<Void> participateStudy(@AuthenticationPrincipal final Long githubId, | ||
@PathVariable("study-id") final Long studyId | ||
) { | ||
studyService.participantStudy(githubId, studyId); | ||
return ResponseEntity.ok().build(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,19 @@ | ||
package com.woowacourse.moamoa.study.domain; | ||
|
||
import static lombok.AccessLevel.PROTECTED; | ||
|
||
import com.woowacourse.moamoa.study.service.exception.InvalidParticipationStudyException; | ||
import java.util.Objects; | ||
import javax.persistence.Column; | ||
import javax.persistence.Embeddable; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Embeddable | ||
@NoArgsConstructor(access = PROTECTED) | ||
public class Details { | ||
|
||
private static final String CLOSE = "CLOSE"; | ||
|
||
@Column(nullable = false) | ||
private String title; | ||
|
||
|
@@ -22,9 +29,6 @@ public class Details { | |
@Column(nullable = false) | ||
private String description; | ||
|
||
protected Details() { | ||
} | ||
|
||
public Details(final String title, final String excerpt, final String thumbnail, final String status, | ||
final String description) { | ||
this.title = title; | ||
|
@@ -34,6 +38,12 @@ public Details(final String title, final String excerpt, final String thumbnail, | |
this.description = description; | ||
} | ||
|
||
protected void checkStudyStatus() { | ||
if (status.equals(CLOSE)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. status를 enum으로 두면 CLOSE같은 상수를 안써도 될 것 같네용 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 넵!! 린론 코드와 병합하는 과정에서 열거형 상수를 사용하게 되면 수정하도록 하겠습니다! |
||
throw new InvalidParticipationStudyException(); | ||
} | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. checkStudyStatus보다 좀 더 의미 있는 이름은 없을까요??? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 저도 isCloseStatus() 등등..이 부분에서 고민이 많았는데요..🤔 |
||
@Override | ||
public boolean equals(final Object o) { | ||
if (this == o) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,24 @@ | ||
package com.woowacourse.moamoa.study.domain; | ||
|
||
import static lombok.AccessLevel.PROTECTED; | ||
|
||
import com.woowacourse.moamoa.study.service.exception.InvalidParticipationStudyException; | ||
import java.util.ArrayList; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Objects; | ||
import java.util.Set; | ||
import javax.persistence.CollectionTable; | ||
import javax.persistence.Column; | ||
import javax.persistence.ElementCollection; | ||
import javax.persistence.Embeddable; | ||
import javax.persistence.FetchType; | ||
import javax.persistence.JoinColumn; | ||
import lombok.NoArgsConstructor; | ||
import lombok.ToString; | ||
|
||
@Embeddable | ||
@ToString | ||
@NoArgsConstructor(access = PROTECTED) | ||
public class Participants { | ||
|
||
@Column(name = "current_member_count") | ||
|
@@ -26,13 +32,10 @@ public class Participants { | |
|
||
@ElementCollection | ||
@CollectionTable(name = "study_member", joinColumns = @JoinColumn(name = "study_id")) | ||
private List<Participant> participants = new ArrayList<>(); | ||
|
||
protected Participants() { | ||
} | ||
private Set<Participant> participants = new HashSet<>(); | ||
|
||
public Participants(final Integer size, final Integer max, | ||
final List<Participant> participants, Long ownerId) { | ||
final Set<Participant> participants, Long ownerId) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 중복된 값 X 👍 명확해서 좋아요! |
||
this.size = size; | ||
this.max = max; | ||
this.participants = participants; | ||
|
@@ -43,8 +46,32 @@ public List<Participant> getParticipants() { | |
return new ArrayList<>(participants); | ||
} | ||
|
||
public static Participants createByMaxSizeAndOwnerId(final Integer maxSize, Long id) { | ||
return new Participants(1, maxSize, new ArrayList<>(), id); | ||
public static Participants createByMaxSizeAndOwnerId(final Integer maxSize, Long ownerId) { | ||
return new Participants(1, maxSize, new HashSet<>(List.of(new Participant(ownerId))), ownerId); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 참여자에 방장은 넣지 않기로 하지 않았나요??? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 헉...수정하겠습ㄴ디ㅏ! |
||
|
||
protected void participate(final Participant participant) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. default 접근 제어자가 좋을 것 같습니다. |
||
participants.add(participant); | ||
this.size = this.size + 1; | ||
} | ||
|
||
public int getCurrentMemberSize() { | ||
return size; | ||
} | ||
|
||
protected void checkParticipating(Long memberId) { | ||
if (isInvalidMemberSize() || isAlreadyParticipation(memberId)) { | ||
throw new InvalidParticipationStudyException(); | ||
} | ||
} | ||
|
||
private boolean isInvalidMemberSize() { | ||
return max != null && max <= size; | ||
} | ||
|
||
private boolean isAlreadyParticipation(final Long memberId) { | ||
final Participant participant = new Participant(memberId); | ||
return Objects.equals(memberId, ownerId) || participants.contains(participant); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이부분을 participate 메서드 안에 넣어서 캡슐화하면 더 좋을 것 같아요... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 오 좋습니다!! 외부에 드러낼 필요가 없네요! 수정하였습니다! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 조건을 메서드로 분리하면 owner는 참여자에 포함하지 않기로 한 도메인 규칙이 잘 드러날 것 같아요! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 그린론이 말해준 내용이 아래와 같을까요?? private boolean isAlreadyParticipation(final Long memberId) {
final Participant participant = new Participant(memberId);
return isOwner(memberId) || isParticipant(participant);
}
private boolean isOwner(final Long memberId) {
return Objects.equals(memberId, ownerId);
}
private boolean isParticipant(final Participant participant) {
return participants.contains(participant);
} |
||
} | ||
|
||
@Override | ||
|
@@ -61,7 +88,7 @@ public boolean equals(final Object o) { | |
} | ||
|
||
@Override | ||
public int hashCode() { | ||
public int hashCode() { | ||
return Objects.hash(size, max, ownerId, participants); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,16 @@ | ||
package com.woowacourse.moamoa.study.domain; | ||
|
||
import com.woowacourse.moamoa.study.domain.exception.InvalidPeriodException; | ||
import com.woowacourse.moamoa.study.service.exception.InvalidParticipationStudyException; | ||
import java.time.LocalDate; | ||
import java.time.LocalDateTime; | ||
import java.util.Objects; | ||
import javax.persistence.Column; | ||
import javax.persistence.Embeddable; | ||
import lombok.Getter; | ||
|
||
@Embeddable | ||
@Getter | ||
public class Period { | ||
|
||
private LocalDate enrollmentEndDate; | ||
|
@@ -21,16 +24,21 @@ public Period() { | |
} | ||
|
||
public Period(final LocalDate enrollmentEndDate, final LocalDate startDate, final LocalDate endDate) { | ||
if ((endDate != null && startDate.isAfter(endDate)) || (enrollmentEndDate != null && endDate != null && enrollmentEndDate.isAfter(endDate))) { | ||
throw new InvalidPeriodException(); | ||
} | ||
validatePeriod(enrollmentEndDate, startDate, endDate); | ||
this.enrollmentEndDate = enrollmentEndDate; | ||
this.startDate = startDate; | ||
this.endDate = endDate; | ||
} | ||
|
||
public boolean isBefore(final LocalDateTime createAt) { | ||
return startDate.isBefore(createAt.toLocalDate()) || (enrollmentEndDate != null && enrollmentEndDate.isBefore(createAt.toLocalDate())); | ||
return startDate.isBefore(createAt.toLocalDate()) || (enrollmentEndDate != null && enrollmentEndDate.isBefore( | ||
createAt.toLocalDate())); | ||
} | ||
|
||
protected void checkParticipatingPeriod() { | ||
if (enrollmentEndDate != null && enrollmentEndDate.isBefore(LocalDate.now())) { | ||
throw new InvalidParticipationStudyException(); | ||
} | ||
} | ||
|
||
@Override | ||
|
@@ -50,4 +58,18 @@ public boolean equals(final Object o) { | |
public int hashCode() { | ||
return Objects.hash(enrollmentEndDate, startDate, endDate); | ||
} | ||
|
||
private void validatePeriod(final LocalDate enrollmentEndDate, final LocalDate startDate, final LocalDate endDate) { | ||
if (isImproperStudyDate(startDate, endDate) || isImproperEnrollmentEndDate(enrollmentEndDate, endDate)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 굿굿 |
||
throw new InvalidPeriodException(); | ||
} | ||
} | ||
|
||
private boolean isImproperStudyDate(final LocalDate startDate, final LocalDate endDate) { | ||
return endDate != null && startDate.isAfter(endDate); | ||
} | ||
|
||
private boolean isImproperEnrollmentEndDate(final LocalDate enrollmentEndDate, final LocalDate endDate) { | ||
return enrollmentEndDate != null && endDate != null && enrollmentEndDate.isAfter(endDate); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ | |
import static javax.persistence.GenerationType.IDENTITY; | ||
import static lombok.AccessLevel.PROTECTED; | ||
|
||
import com.woowacourse.moamoa.member.domain.Member; | ||
import com.woowacourse.moamoa.study.domain.exception.InvalidPeriodException; | ||
import java.time.LocalDateTime; | ||
import javax.persistence.Column; | ||
|
@@ -56,6 +57,19 @@ public Study(final Long id, final Details details, final Participants participan | |
validatePeriod(period); | ||
} | ||
|
||
public void participate(final Member member) { | ||
checkStudyParticipating(member.getId()); | ||
|
||
final Participant participant = new Participant(member.getId()); | ||
participants.participate(participant); | ||
} | ||
|
||
private void checkStudyParticipating(Long memberId) { | ||
details.checkStudyStatus(); | ||
period.checkParticipatingPeriod(); | ||
participants.checkParticipating(memberId); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 각각의 Embeddable 객체에서 예외를 던지는게 아니라 상태만 확인하고 Study에서 예외를 던지는건 어떨까요?? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 수정해보았습니다!! 확인 부탁드려요~_~ |
||
} | ||
|
||
private void validatePeriod(final Period period) { | ||
if (period.isBefore(createdAt)) { | ||
throw new InvalidPeriodException(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
participantStudy
->participateStudy
의견 : join, regist