Skip to content
Open
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
54 changes: 48 additions & 6 deletions src/main/java/com/retrip/crew/application/in/DemandService.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,11 @@
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.request.demand.UpdateDemandRequest;
import com.retrip.crew.application.in.response.CreateRecruitmentQuestionResponse;
import com.retrip.crew.application.in.response.RecruitmentQuestionResponse;
import com.retrip.crew.application.in.response.UpdateRecruitmentQuestionResponse;
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.response.demand.*;
import com.retrip.crew.application.in.usecase.ManageDemandUseCase;
import com.retrip.crew.application.in.usecase.ManageRecruitmentQuestionUseCase;
import com.retrip.crew.application.in.usecase.UpdateRecruitmentUseCase;
Expand All @@ -24,14 +20,17 @@
import com.retrip.crew.application.out.repository.RecruitmentQuestionRepository;
import com.retrip.crew.domain.entity.Crew;
import com.retrip.crew.domain.entity.Demand;
import com.retrip.crew.domain.entity.RecruitmentAnswer;
import com.retrip.crew.domain.entity.RecruitmentQuestion;
import com.retrip.crew.domain.exception.CrewNotFoundException;
import com.retrip.crew.domain.exception.NotCrewLeaderException;
import com.retrip.crew.domain.exception.QuestionNotFoundException;
import com.retrip.crew.domain.exception.common.BusinessException;
import com.retrip.crew.domain.exception.common.EntityNotFoundException;
import com.retrip.crew.domain.exception.common.ErrorCode;
import com.retrip.crew.domain.vo.DemandStatus;
import com.retrip.crew.infra.util.PaginationUtils;
import com.retrip.crew.domain.exception.common.InvalidValueException;
import java.util.List;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
Expand All @@ -40,6 +39,7 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


