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] 서비스 중복 로직 제거 및 캡슐화 #723

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all 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
@@ -1,7 +1,6 @@
package harustudy.backend.content.service;

import harustudy.backend.auth.dto.AuthMember;
import harustudy.backend.auth.exception.AuthorizationException;
import harustudy.backend.content.domain.Content;
import harustudy.backend.content.dto.ContentResponse;
import harustudy.backend.content.dto.ContentsResponse;
Expand All @@ -12,18 +11,14 @@
import harustudy.backend.member.domain.Member;
import harustudy.backend.member.repository.MemberRepository;
import harustudy.backend.participant.domain.Participant;
import harustudy.backend.participant.domain.Step;
import harustudy.backend.participant.exception.StudyStepException;
import harustudy.backend.participant.exception.ParticipantNotBelongToStudyException;
import harustudy.backend.participant.repository.ParticipantRepository;
import harustudy.backend.study.domain.Study;
import harustudy.backend.study.repository.StudyRepository;
import jakarta.annotation.Nullable;
import java.util.List;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Objects;

@RequiredArgsConstructor
@Transactional
Expand All @@ -36,33 +31,26 @@ public class ContentService {
private final ContentRepository contentRepository;

@Transactional(readOnly = true)
public ContentsResponse findContentsWithFilter(
AuthMember authMember, Long studyId, Long participantId, @Nullable Integer cycle) {
public ContentsResponse findContentsWithFilter(AuthMember authMember, Long studyId,
Long participantId, Integer cycle) {
Participant participant = participantRepository.findByIdIfExists(participantId);
validateParticipantIsCreatedByMember(participant, authMember.id());
validateParticipantBelongsToStudy(participant, studyId);
Study study = studyRepository.findByIdIfExists(studyId);
Member member = memberRepository.findByIdIfExists(authMember.id());

participant.validateIsCreatedByMember(member);
participant.validateIsBelongsTo(study);

return getContentsResponseByCycleFilter(cycle, participant);
}

private ContentsResponse getContentsResponseByCycleFilter(Integer cycle, Participant participant) {
List<Content> contents = participant.getContents();
if (Objects.isNull(cycle)) {
return getContentsResponseWithoutCycleFilter(contents);
}
return getContentsResponseWithCycleFilter(contents, cycle);
}

private void validateParticipantIsCreatedByMember(Participant participant, Long memberId) {
Member member = memberRepository.findByIdIfExists(memberId);
if (participant.isNotCreatedBy(member)) {
throw new AuthorizationException();
}
}

private void validateParticipantBelongsToStudy(Participant participant, Long studyId) {
Study study = studyRepository.findByIdIfExists(studyId);
if (!participant.isParticipantOf(study)) {
throw new AuthorizationException();
}
}

private ContentsResponse getContentsResponseWithoutCycleFilter(List<Content> contents) {
List<ContentResponse> contentResponses = contents.stream()
.map(ContentResponse::from)
Expand All @@ -81,59 +69,35 @@ private ContentsResponse getContentsResponseWithCycleFilter(List<Content> conten
public void writePlan(AuthMember authMember, Long studyId, WritePlanRequest request) {
Study study = studyRepository.findByIdIfExists(studyId);
Participant participant = participantRepository.findByIdIfExists(request.participantId());
Member member = memberRepository.findByIdIfExists(authMember.id());

validateParticipantBelongsToStudy(study, participant);
validateParticipantIsCreatedByMember(authMember.id(), participant);
validateStudyIsPlanning(study);
participant.validateIsBelongsTo(study);
participant.validateIsCreatedByMember(member);
study.validateIsPlanning();

Content recentContent = findContentWithSameCycle(study, participant);
recentContent.changePlan(request.plan());
}

private void validateParticipantBelongsToStudy(Study study, Participant participant) {
if (!participant.isParticipantOf(study)) {
throw new ParticipantNotBelongToStudyException();
}
}

private void validateStudyIsPlanning(Study study) {
if (!study.isStep(Step.PLANNING)) {
throw new StudyStepException();
}
}

private Content findContentWithSameCycle(Study study, Participant participant) {
List<Content> contents = contentRepository.findByParticipant(
participant);

return contents.stream()
.filter(content -> content.hasSameCycleWith(study))
.findAny()
.orElseThrow(ContentNotFoundException::new);
}

public void writeRetrospect(AuthMember authMember, Long studyId, WriteRetrospectRequest request) {
Study study = studyRepository.findByIdIfExists(studyId);
Participant participant = participantRepository.findByIdIfExists(request.participantId());
Member member = memberRepository.findByIdIfExists(authMember.id());

validateParticipantBelongsToStudy(study, participant);
validateParticipantIsCreatedByMember(authMember.id(), participant);
validateStudyIsRetrospect(study);
participant.validateIsBelongsTo(study);
participant.validateIsCreatedByMember(member);
study.validateIsRetrospect();

Content recentContent = findContentWithSameCycle(study, participant);
recentContent.changeRetrospect(request.retrospect());
}

private void validateParticipantIsCreatedByMember(Long memberId, Participant participant) {
Member member = memberRepository.findByIdIfExists(memberId);
if (participant.isNotCreatedBy(member)) {
throw new AuthorizationException();
}
}
private Content findContentWithSameCycle(Study study, Participant participant) {
List<Content> contents = contentRepository.findByParticipant(participant);

private void validateStudyIsRetrospect(Study study) {
if (!study.isStep(Step.RETROSPECT)) {
throw new StudyStepException();
}
return contents.stream()
.filter(content -> content.hasSameCycleWith(study))
.findAny()
.orElseThrow(ContentNotFoundException::new);
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package harustudy.backend.participant.domain;

import harustudy.backend.auth.exception.AuthorizationException;
import harustudy.backend.common.BaseTimeEntity;
import harustudy.backend.content.domain.Content;
import harustudy.backend.member.domain.Member;
import harustudy.backend.participant.exception.NicknameLengthException;
import harustudy.backend.participant.exception.ParticipantIsNotHostException;
import harustudy.backend.participant.exception.ParticipantNotBelongToStudyException;
import harustudy.backend.study.domain.Study;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
Expand Down Expand Up @@ -95,4 +97,16 @@ public void validateIsHost() {
throw new ParticipantIsNotHostException();
}
}

public void validateIsBelongsTo(Study study) {
if (!this.study.getId().equals(study.getId())) {
throw new ParticipantNotBelongToStudyException();
}
}

public void validateIsCreatedByMember(Member member) {
if (isNotCreatedBy(member)) {
throw new AuthorizationException();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,13 @@
import harustudy.backend.participant.domain.Participant;
import harustudy.backend.participant.exception.ParticipantNotFoundException;
import harustudy.backend.study.domain.Study;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface ParticipantRepository extends JpaRepository<Participant, Long> {

Optional<Participant> findByStudyAndMember(Study study,
Member member);
Optional<Participant> findByStudyAndMember(Study study, Member member);

List<Participant> findByStudy(Study study);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,16 @@
import harustudy.backend.member.domain.Member;
import harustudy.backend.member.repository.MemberRepository;
import harustudy.backend.participant.domain.Participant;
import harustudy.backend.participant.domain.Step;
import harustudy.backend.participant.dto.ParticipateStudyRequest;
import harustudy.backend.participant.dto.ParticipantResponse;
import harustudy.backend.participant.dto.ParticipantsResponse;
import harustudy.backend.participant.exception.ParticipantNotBelongToStudyException;
import harustudy.backend.participant.dto.ParticipateStudyRequest;
import harustudy.backend.participant.exception.ParticipantNotFoundException;
import harustudy.backend.participant.repository.ParticipantRepository;
import harustudy.backend.study.domain.Study;
import harustudy.backend.study.exception.StudyAlreadyStartedException;
import harustudy.backend.study.repository.StudyRepository;
import jakarta.annotation.Nullable;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

Expand All @@ -33,32 +28,30 @@ public class ParticipantService {
private final StudyRepository studyRepository;

@Transactional(readOnly = true)
public ParticipantResponse findParticipant(
AuthMember authMember, Long studyId, Long participantId
) {
public ParticipantResponse findParticipant(AuthMember authMember, Long studyId, Long participantId) {
Study study = studyRepository.findByIdIfExists(studyId);
Participant participant = participantRepository.findByIdIfExists(participantId);
validateParticipantIsRelatedWith(participant, authMember, study);
Member member = memberRepository.findByIdIfExists(authMember.id());

participant.validateIsCreatedByMember(member);
participant.validateIsBelongsTo(study);

return ParticipantResponse.from(participant);
}

// TODO: 임시용이므로 이후에 제거
public ParticipantsResponse tempFindParticipantWithFilter(
AuthMember authMember, Long studyId, Long memberId
) {
public ParticipantsResponse tempFindParticipantWithFilter(AuthMember authMember, Long studyId, Long memberId) {
Study study = studyRepository.findByIdIfExists(studyId);
if (Objects.isNull(memberId)) {
validateEverParticipated(authMember, study);
return getParticipantsResponseWithoutMemberFilter(study);
}
Member member = memberRepository.findByIdIfExists(memberId);
validateIsSameMemberId(authMember, memberId);
Member member = memberRepository.findByIdIfExists(memberId);
return tempGetParticipantsResponseWithMemberFilter(study, member);
}

// TODO: 임시용이므로 이후에 제거
private ParticipantsResponse tempGetParticipantsResponseWithMemberFilter(
Study study, Member member) {
private ParticipantsResponse tempGetParticipantsResponseWithMemberFilter(Study study, Member member) {
return participantRepository.findByStudyAndMember(study, member)
.map(ParticipantResponse::from)
.map(response -> ParticipantsResponse.from(List.of(response)))
Expand All @@ -67,16 +60,14 @@ private ParticipantsResponse tempGetParticipantsResponseWithMemberFilter(

// TODO: 동적쿼리로 변경(memberId 유무에 따른 분기처리)
@Transactional(readOnly = true)
public ParticipantsResponse findParticipantsWithFilter(
AuthMember authMember, Long studyId, @Nullable Long memberId
) {
public ParticipantsResponse findParticipantsWithFilter(AuthMember authMember, Long studyId, Long memberId) {
Study study = studyRepository.findByIdIfExists(studyId);
if (Objects.isNull(memberId)) {
validateEverParticipated(authMember, study);
return getParticipantsResponseWithoutMemberFilter(study);
}
Member member = memberRepository.findByIdIfExists(memberId);
validateIsSameMemberId(authMember, memberId);
Member member = memberRepository.findByIdIfExists(memberId);
return getParticipantsResponseWithMemberFilter(study, member);
}

Expand All @@ -86,36 +77,32 @@ private void validateEverParticipated(AuthMember authMember, Study study) {
.orElseThrow(AuthorizationException::new);
}

private ParticipantsResponse getParticipantsResponseWithoutMemberFilter(
Study study
) {
List<ParticipantResponse> responses =
participantRepository.findByStudy(study)
.stream()
.map(ParticipantResponse::from)
.toList();
private ParticipantsResponse getParticipantsResponseWithoutMemberFilter(Study study) {
List<ParticipantResponse> responses = participantRepository.findByStudy(study)
.stream()
.map(ParticipantResponse::from)
.toList();
return ParticipantsResponse.from(responses);
}

private ParticipantsResponse getParticipantsResponseWithMemberFilter(
Study study, Member member
) {
ParticipantResponse response =
participantRepository.findByStudyAndMember(study, member)
.map(ParticipantResponse::from)
.orElseThrow(ParticipantNotFoundException::new);
private ParticipantsResponse getParticipantsResponseWithMemberFilter(Study study, Member member) {
ParticipantResponse response = participantRepository.findByStudyAndMember(study, member)
.map(ParticipantResponse::from)
.orElseThrow(ParticipantNotFoundException::new);
return ParticipantsResponse.from(List.of(response));
}

public Long participateStudy(AuthMember authMember, Long studyId, ParticipateStudyRequest request) {
Member member = memberRepository.findByIdIfExists(request.memberId());
validateIsSameMemberId(authMember, request.memberId());
Member member = memberRepository.findByIdIfExists(request.memberId());
Study study = studyRepository.findByIdIfExists(studyId);
validateIsWaiting(study);

study.validateIsWaiting();
Participant participant = Participant.createParticipantOfStudy(study, member, request.nickname());
participant.generateContents(study.getTotalCycle());
Participant saved = participantRepository.save(participant);
return saved.getId();
participantRepository.save(participant);

return participant.getId();
}

private void validateIsSameMemberId(AuthMember authMember, Long memberId) {
Expand All @@ -124,37 +111,15 @@ private void validateIsSameMemberId(AuthMember authMember, Long memberId) {
}
}

private void validateIsWaiting(Study study) {
if (!study.isStep(Step.WAITING)) {
throw new StudyAlreadyStartedException();
}
}

private void validateParticipantIsRelatedWith(
Participant participant, AuthMember authMember, Study study
) {
validateMemberOwns(participant, authMember);
validateParticipantIsIncludedIn(study, participant);
}

private void validateMemberOwns(Participant participant, AuthMember authMember) {
Member member = memberRepository.findByIdIfExists(authMember.id());
if (participant.isNotCreatedBy(member)) {
throw new AuthorizationException();
}
}

private void validateParticipantIsIncludedIn(Study study, Participant participant) {
if (participant.isNotIncludedIn(study)) {
throw new ParticipantNotBelongToStudyException();
}
}

public void deleteParticipant(AuthMember authMember, Long studyId, Long participantId) {
Study study = studyRepository.findByIdIfExists(studyId);
validateEverParticipated(authMember, study);
Member member = memberRepository.findByIdIfExists(authMember.id());
Participant participant = participantRepository.findByIdIfExists(participantId);
validateParticipantIsRelatedWith(participant, authMember, study);

validateEverParticipated(authMember, study);
participant.validateIsCreatedByMember(member);
participant.validateIsBelongsTo(study);

participantRepository.delete(participant);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class PollingController {
@Operation(summary = "진행 페이지 폴링")
@GetMapping("/api/v2/progress")
public ResponseEntity<ProgressResponse> progressPolling(@RequestParam Long studyId) {
ProgressResponse progressResponse = pollingService.pollProgress(studyId);
ProgressResponse progressResponse = pollingService.pollInProgress(studyId);
return ResponseEntity.ok(progressResponse);
}

Expand Down
Loading