Skip to content
Merged
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
113 changes: 13 additions & 100 deletions src/main/java/com/retrip/crew/application/in/CrewService.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
import com.retrip.crew.application.in.request.crew.CrewCreateRequest;
import com.retrip.crew.application.in.request.crew.CrewOrder;
import com.retrip.crew.application.in.request.crew.CrewUpdateRequest;
import com.retrip.crew.application.in.request.demand.CreateDemandRequest;
import com.retrip.crew.application.in.request.demand.DemandOrder;
import com.retrip.crew.application.in.request.crew.CrewWithdrawalRequest;
import com.retrip.crew.application.in.response.IntroductionCreateResponse;
import com.retrip.crew.application.in.response.IntroductionDetailResponse;
import com.retrip.crew.application.in.response.IntroductionListResponse;
Expand All @@ -16,56 +15,37 @@
import com.retrip.crew.application.in.response.crew.CrewDetailResponse;
import com.retrip.crew.application.in.response.crew.CrewListResponse;
import com.retrip.crew.application.in.response.crew.CrewUpdateResponse;
import com.retrip.crew.application.in.response.demand.ApproveDemandResponse;
import com.retrip.crew.application.in.response.demand.ChangeRecruitmentStatusResponse;
import com.retrip.crew.application.in.response.demand.CreateDemandResponse;
import com.retrip.crew.application.in.response.demand.CrewsOfDemandResponse;
import com.retrip.crew.application.in.response.demand.DemandsResponse;
import com.retrip.crew.application.in.response.demand.RejectDemandResponse;
import com.retrip.crew.application.in.usecase.GetCrewUseCase;
import com.retrip.crew.application.in.usecase.ManageCrewUseCase;
import com.retrip.crew.application.in.usecase.ManageDemandUseCase;
import com.retrip.crew.application.in.usecase.ManageIntroductionUseCase;
import com.retrip.crew.application.in.usecase.UpdateRecruitmentUseCase;
import com.retrip.crew.application.out.repository.CrewDemandRepository;
import com.retrip.crew.application.out.repository.CrewMemberRepository;
import com.retrip.crew.application.out.repository.CrewQueryRepository;
import com.retrip.crew.application.out.repository.CrewRepository;
import com.retrip.crew.application.out.repository.IntroductionQueryRepository;
import com.retrip.crew.application.out.repository.IntroductionRepository;
import com.retrip.crew.application.out.repository.*;
import com.retrip.crew.domain.entity.Crew;
import com.retrip.crew.domain.entity.Demand;
import com.retrip.crew.domain.entity.CrewMembers;
import com.retrip.crew.domain.entity.Introduction;
import com.retrip.crew.domain.entity.Recruitment;
import com.retrip.crew.domain.exception.CrewNotFoundException;
import com.retrip.crew.domain.exception.IntroductionNotFoundException;
import com.retrip.crew.domain.exception.NotCrewLeaderException;
import com.retrip.crew.domain.exception.common.BusinessException;
import com.retrip.crew.domain.exception.common.EntityNotFoundException;
import com.retrip.crew.domain.vo.CrewDescription;
import com.retrip.crew.domain.vo.CrewTitle;
import com.retrip.crew.domain.vo.DemandStatus;
import com.retrip.crew.domain.vo.IntroductionContent;
import com.retrip.crew.domain.vo.IntroductionTitle;
import com.retrip.crew.infra.adapter.in.presentation.rest.common.ScrollPageResponse;
import com.retrip.crew.infra.util.PaginationUtils;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.UUID;