@Service
@Transactional
@RequiredArgsConstructor
Expand Down Expand Up @@ -67,7 +67,25 @@ public ChangeRecruitmentStatusResponse stopRecruitment(UUID crewId) {
@Override
public CreateDemandResponse createDemand(UUID crewId, CreateDemandRequest request) {
Crew crew = findById(crewId);

if (crew.getRecruitment().getRecruitmentQuestions().getValues().size() != request.answers().size()) {
throw new InvalidValueException(ErrorCode.MISMATCHED_ANSWER_COUNT);
}
Comment on lines +71 to +73
Copy link
Contributor

Choose a reason for hiding this comment

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

디미터 법칙을 참고해 주시면 좋을것 같아요


Demand demand = crew.demand(request.memberId());

request.answers().forEach(answerRequest -> {
RecruitmentQuestion question = recruitmentQuestionRepository.findById(answerRequest.questionId())
.orElseThrow(QuestionNotFoundException::new);

if (!question.getCrew().getId().equals(crewId)) {
throw new InvalidValueException(ErrorCode.INVALID_QUESTION_FOR_CREW);
}
Comment on lines +77 to +83
Copy link
Contributor

Choose a reason for hiding this comment

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

jpa 쓰기 지연이 작동하겠지만 반복문으로 repository 를 호출하는건 문제가 될 수 있어 보입니다. 한번에 목록으로 조회해서 적절한 책임을 갖는 객체에서 검증하는 것도 괜찮을것 같아요.


RecruitmentAnswer answer = RecruitmentAnswer.of(demand, question, answerRequest.content());
demand.addAnswer(answer);
});

return CreateDemandResponse.of(crew.getId(), demand);
}

Expand Down Expand Up @@ -162,4 +180,28 @@ private RecruitmentQuestion findRecruitmentQuestionByIdAndCrewId(UUID questionId
return recruitmentQuestionRepository.findByIdAndCrewId(questionId, crewId)
.orElseThrow(QuestionNotFoundException::new);
}

@Override
@Transactional(readOnly = true)
public MyDemandResponse getMyDemand(UUID crewId, UUID memberId) {
Demand demand = demandRepository.findByCrewIdAndMemberId(crewId, memberId)
.orElseThrow(() -> new EntityNotFoundException(ErrorCode.USER_DEMAND_NOT_FOUND));
return MyDemandResponse.from(demand);
}

@Override
public UpdateDemandResponse updateDemand(UUID crewId, UpdateDemandRequest request) {
Demand demand = demandRepository.findByCrewIdAndMemberId(crewId, request.memberId())
.orElseThrow(() -> new EntityNotFoundException(ErrorCode.USER_DEMAND_NOT_FOUND));

List<RecruitmentAnswer> newAnswers = request.answers().stream()
.map(answerRequest -> {
RecruitmentQuestion question = findRecruitmentQuestionByIdAndCrewId(answerRequest.questionId(), crewId);
return RecruitmentAnswer.of(demand, question, answerRequest.content());
}).toList();
Comment on lines +197 to +201
Copy link
Contributor

Choose a reason for hiding this comment

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

리스트를 다루는 로직은 아무래도 일급컬렉션을 사용하는게 깔끔해 보입니다.


demand.updateAnswers(request.memberId(), newAnswers);

return UpdateDemandResponse.from(demand);
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,29 @@
package com.retrip.crew.application.in.request.demand;

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

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import java.util.List;
import java.util.UUID;

@Schema(description = "크루 참여 요청 생성 Request")
public record CreateDemandRequest(
UUID memberId
@Schema(description = "참여 요청자 ID")
@NotNull
UUID memberId,

@Schema(description = "질문 답변 목록")
@Valid
List<AnswerRequest> answers
) {
}
@Schema(description = "질문 답변 Request")
public record AnswerRequest(
@Schema(description = "질문 ID")
@NotNull
UUID questionId,

@Schema(description = "답변 내용")
@NotNull
String content
) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.retrip.crew.application.in.request.demand;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import java.util.List;
import java.util.UUID;

@Schema(description = "크루 참여 요청 수정 Request")
public record UpdateDemandRequest(
@Schema(description = "참여 요청자 ID")
@NotNull
UUID memberId,

@Schema(description = "수정할 질문 답변 목록")
@Valid
@NotNull
List<AnswerRequest> answers
) {
@Schema(description = "질문 답변 Request")
public record AnswerRequest(
@Schema(description = "질문 ID")
@NotNull
UUID questionId,

@Schema(description = "새로운 답변 내용")
@NotNull
String content
) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ public record CreateDemandResponse(
@Schema(description = "크루 ID")
UUID crewId,

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

@Schema(description = "참여 요청자 ID")
UUID memberId
) {
public static CreateDemandResponse of(UUID crewId, Demand demand) {
return new CreateDemandResponse(crewId, demand.getMemberId());
return new CreateDemandResponse(crewId, demand.getId(), demand.getMemberId());
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package com.retrip.crew.application.in.response.demand;

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

import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Schema(description = "참여 요청 목록 조회 Response")
public record DemandsResponse(
Expand All @@ -18,9 +21,38 @@ public record DemandsResponse(
UUID memberId,

@Schema(description = "참여 요청 상태")
DemandStatus status
DemandStatus status,

@Schema(description = "질문 답변 목록")
List<AnswerResponse> answers
) {
public static DemandsResponse of(UUID crewId, Demand demand) {
return new DemandsResponse(crewId, demand.getId(), demand.getMemberId(), demand.getStatus());
return new DemandsResponse(
crewId,
demand.getId(),
demand.getMemberId(),
demand.getStatus(),
demand.getAnswers().stream()
.map(AnswerResponse::of)
.collect(Collectors.toList())
);
}

@Schema(description = "질문 답변 Response")
public record AnswerResponse(
@Schema(description = "질문 ID")
UUID questionId,
@Schema(description = "질문 내용")
String questionContent,
@Schema(description = "답변 내용")
String answerContent
) {
public static AnswerResponse of(RecruitmentAnswer answer) {
return new AnswerResponse(
answer.getQuestion().getId(),
answer.getQuestion().getContent().getValue(),
answer.getContent().getValue()
);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.retrip.crew.application.in.response.demand;

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

import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Builder
@Schema(description = "내 참여 요청 조회 Response")
public record MyDemandResponse(
@Schema(description = "크루 ID")
UUID crewId,

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

@Schema(description = "참여 요청 상태")
DemandStatus status,

@Schema(description = "질문 답변 목록")
List<AnswerResponse> answers
) {
public static MyDemandResponse from(Demand demand) {
return MyDemandResponse.builder()
.crewId(demand.getCrew().getId())
.demandId(demand.getId())
.status(demand.getStatus())
.answers(demand.getAnswers().stream()
.map(AnswerResponse::from)
.collect(Collectors.toList()))
.build();
}

@Schema(description = "질문 답변 Response")
public record AnswerResponse(
@Schema(description = "질문 ID")
UUID questionId,
@Schema(description = "질문 내용")
String questionContent,
@Schema(description = "답변 내용")
String answerContent
) {
public static AnswerResponse from(RecruitmentAnswer answer) {
return new AnswerResponse(
answer.getQuestion().getId(),
answer.getQuestion().getContent().getValue(),
answer.getContent().getValue()
);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.retrip.crew.application.in.response.demand;

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

import java.util.UUID;

@Builder
@Schema(description = "크루 참여 요청 수정 Response")
public record UpdateDemandResponse(
@Schema(description = "크루 ID")
UUID crewId,

@Schema(description = "참여 요청 ID")
UUID demandId
) {
public static UpdateDemandResponse from(Demand demand) {
return UpdateDemandResponse.builder()
.crewId(demand.getCrew().getId())
.demandId(demand.getId())
.build();
}
Comment on lines +18 to +23
Copy link
Contributor

Choose a reason for hiding this comment

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

메소드명 of 로 통일하는게 좋겠어요

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
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.request.demand.UpdateDemandRequest;
import com.retrip.crew.application.in.response.demand.*;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
Expand All @@ -22,4 +23,8 @@ Page<DemandsResponse> getDemands(
RejectDemandResponse rejectDemand(UUID crewId, UUID demandId, UUID memberId);

ApproveDemandResponse approveDemand(UUID crewId, UUID demandId, UUID memberId);

MyDemandResponse getMyDemand(UUID crewId, UUID memberId);

UpdateDemandResponse updateDemand(UUID crewId, UpdateDemandRequest request);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,7 @@ public interface CrewDemandRepository extends ReadRepository<Demand, UUID> {

@Query("select d, c from Demand d join fetch d.crew c where d.id = :demandId and c.id = :crewId")
Optional<Demand> findCrewByIdAndCrewId(UUID demandId, UUID crewId);

@Query("select d from Demand d join fetch d.answers where d.crew.id = :crewId and d.memberId = :memberId and d.status <> 'CANCELED'")
Optional<Demand> findByCrewIdAndMemberId(UUID crewId, UUID memberId);
}
Loading