-
Notifications
You must be signed in to change notification settings - Fork 2
feat : 크루 참여 요청 시 질문 답변 기능 구현 #50
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
base: develop
Are you sure you want to change the base?
Changes from all commits
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 |
|---|---|---|
|
|
@@ -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; | ||
|
|
@@ -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; | ||
|
|
@@ -40,6 +39,7 @@ | |
| import org.springframework.stereotype.Service; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
|
|
||
|
|
||
| @Service | ||
| @Transactional | ||
| @RequiredArgsConstructor | ||
|
|
@@ -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); | ||
| } | ||
|
|
||
| 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
Contributor
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. jpa 쓰기 지연이 작동하겠지만 반복문으로 repository 를 호출하는건 문제가 될 수 있어 보입니다. 한번에 목록으로 조회해서 적절한 책임을 갖는 객체에서 검증하는 것도 괜찮을것 같아요. |
||
|
|
||
| RecruitmentAnswer answer = RecruitmentAnswer.of(demand, question, answerRequest.content()); | ||
| demand.addAnswer(answer); | ||
| }); | ||
|
|
||
| return CreateDemandResponse.of(crew.getId(), demand); | ||
| } | ||
|
|
||
|
|
@@ -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
Contributor
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. 리스트를 다루는 로직은 아무래도 일급컬렉션을 사용하는게 깔끔해 보입니다. |
||
|
|
||
| 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 |
|---|---|---|
| @@ -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
Contributor
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. 메소드명 of 로 통일하는게 좋겠어요 |
||
| } | ||
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.
디미터 법칙을 참고해 주시면 좋을것 같아요