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
75 changes: 70 additions & 5 deletions src/main/java/com/retrip/crew/application/in/CrewService.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,37 @@
package com.retrip.crew.application.in;

import com.retrip.crew.application.in.request.CreateDemandRequest;
import com.retrip.crew.application.in.request.CrewCreateRequest;
import com.retrip.crew.application.in.request.CrewOrder;
import com.retrip.crew.application.in.request.CrewUpdateRequest;
import com.retrip.crew.application.in.response.*;
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.response.crew.CrewCreateResponse;
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.*;
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.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.domain.entity.Crew;
import com.retrip.crew.domain.entity.Demand;
import com.retrip.crew.domain.entity.Recruitment;
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.CrewDescription;
import com.retrip.crew.domain.vo.CrewTitle;
import com.retrip.crew.domain.vo.DemandStatus;
import com.retrip.crew.infra.adapter.in.presentation.rest.common.ScrollPageResponse;
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.data.domain.Slice;
import org.springframework.stereotype.Service;
Expand All @@ -35,6 +46,7 @@ public class CrewService implements ManageCrewUseCase, UpdateRecruitmentUseCase,
private final CrewRepository crewRepository;
private final CrewMemberRepository crewMemberRepository;
private final CrewQueryRepository crewQueryRepository;
private final CrewDemandRepository demandRepository;

