diff --git a/src/main/java/com/unionmate/backend/domain/applicant/application/dto/response/ApplicationAnswerResponse.java b/src/main/java/com/unionmate/backend/domain/applicant/application/dto/response/ApplicationAnswerResponse.java index f8e48f7..26b8d8e 100644 --- a/src/main/java/com/unionmate/backend/domain/applicant/application/dto/response/ApplicationAnswerResponse.java +++ b/src/main/java/com/unionmate/backend/domain/applicant/application/dto/response/ApplicationAnswerResponse.java @@ -1,5 +1,7 @@ package com.unionmate.backend.domain.applicant.application.dto.response; +import java.util.Map; + import com.unionmate.backend.domain.recruitment.application.exception.ItemTypeNotExistException; import com.unionmate.backend.domain.recruitment.domain.entity.enums.ItemType; import com.unionmate.backend.domain.recruitment.domain.entity.item.CalendarItem; @@ -17,10 +19,10 @@ public sealed interface ApplicationAnswerResponse String description(); - static ApplicationAnswerResponse from(Item item) { + static ApplicationAnswerResponse from(Item item, Map selectOptionTitleById) { return switch (item) { case TextItem textItem -> TextAnswerResponse.from(textItem); - case SelectItem selectItem -> SelectAnswerResponse.from(selectItem); + case SelectItem selectItem -> SelectAnswerResponse.from(selectItem, selectOptionTitleById); case CalendarItem calendarItem -> CalendarAnswerResponse.from(calendarItem); default -> throw new ItemTypeNotExistException(); }; diff --git a/src/main/java/com/unionmate/backend/domain/applicant/application/dto/response/GetApplicationAdminResponse.java b/src/main/java/com/unionmate/backend/domain/applicant/application/dto/response/GetApplicationAdminResponse.java index 8486207..399a667 100644 --- a/src/main/java/com/unionmate/backend/domain/applicant/application/dto/response/GetApplicationAdminResponse.java +++ b/src/main/java/com/unionmate/backend/domain/applicant/application/dto/response/GetApplicationAdminResponse.java @@ -3,12 +3,17 @@ import java.time.LocalDateTime; import java.util.Comparator; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import com.unionmate.backend.domain.applicant.domain.entity.Application; import com.unionmate.backend.domain.applicant.domain.entity.embed.Interview; import com.unionmate.backend.domain.applicant.domain.entity.enums.EvaluationStatus; +import com.unionmate.backend.domain.recruitment.domain.entity.Recruitment; import com.unionmate.backend.domain.recruitment.domain.entity.enums.RecruitmentStatus; import com.unionmate.backend.domain.recruitment.domain.entity.item.Item; +import com.unionmate.backend.domain.recruitment.domain.entity.item.SelectItem; +import com.unionmate.backend.domain.recruitment.domain.entity.item.SelectItemOption; import io.swagger.v3.oas.annotations.media.Schema; @@ -37,9 +42,11 @@ public record GetApplicationAdminResponse( LocalDateTime submittedAt ) { public static GetApplicationAdminResponse from(Application application) { + Map selectOptions = buildSelectOptionMap(application.getRecruitment()); + List sortedAnswers = application.getAnswers().stream() .sorted(Comparator.comparing(Item::getOrder)) - .map(ApplicationAnswerResponse::from) + .map(item -> ApplicationAnswerResponse.from(item, selectOptions)) .toList(); InterviewResponse interviewResponse = from(application.getInterview()); @@ -118,4 +125,15 @@ public record InterviewResponse( String place ) { } + + private static Map buildSelectOptionMap(Recruitment recruitment) { + return recruitment.getItems().stream() + .filter(item -> item instanceof SelectItem) + .map(item -> (SelectItem)item) + .flatMap(selectItem -> selectItem.getSelectItemOptions().stream()) + .collect(Collectors.toMap( + SelectItemOption::getId, + SelectItemOption::getTitle + )); + } } diff --git a/src/main/java/com/unionmate/backend/domain/applicant/application/dto/response/GetApplicationResponse.java b/src/main/java/com/unionmate/backend/domain/applicant/application/dto/response/GetApplicationResponse.java index e0bba53..c26b29b 100644 --- a/src/main/java/com/unionmate/backend/domain/applicant/application/dto/response/GetApplicationResponse.java +++ b/src/main/java/com/unionmate/backend/domain/applicant/application/dto/response/GetApplicationResponse.java @@ -2,9 +2,14 @@ import java.util.Comparator; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import com.unionmate.backend.domain.applicant.domain.entity.Application; +import com.unionmate.backend.domain.recruitment.domain.entity.Recruitment; import com.unionmate.backend.domain.recruitment.domain.entity.item.Item; +import com.unionmate.backend.domain.recruitment.domain.entity.item.SelectItem; +import com.unionmate.backend.domain.recruitment.domain.entity.item.SelectItemOption; import io.swagger.v3.oas.annotations.media.Schema; @@ -29,9 +34,11 @@ public record GetApplicationResponse( List answers ) { public static GetApplicationResponse from(Application application) { + Map selectOptions = buildSelectOptionMap(application.getRecruitment()); + List answer = application.getAnswers().stream() .sorted(Comparator.comparing(Item::getOrder)) - .map(ApplicationAnswerResponse::from) + .map(item -> ApplicationAnswerResponse.from(item, selectOptions)) .toList(); return new GetApplicationResponse( @@ -44,4 +51,15 @@ public static GetApplicationResponse from(Application application) { answer ); } + + private static Map buildSelectOptionMap(Recruitment recruitment) { + return recruitment.getItems().stream() + .filter(item -> item instanceof SelectItem) + .map(item -> (SelectItem)item) + .flatMap(selectItem -> selectItem.getSelectItemOptions().stream()) + .collect(Collectors.toMap( + SelectItemOption::getId, + SelectItemOption::getTitle + )); + } } diff --git a/src/main/java/com/unionmate/backend/domain/applicant/application/dto/response/SelectAnswerResponse.java b/src/main/java/com/unionmate/backend/domain/applicant/application/dto/response/SelectAnswerResponse.java index f5efa6c..a184641 100644 --- a/src/main/java/com/unionmate/backend/domain/applicant/application/dto/response/SelectAnswerResponse.java +++ b/src/main/java/com/unionmate/backend/domain/applicant/application/dto/response/SelectAnswerResponse.java @@ -1,6 +1,7 @@ package com.unionmate.backend.domain.applicant.application.dto.response; import java.util.List; +import java.util.Map; import com.unionmate.backend.domain.recruitment.domain.entity.enums.ItemType; import com.unionmate.backend.domain.recruitment.domain.entity.item.SelectItem; @@ -23,18 +24,24 @@ public record SelectAnswerResponse( @Schema(description = "중복 선택 가능 여부 ", example = "false") boolean multiple, - @Schema(description = "답변한 선택지") - List selectedOptionIds + @Schema(description = "답변한 선택지 항목") + List selectOptions ) implements ApplicationAnswerResponse { - public static SelectAnswerResponse from(SelectItem selectItem) { + public static SelectAnswerResponse from(SelectItem selectItem, Map selectOptionTitleById) { + List selectOptionIds = selectItem.getAnswer() == null ? List.of() : selectItem.getAnswer().answer(); + + List selectOptions = selectOptionIds.stream() + .map(optionId -> new SelectOptionAnswerResponse(optionId, selectOptionTitleById.get(optionId))) + .toList(); + return new SelectAnswerResponse( ItemType.SELECT, selectItem.getTitle(), selectItem.getOrder(), selectItem.getDescription(), selectItem.isMultiple(), - selectItem.getAnswer() == null ? List.of() : selectItem.getAnswer().answer() + selectOptions ); } } diff --git a/src/main/java/com/unionmate/backend/domain/applicant/application/dto/response/SelectOptionAnswerResponse.java b/src/main/java/com/unionmate/backend/domain/applicant/application/dto/response/SelectOptionAnswerResponse.java new file mode 100644 index 0000000..f1f25f3 --- /dev/null +++ b/src/main/java/com/unionmate/backend/domain/applicant/application/dto/response/SelectOptionAnswerResponse.java @@ -0,0 +1,12 @@ +package com.unionmate.backend.domain.applicant.application.dto.response; + +import io.swagger.v3.oas.annotations.media.Schema; + +public record SelectOptionAnswerResponse( + @Schema(description = "선택지 id", example = "1") + Long optionId, + + @Schema(description = "선택지 title", example = "월요일") + String title +) { +} diff --git a/src/main/java/com/unionmate/backend/domain/applicant/domain/repository/ApplicationRepository.java b/src/main/java/com/unionmate/backend/domain/applicant/domain/repository/ApplicationRepository.java index 11bae99..5f30f34 100644 --- a/src/main/java/com/unionmate/backend/domain/applicant/domain/repository/ApplicationRepository.java +++ b/src/main/java/com/unionmate/backend/domain/applicant/domain/repository/ApplicationRepository.java @@ -29,7 +29,7 @@ public interface ApplicationRepository extends JpaRepository ) from Application a join a.recruitment r - where r.council = :council + where r = :recruitment and ( a.stage.recruitmentStatus = com.unionmate.backend.domain.recruitment.domain.entity.enums.RecruitmentStatus.DOCUMENT_SCREENING or ( @@ -39,7 +39,7 @@ public interface ApplicationRepository extends JpaRepository ) order by a.id desc """) - List findDocumentListNoFilter(@Param("council") Council council); + List findDocumentListNoFilter(@Param("recruitment") Recruitment recruitment); @Query(""" select new com.unionmate.backend.domain.council.application.dto.CouncilApplicantQueryRow( @@ -47,12 +47,12 @@ public interface ApplicationRepository extends JpaRepository ) from Application a join a.recruitment r - where r.council = :council + where r = :recruitment and a.stage.recruitmentStatus = com.unionmate.backend.domain.recruitment.domain.entity.enums.RecruitmentStatus.DOCUMENT_SCREENING and a.stage.evaluationStatus = com.unionmate.backend.domain.applicant.domain.entity.enums.EvaluationStatus.SUBMITTED order by a.id desc """) - List findDocumentListSubmitted(@Param("council") Council council); + List findDocumentListSubmitted(@Param("recruitment") Recruitment recruitment); @Query(""" select new com.unionmate.backend.domain.council.application.dto.CouncilApplicantQueryRow( @@ -60,12 +60,12 @@ public interface ApplicationRepository extends JpaRepository ) from Application a join a.recruitment r - where r.council = :council + where r = :recruitment and a.stage.recruitmentStatus = com.unionmate.backend.domain.recruitment.domain.entity.enums.RecruitmentStatus.INTERVIEW and a.stage.evaluationStatus = com.unionmate.backend.domain.applicant.domain.entity.enums.EvaluationStatus.SUBMITTED order by a.id desc """) - List findDocumentListPassed(@Param("council") Council council); + List findDocumentListPassed(@Param("recruitment") Recruitment recruitment); @Query(""" select new com.unionmate.backend.domain.council.application.dto.CouncilApplicantQueryRow( @@ -73,12 +73,12 @@ public interface ApplicationRepository extends JpaRepository ) from Application a join a.recruitment r - where r.council = :council + where r = :recruitment and a.stage.recruitmentStatus = com.unionmate.backend.domain.recruitment.domain.entity.enums.RecruitmentStatus.DOCUMENT_SCREENING and a.stage.evaluationStatus = com.unionmate.backend.domain.applicant.domain.entity.enums.EvaluationStatus.FAILED order by a.id desc """) - List findDocumentListFailed(@Param("council") Council council); + List findDocumentListFailed(@Param("recruitment") Recruitment recruitment); @Query(""" select new com.unionmate.backend.domain.council.application.dto.CouncilApplicantQueryRow( @@ -86,14 +86,14 @@ public interface ApplicationRepository extends JpaRepository ) from Application a join a.recruitment r - where r.council = :council + where r = :recruitment and a.stage.recruitmentStatus in ( com.unionmate.backend.domain.recruitment.domain.entity.enums.RecruitmentStatus.INTERVIEW, com.unionmate.backend.domain.recruitment.domain.entity.enums.RecruitmentStatus.FINAL ) order by a.id desc """) - List findInterviewListNoFilter(@Param("council") Council council); + List findInterviewListNoFilter(@Param("recruitment") Recruitment recruitment); @Query(""" select new com.unionmate.backend.domain.council.application.dto.CouncilApplicantQueryRow( @@ -101,12 +101,12 @@ and a.stage.recruitmentStatus in ( ) from Application a join a.recruitment r - where r.council = :council + where r = :recruitment and a.stage.recruitmentStatus = com.unionmate.backend.domain.recruitment.domain.entity.enums.RecruitmentStatus.INTERVIEW and a.stage.evaluationStatus = com.unionmate.backend.domain.applicant.domain.entity.enums.EvaluationStatus.SUBMITTED order by a.id desc """) - List findInterviewListSubmitted(@Param("council") Council council); + List findInterviewListSubmitted(@Param("recruitment") Recruitment recruitment); @Query(""" select new com.unionmate.backend.domain.council.application.dto.CouncilApplicantQueryRow( @@ -114,12 +114,12 @@ and a.stage.recruitmentStatus in ( ) from Application a join a.recruitment r - where r.council = :council + where r = :recruitment and a.stage.recruitmentStatus = com.unionmate.backend.domain.recruitment.domain.entity.enums.RecruitmentStatus.FINAL and a.stage.evaluationStatus = com.unionmate.backend.domain.applicant.domain.entity.enums.EvaluationStatus.PASSED order by a.id desc """) - List findInterviewListPassed(@Param("council") Council council); + List findInterviewListPassed(@Param("recruitment") Recruitment recruitment); @Query(""" select new com.unionmate.backend.domain.council.application.dto.CouncilApplicantQueryRow( @@ -127,12 +127,12 @@ and a.stage.recruitmentStatus in ( ) from Application a join a.recruitment r - where r.council = :council + where r = :recruitment and a.stage.recruitmentStatus = com.unionmate.backend.domain.recruitment.domain.entity.enums.RecruitmentStatus.FINAL and a.stage.evaluationStatus = com.unionmate.backend.domain.applicant.domain.entity.enums.EvaluationStatus.FAILED order by a.id desc """) - List findInterviewListFailed(@Param("council") Council council); + List findInterviewListFailed(@Param("recruitment") Recruitment recruitment); @EntityGraph(attributePaths = {"recruitment", "recruitment.council", "answers"}) @Query("select a from Application a where a.id = :id") diff --git a/src/main/java/com/unionmate/backend/domain/applicant/domain/service/ApplicationGetService.java b/src/main/java/com/unionmate/backend/domain/applicant/domain/service/ApplicationGetService.java index e80b911..c5f9520 100644 --- a/src/main/java/com/unionmate/backend/domain/applicant/domain/service/ApplicationGetService.java +++ b/src/main/java/com/unionmate/backend/domain/applicant/domain/service/ApplicationGetService.java @@ -51,33 +51,33 @@ public Application getByRecruitmentIdAndNameAndEmailWithRecruitmentAndCouncil( .orElseThrow(ApplicationNotFoundException::new); } - public List getDocumentScreeningApplicantsForCouncil( - Council council, EvaluationStatus evaluationFilterOrNull + public List getDocumentScreeningApplicantsForRecruitment( + Recruitment recruitment, EvaluationStatus evaluationFilterOrNull ) { if (evaluationFilterOrNull == null) { - return applicationRepository.findDocumentListNoFilter(council); + return applicationRepository.findDocumentListNoFilter(recruitment); } return switch (evaluationFilterOrNull) { - case SUBMITTED -> applicationRepository.findDocumentListSubmitted(council); - case PASSED -> applicationRepository.findDocumentListPassed(council); - case FAILED -> applicationRepository.findDocumentListFailed(council); - default -> applicationRepository.findDocumentListNoFilter(council); + case SUBMITTED -> applicationRepository.findDocumentListSubmitted(recruitment); + case PASSED -> applicationRepository.findDocumentListPassed(recruitment); + case FAILED -> applicationRepository.findDocumentListFailed(recruitment); + default -> applicationRepository.findDocumentListNoFilter(recruitment); }; } - public List getInterviewApplicantsForCouncil( - Council council, EvaluationStatus evaluationFilterOrNull + public List getInterviewApplicantsForRecruitment( + Recruitment recruitment, EvaluationStatus evaluationFilterOrNull ) { if (evaluationFilterOrNull == null) { - return applicationRepository.findInterviewListNoFilter(council); + return applicationRepository.findInterviewListNoFilter(recruitment); } return switch (evaluationFilterOrNull) { - case SUBMITTED -> applicationRepository.findInterviewListSubmitted(council); - case PASSED -> applicationRepository.findInterviewListPassed(council); - case FAILED -> applicationRepository.findInterviewListFailed(council); - default -> applicationRepository.findInterviewListNoFilter(council); + case SUBMITTED -> applicationRepository.findInterviewListSubmitted(recruitment); + case PASSED -> applicationRepository.findInterviewListPassed(recruitment); + case FAILED -> applicationRepository.findInterviewListFailed(recruitment); + default -> applicationRepository.findInterviewListNoFilter(recruitment); }; } diff --git a/src/main/java/com/unionmate/backend/domain/council/application/usecase/CouncilManageUsecase.java b/src/main/java/com/unionmate/backend/domain/council/application/usecase/CouncilManageUsecase.java index 3ab6086..4646381 100644 --- a/src/main/java/com/unionmate/backend/domain/council/application/usecase/CouncilManageUsecase.java +++ b/src/main/java/com/unionmate/backend/domain/council/application/usecase/CouncilManageUsecase.java @@ -27,6 +27,8 @@ import com.unionmate.backend.domain.member.domain.entity.School; import com.unionmate.backend.domain.member.domain.service.MemberGetService; import com.unionmate.backend.domain.member.domain.service.SchoolGetService; +import com.unionmate.backend.domain.recruitment.domain.entity.Recruitment; +import com.unionmate.backend.domain.recruitment.domain.service.RecruitmentGetService; import lombok.RequiredArgsConstructor; @@ -39,6 +41,7 @@ public class CouncilManageUsecase { private final ApplicationGetService applicationGetService; private final CouncilManagerGetService councilManagerGetService; private final CouncilGetService councilGetService; + private final RecruitmentGetService recruitmentGetService; private final CouncilSaveService councilSaveService; private final CouncilManagerSaveService councilManagerSaveService; @@ -113,14 +116,16 @@ private void validateCouncilManagerExists(Member member) { } public List getDocumentScreeningApplicants( - long memberId, long councilId, EvaluationStatus evaluationFilterOrNull + long memberId, long recruitmentId, EvaluationStatus evaluationFilterOrNull ) { + Recruitment recruitment = recruitmentGetService.getRecruitmentById(recruitmentId); + CouncilManager councilManager = councilManagerGetService.getCouncilManagerByMemberId(memberId); - Council council = councilGetService.getCouncilById(councilId); + Council council = recruitment.getCouncil(); councilManager.validateBelongsToCouncil(councilManager, council); List rows = - applicationGetService.getDocumentScreeningApplicantsForCouncil(council, evaluationFilterOrNull); + applicationGetService.getDocumentScreeningApplicantsForRecruitment(recruitment, evaluationFilterOrNull); return rows.stream() .map(row -> CouncilApplicantResponse.of( @@ -130,14 +135,16 @@ public List getDocumentScreeningApplicants( } public List getInterviewApplicants( - long memberId, long councilId, EvaluationStatus evaluationFilterOrNull + long memberId, long recruitmentId, EvaluationStatus evaluationFilterOrNull ) { + Recruitment recruitment = recruitmentGetService.getRecruitmentById(recruitmentId); + CouncilManager councilManager = councilManagerGetService.getCouncilManagerByMemberId(memberId); - Council council = councilGetService.getCouncilById(councilId); + Council council = recruitment.getCouncil(); councilManager.validateBelongsToCouncil(councilManager, council); List rows = - applicationGetService.getInterviewApplicantsForCouncil(council, evaluationFilterOrNull); + applicationGetService.getInterviewApplicantsForRecruitment(recruitment, evaluationFilterOrNull); return rows.stream() .map(row -> CouncilApplicantResponse.of( diff --git a/src/main/java/com/unionmate/backend/domain/council/presentation/CouncilController.java b/src/main/java/com/unionmate/backend/domain/council/presentation/CouncilController.java index adbe85b..30b6ef7 100644 --- a/src/main/java/com/unionmate/backend/domain/council/presentation/CouncilController.java +++ b/src/main/java/com/unionmate/backend/domain/council/presentation/CouncilController.java @@ -119,14 +119,14 @@ public CommonResponse removeCouncilMember(@CurrentMemberId long memberId, - result=FAILED : DOCUMENT_SCREENING + FAILED """ ) - @GetMapping("/{councilId}/applications/document-screening") + @GetMapping("/{recruitmentId}/applications/document-screening") public CommonResponse> getDocumentScreeningApplicants( @CurrentMemberId long memberId, - @PathVariable long councilId, + @PathVariable long recruitmentId, @RequestParam(name = "result", required = false) EvaluationStatus evaluationStatus ) { List response = councilManageUsecase.getDocumentScreeningApplicants(memberId, - councilId, evaluationStatus); + recruitmentId, evaluationStatus); return CommonResponse.success(COUNCIL_DOCUMENT_LIST, response); } @@ -140,13 +140,13 @@ public CommonResponse> getDocumentScreeningApplic - result=FAILED : FINAL + FAILED """ ) - @GetMapping("/{councilId}/applications/interview") + @GetMapping("/{recruitmentId}/applications/interview") public CommonResponse> getInterviewApplicants( @CurrentMemberId long memberId, - @PathVariable long councilId, + @PathVariable long recruitmentId, @RequestParam(name = "result", required = false) EvaluationStatus evaluationStatus ) { - List response = councilManageUsecase.getInterviewApplicants(memberId, councilId, + List response = councilManageUsecase.getInterviewApplicants(memberId, recruitmentId, evaluationStatus); return CommonResponse.success(COUNCIL_INTERVIEW_LIST, response);