@Service
@Transactional
@RequiredArgsConstructor
public class CrewService implements ManageCrewUseCase, UpdateRecruitmentUseCase, ManageDemandUseCase, GetCrewUseCase, ManageIntroductionUseCase{

public class CrewService implements ManageCrewUseCase, GetCrewUseCase, ManageIntroductionUseCase{
private final CrewRepository crewRepository;
private final CrewMemberRepository crewMemberRepository;
private final CrewQueryRepository crewQueryRepository;
private final CrewDemandRepository demandRepository;
private final IntroductionRepository introductionRepository;
private final IntroductionQueryRepository introductionQueryRepository;

Expand All @@ -87,80 +67,6 @@ public CrewUpdateResponse updateCrew(UUID crewId, CrewUpdateRequest request) {
return CrewUpdateResponse.of(crew);
}

@Override
public ChangeRecruitmentStatusResponse startRecruitment(UUID crewId) {
Crew crew = findCrewById(crewId);
crew.startRecruitment();
return ChangeRecruitmentStatusResponse.of(crew);
}

@Override
public ChangeRecruitmentStatusResponse stopRecruitment(UUID crewId) {
Crew crew = findCrewById(crewId);
crew.stopRecruitment();
return ChangeRecruitmentStatusResponse.of(crew);
}

@Override
public CreateDemandResponse createDemand(UUID crewId, CreateDemandRequest request) {
Crew crew = findCrewById(crewId);
Demand demand = crew.demand(request.memberId());
return CreateDemandResponse.of(crew.getId(), demand);
}

@Override
public Page<DemandsResponse> getDemands(
UUID crewId, UUID memberId, String status, Pageable pageable, DemandOrder order, String sort) {
Crew crew = findCrewById(crewId);
throwIfNotLeader(crew, memberId, new NotCrewLeaderException());
Page<Demand> demands = demandRepository.findByCrewIdAndStatus(
crewId, DemandStatus.valueOf(status), PaginationUtils.createPageRequest(pageable, order.getField(), sort));
return demands.map(d -> DemandsResponse.of(crewId, d));
}

@Override
public Page<CrewsOfDemandResponse> getCrewsOfDemand(
UUID crewId, UUID demandId, UUID memberId, Pageable pageable, CrewOrder order, String sort) {
Crew crew = findCrewById(crewId);
throwIfNotLeader(crew, memberId, new NotCrewLeaderException());
Demand demand = findDemandByIdAndCrewId(demandId, crewId);
return crewQueryRepository.findAllContainsMember(pageable, demand.getMemberId());
}

private static void throwIfNotLeader(Crew crew, UUID memberId, BusinessException exception) {
if (!crew.getCrewMembers().isLeader(memberId)) {
throw exception;
}
}

@Override
public void cancelDemand(UUID crewId, UUID demandId, UUID memberId) {
Demand demand = findDemandByIdAndCrewId(demandId, crewId);
Crew crew = demand.getCrew();
crew.cancelDemand(demand);
}

@Override
public RejectDemandResponse rejectDemand(UUID crewId, UUID demandId, UUID memberId) {
Demand demand = findDemandByIdAndCrewId(demandId, crewId);
Crew crew = demand.getCrew();
crew.rejectDemand(demand);
return RejectDemandResponse.of(demand);
}

@Override
public ApproveDemandResponse approveDemand(UUID crewId, UUID demandId, UUID memberId) {
Demand demand = findDemandByIdAndCrewId(demandId, crewId);
Crew crew = demand.getCrew();
crew.approveDemand(demand);
return ApproveDemandResponse.of(demand);
}

private Demand findDemandByIdAndCrewId(UUID demandId, UUID crewId) {
return demandRepository.findCrewByIdAndCrewId(demandId, crewId)
.orElseThrow(() -> new EntityNotFoundException("참여 요청 엔티티를 찾을 수 없습니다."));
}

@Override
@Transactional(readOnly = true)
public ScrollPageResponse<CrewListResponse> getCrews(Pageable pageable, String keyword, CrewOrder order, String sort) {
Expand Down Expand Up @@ -232,4 +138,11 @@ public Introduction findIntroductionByIdAndCrewId(UUID introductionId, UUID crew
return introductionRepository.findByIdAndCrewId(introductionId, crewId)
.orElseThrow(IntroductionNotFoundException::new);
}

@Override
public void withdrawCrew(UUID crewId, CrewWithdrawalRequest request) {
Crew crew = findCrewById(crewId);
CrewMembers crewMembers = crew.getCrewMembers();
crewMembers.withdraw(request.memberId(), request.participatingCrewTrips());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

withDraw면 탈퇴하다 뜻인가요??

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네 맞습니다

}
}
114 changes: 114 additions & 0 deletions src/main/java/com/retrip/crew/application/in/DemandService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package com.retrip.crew.application.in;

import com.retrip.crew.application.in.request.crew.CrewOrder;
import com.retrip.crew.application.in.request.demand.CreateDemandRequest;
import com.retrip.crew.application.in.request.demand.DemandOrder;
import com.retrip.crew.application.in.response.demand.*;
import com.retrip.crew.application.in.usecase.ManageDemandUseCase;
import com.retrip.crew.application.in.usecase.UpdateRecruitmentUseCase;
import com.retrip.crew.application.out.repository.CrewDemandRepository;
import com.retrip.crew.application.out.repository.CrewQueryRepository;
import com.retrip.crew.application.out.repository.CrewRepository;
import com.retrip.crew.domain.entity.Crew;
import com.retrip.crew.domain.entity.Demand;
import com.retrip.crew.domain.exception.CrewNotFoundException;
import com.retrip.crew.domain.exception.NotCrewLeaderException;
import com.retrip.crew.domain.exception.common.BusinessException;
import com.retrip.crew.domain.exception.common.EntityNotFoundException;
import com.retrip.crew.domain.vo.DemandStatus;
import com.retrip.crew.infra.util.PaginationUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.UUID;

@Service
@Transactional
@RequiredArgsConstructor
public class DemandService implements UpdateRecruitmentUseCase, ManageDemandUseCase {
private final CrewRepository crewRepository;
private final CrewDemandRepository demandRepository;
private final CrewQueryRepository crewQueryRepository;

@Override
public ChangeRecruitmentStatusResponse startRecruitment(UUID crewId) {
Crew crew = findById(crewId);
crew.startRecruitment();
return ChangeRecruitmentStatusResponse.of(crew);
}

@Override
public ChangeRecruitmentStatusResponse stopRecruitment(UUID crewId) {
Crew crew = findById(crewId);
crew.stopRecruitment();
return ChangeRecruitmentStatusResponse.of(crew);
}

@Override
public CreateDemandResponse createDemand(UUID crewId, CreateDemandRequest request) {
Crew crew = findById(crewId);
Demand demand = crew.demand(request.memberId());
return CreateDemandResponse.of(crew.getId(), demand);
}

@Override
public Page<DemandsResponse> getDemands(
UUID crewId, UUID memberId, String status, Pageable pageable, DemandOrder order, String sort) {
Crew crew = findById(crewId);
throwIfNotLeader(crew, memberId, new NotCrewLeaderException());
Page<Demand> demands = demandRepository.findByCrewIdAndStatus(
crewId, DemandStatus.valueOf(status), PaginationUtils.createPageRequest(pageable, order.getField(), sort));
return demands.map(d -> DemandsResponse.of(crewId, d));
}

@Override
public Page<CrewsOfDemandResponse> getCrewsOfDemand(
UUID crewId, UUID demandId, UUID memberId, Pageable pageable, CrewOrder order, String sort) {
Crew crew = findById(crewId);
throwIfNotLeader(crew, memberId, new NotCrewLeaderException());
Demand demand = findDemandByIdAndCrewId(demandId, crewId);
return crewQueryRepository.findAllContainsMember(pageable, demand.getMemberId());
}

private static void throwIfNotLeader(Crew crew, UUID memberId, BusinessException exception) {
if (!crew.getCrewMembers().isLeader(memberId)) {
throw exception;
}
}

@Override
public void cancelDemand(UUID crewId, UUID demandId, UUID memberId) {
Demand demand = findDemandByIdAndCrewId(demandId, crewId);
Crew crew = demand.getCrew();
crew.cancelDemand(demand);
}

@Override
public RejectDemandResponse rejectDemand(UUID crewId, UUID demandId, UUID memberId) {
Demand demand = findDemandByIdAndCrewId(demandId, crewId);
Crew crew = demand.getCrew();
crew.rejectDemand(demand);
return RejectDemandResponse.of(demand);
}

@Override
public ApproveDemandResponse approveDemand(UUID crewId, UUID demandId, UUID memberId) {
Demand demand = findDemandByIdAndCrewId(demandId, crewId);
Crew crew = demand.getCrew();
crew.approveDemand(demand);
return ApproveDemandResponse.of(demand);
}

private Demand findDemandByIdAndCrewId(UUID demandId, UUID crewId) {
return demandRepository.findCrewByIdAndCrewId(demandId, crewId)
.orElseThrow(() -> new EntityNotFoundException("참여 요청 엔티티를 찾을 수 없습니다."));
}

private Crew findById(UUID crewId){
return crewRepository.findById(crewId)
.orElseThrow(CrewNotFoundException::new);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.retrip.crew.application.in.request.crew;

import com.retrip.crew.domain.CrewTrip;
import io.swagger.v3.oas.annotations.media.Schema;

import java.util.List;
import java.util.UUID;

@Schema(description = "크루 탈퇴 Request")
public record CrewWithdrawalRequest(
@Schema(description = "크루원 ID")
UUID memberId,

@Schema(description = "참여 중인 크루 여행 목록")
List<CrewTrip> participatingCrewTrips
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.retrip.crew.application.in.request.crew.CrewCreateRequest;
import com.retrip.crew.application.in.request.crew.CrewUpdateRequest;
import com.retrip.crew.application.in.request.crew.CrewWithdrawalRequest;
import com.retrip.crew.application.in.response.crew.CrewCreateResponse;
import com.retrip.crew.application.in.response.crew.CrewUpdateResponse;

Expand All @@ -12,4 +13,5 @@ public interface ManageCrewUseCase {

CrewUpdateResponse updateCrew(UUID crewId, CrewUpdateRequest request);

void withdrawCrew(UUID crewId, CrewWithdrawalRequest request);
}
29 changes: 29 additions & 0 deletions src/main/java/com/retrip/crew/domain/CrewTrip.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.retrip.crew.domain;

import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.UUID;

import static com.retrip.crew.domain.CrewTrip.CrewTripType.EXCLUSION;

public record CrewTrip(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

혹시 해당 CrewTrip을 탈퇴 Request에서 받던데 본인이 참여중인 크루 여행목록은 프론트에서 주는건가요?? 여행에서 가져오는게 아니라?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API gateway에서 Trip 서비스로 요청해서 참여중인 크루 여행 목록을 받아오고
다시 Crew 서비스의 크루 탈퇴 API의 Request로 넘겨준다고 생각해서 설계했습니다.

UUID tripId,
CrewTripType type
) {
public boolean isImpossibleWithdrawal() {
return this.type == EXCLUSION;
}

@Getter
@AllArgsConstructor
public enum CrewTripType {
EXCLUSION("EXCLUSION", "크루원 전용"),
INCLUSION("INCLUSION", "크루원 포함");

private final String code;
private final String viewName;
}
}


Loading