@Override
public CrewCreateResponse createCrew(CrewCreateRequest request) {
Expand Down Expand Up @@ -75,6 +87,59 @@ public CreateDemandResponse createDemand(UUID crewId, CreateDemandRequest reques
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) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

해당 코드가 서비스 로직에 있는것이 맞는걸까요??

Copy link
Contributor Author

Choose a reason for hiding this comment

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

조회를 위한 검증이라 entity로 옮기긴 애매할것 같아요. 생각나는 좋은 방법 있으신가요?

Copy link
Collaborator

Choose a reason for hiding this comment

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

엔티티에 있으면 좋을 것 같다고 생각하긴 했는데.. 말씀주신대로 조회를 위한 검증이라 서비스에 있는것이 좋을 것 같습니다.
추가로 Crew 조회 시, Crew Member와 같이 Fetch 조인하면, Query를 1번만 호출할 거 같네요!

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) {
Copy link
Collaborator

@xjvmdutl xjvmdutl Apr 6, 2025

Choose a reason for hiding this comment

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

CrewId까지 Join한 이유가 궁금합니다~
추가로 CrewId로 조인한 것이면, Crew를 조회할 필요가 있을지도 궁금합니다!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

crew는 approveDemand를 호출하기 위해 필요하고 demand를 조회할때 crewId를 파라미터로 사용한 이유는 크루에 해당하는 demand를 안전하게 조회하기 위함입니다. 또한 demand에서 crewId는 외래키이기 때문에 조인은 되지 않습니다.

Copy link
Collaborator

Choose a reason for hiding this comment

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

2테이블을 Join 조회 한 후, Demand에 대한 정보만 조회한다면, Query 1번 만으로 가능할 거 같아서요!
현재는 Crew 조회(DB 조회) > Crew, DemandId를 통한 Demand 엔티티 조회(DB조회)
-> Demand 조회 시, Crew & Demand 테이블을 조인해서 조회 (DB 조회)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

이해했습니다. crew를 조회할때 demand도 함께 가져오는게 좋겠네요.

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

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.retrip.crew.application.in.request;
package com.retrip.crew.application.in.request.crew;

import com.retrip.crew.domain.entity.Crew;
import io.swagger.v3.oas.annotations.media.Schema;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.retrip.crew.application.in.request;
package com.retrip.crew.application.in.request.crew;

import lombok.Getter;
import lombok.RequiredArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.retrip.crew.application.in.request;
package com.retrip.crew.application.in.request.crew;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Size;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.retrip.crew.application.in.request.demand;

import io.swagger.v3.oas.annotations.media.Schema;

import java.util.UUID;

@Schema(description = "크루 참여 요청 생성 Request")
public record CreateDemandRequest(
UUID memberId
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.retrip.crew.application.in.request.demand;

import lombok.Getter;
import lombok.RequiredArgsConstructor;

@Getter
@RequiredArgsConstructor
public enum DemandOrder {
DATE("createdAt");

private final String field;
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.retrip.crew.application.in.response;
package com.retrip.crew.application.in.response.crew;

import com.retrip.crew.domain.entity.Crew;
import com.retrip.crew.domain.vo.RecruitmentStatus;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.retrip.crew.application.in.response;
package com.retrip.crew.application.in.response.crew;

import com.retrip.crew.domain.entity.Crew;
import com.retrip.crew.domain.entity.CrewMember;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.retrip.crew.application.in.response;
package com.retrip.crew.application.in.response.crew;

import io.swagger.v3.oas.annotations.media.Schema;
import java.util.UUID;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package com.retrip.crew.application.in.response;
package com.retrip.crew.application.in.response.crew;

import com.retrip.crew.domain.entity.Crew;
import com.retrip.crew.domain.vo.RecruitmentStatus;
import io.swagger.v3.oas.annotations.media.Schema;

import java.util.UUID;

@Schema(description = "크루 정보 변경 Response")
public record CrewUpdateResponse(
@Schema(description = "크루 ID")
UUID id,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.retrip.crew.application.in.response.demand;

import com.retrip.crew.domain.entity.Demand;
import com.retrip.crew.domain.vo.DemandStatus;
import io.swagger.v3.oas.annotations.media.Schema;

import java.util.UUID;

@Schema(description = "크루 참여 요청 승인 Response")
public record ApproveDemandResponse(
@Schema(description = "크루 ID")
UUID crewId,

@Schema(description = "참여 요청 ID")
UUID demandId,

@Schema(description = "참여 요청자 ID")
UUID memberId,

@Schema(description = "참여 요청 상태")
DemandStatus status
) {
public static ApproveDemandResponse of(Demand demand) {
return new ApproveDemandResponse(demand.getCrew().getId(), demand.getId(), demand.getMemberId(), demand.getStatus());
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package com.retrip.crew.application.in.response;
package com.retrip.crew.application.in.response.demand;

import com.retrip.crew.domain.entity.Crew;
import com.retrip.crew.domain.vo.RecruitmentStatus;
import io.swagger.v3.oas.annotations.media.Schema;

import java.util.UUID;

@Schema(description = "크루 모집 상태 변경 Response")
public record ChangeRecruitmentStatusResponse(
@Schema(description = "크루 ID")
UUID id,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package com.retrip.crew.application.in.response;
package com.retrip.crew.application.in.response.demand;

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

import java.util.UUID;

@Schema(description = "크루 참여 요청 생성 Response")
public record CreateDemandResponse(
@Schema(description = "크루 ID")
UUID crewId,

@Schema(description = "참여 요청자 ID")
UUID memberId
) {
public static CreateDemandResponse of(UUID crewId, Demand demand) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.retrip.crew.application.in.response.demand;

import io.swagger.v3.oas.annotations.media.Schema;

import java.util.UUID;

@Schema(description = "참여자가 속한 크루 목록 조회 Response")
public record CrewsOfDemandResponse(
@Schema(description = "참여 요청자 ID")
UUID memberId,

@Schema(description = "크루 ID")
UUID id,

@Schema(description = "크루 타이틀")
String title,

@Schema(description = "크루 리더 ID")
UUID leaderId,

@Schema(description = "크루원 현재 인원수")
long memberCount,

@Schema(description = "크루원 최대 인원수")
int maxMemberCount
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.retrip.crew.application.in.response.demand;

import com.retrip.crew.domain.entity.Demand;
import com.retrip.crew.domain.vo.DemandStatus;
import io.swagger.v3.oas.annotations.media.Schema;

import java.util.UUID;

@Schema(description = "참여 요청 목록 조회 Response")
public record DemandsResponse(
@Schema(description = "크루 ID")
UUID crewId,

@Schema(description = "참여 요청 ID")
UUID demandId,

@Schema(description = "참여 요청자 ID")
UUID memberId,

@Schema(description = "참여 요청 상태")
DemandStatus status
) {
public static DemandsResponse of(UUID crewId, Demand demand) {
return new DemandsResponse(crewId, demand.getId(), demand.getMemberId(), demand.getStatus());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.retrip.crew.application.in.response.demand;

import com.retrip.crew.domain.entity.Demand;
import com.retrip.crew.domain.vo.DemandStatus;
import io.swagger.v3.oas.annotations.media.Schema;

import java.util.UUID;

@Schema(description = "크루 참여 요청 거절 Response")
public record RejectDemandResponse(
@Schema(description = "크루 ID")
UUID crewId,

@Schema(description = "참여 요청 ID")
UUID demandId,

@Schema(description = "참여 요청자 ID")
UUID memberId,

@Schema(description = "참여 요청 상태")
DemandStatus status
) {
public static RejectDemandResponse of(Demand demand) {
return new RejectDemandResponse(demand.getCrew().getId(), demand.getId(), demand.getMemberId(), demand.getStatus());
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package com.retrip.crew.application.in.usecase;

import com.retrip.crew.application.in.request.CrewOrder;
import com.retrip.crew.application.in.response.CrewDetailResponse;
import com.retrip.crew.application.in.response.CrewListResponse;
import com.retrip.crew.application.in.request.crew.CrewOrder;
import com.retrip.crew.application.in.response.crew.CrewDetailResponse;
import com.retrip.crew.application.in.response.crew.CrewListResponse;
import com.retrip.crew.infra.adapter.in.presentation.rest.common.ScrollPageResponse;
import java.util.UUID;
import org.springframework.data.domain.Pageable;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.retrip.crew.application.in.usecase;

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

import java.util.UUID;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
package com.retrip.crew.application.in.usecase;

import com.retrip.crew.application.in.request.CreateDemandRequest;
import com.retrip.crew.application.in.response.CreateDemandResponse;
import com.retrip.crew.application.in.request.demand.CreateDemandRequest;
import com.retrip.crew.application.in.request.crew.CrewOrder;
import com.retrip.crew.application.in.request.demand.DemandOrder;
import com.retrip.crew.application.in.response.demand.*;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.UUID;

public interface ManageDemandUseCase {
CreateDemandResponse createDemand(UUID crewId, CreateDemandRequest request);

Page<DemandsResponse> getDemands(
UUID crewId, UUID memberId, String status, Pageable pageable, DemandOrder order, String sort);

Page<CrewsOfDemandResponse> getCrewsOfDemand(UUID crewId, UUID demandId, UUID memberId, Pageable pageable, CrewOrder order, String sort);

void cancelDemand(UUID crewId, UUID demandId, UUID memberId);

RejectDemandResponse rejectDemand(UUID crewId, UUID demandId, UUID memberId);

ApproveDemandResponse approveDemand(UUID crewId, UUID demandId, UUID memberId);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.retrip.crew.application.in.usecase;

import com.retrip.crew.application.in.response.ChangeRecruitmentStatusResponse;
import com.retrip.crew.application.in.response.demand.ChangeRecruitmentStatusResponse;

import java.util.UUID;

Expand Down
Loading