diff --git a/src/main/java/KUSITMS/WITHUS/domain/application/application/controller/AdminApplicationController.java b/src/main/java/KUSITMS/WITHUS/domain/application/application/controller/AdminApplicationController.java index 351e875b..a99fd48c 100644 --- a/src/main/java/KUSITMS/WITHUS/domain/application/application/controller/AdminApplicationController.java +++ b/src/main/java/KUSITMS/WITHUS/domain/application/application/controller/AdminApplicationController.java @@ -156,6 +156,16 @@ public SuccessResponse sendBulkMail( return SuccessResponse.ok("메일을 발송 요청을 보냈습니다."); } + @GetMapping("/recruitment/{recruitmentId}/search") + @Operation(summary = "공고 전체 지원자 검색", description = "메일/문자 발송용으로 공고의 전체 지원자를 이름 또는 이메일로 검색합니다.") + public SuccessResponse> searchApplicants( + @PathVariable Long recruitmentId, + @RequestParam(required = false) String keyword + ) { + List applicants = applicationService.searchApplicantsForMailSms(recruitmentId, keyword); + return SuccessResponse.ok(applicants); + } + @PostMapping("/bulk-sms") @Operation(summary = "지원서 대상 다중 문자 발송", description = "복수의 수신자 전화번호와 메시지, 첨부파일(MMS)을 받아 일괄 발송합니다.") public SuccessResponse sendBulkSms( diff --git a/src/main/java/KUSITMS/WITHUS/domain/application/application/dto/ApplicationResponseDTO.java b/src/main/java/KUSITMS/WITHUS/domain/application/application/dto/ApplicationResponseDTO.java index 8860c209..f480aaab 100644 --- a/src/main/java/KUSITMS/WITHUS/domain/application/application/dto/ApplicationResponseDTO.java +++ b/src/main/java/KUSITMS/WITHUS/domain/application/application/dto/ApplicationResponseDTO.java @@ -555,4 +555,21 @@ public static Applicant from(Application application) { } } + @Schema(description = "메일/문자 발송용 지원자 검색 응답 DTO") + public record ApplicantForMailSms( + @Schema(description = "지원서 ID", example = "1") Long applicationId, + @Schema(description = "지원자 이름", example = "홍길동") String name, + @Schema(description = "지원자 이메일", example = "hong@example.com") String email, + @Schema(description = "프로필 사진 URL", example = "https://example.com/profile.jpg") String profileImageUrl + ) { + public static ApplicantForMailSms from(Application application) { + return new ApplicantForMailSms( + application.getId(), + application.getName(), + application.getEmail(), + application.getImageUrl() + ); + } + } + } diff --git a/src/main/java/KUSITMS/WITHUS/domain/application/application/repository/ApplicationJpaRepository.java b/src/main/java/KUSITMS/WITHUS/domain/application/application/repository/ApplicationJpaRepository.java index 1d3f656c..a8705d54 100644 --- a/src/main/java/KUSITMS/WITHUS/domain/application/application/repository/ApplicationJpaRepository.java +++ b/src/main/java/KUSITMS/WITHUS/domain/application/application/repository/ApplicationJpaRepository.java @@ -11,6 +11,7 @@ public interface ApplicationJpaRepository extends JpaRepository findByRecruitmentId(Long recruitmentId); List findByRecruitmentIdAndStatusIn(Long recruitmentId, List statuses); List findByRecruitment_IdAndOrganizationRole_Id(Long recruitmentId, Long organizationRoleId); + List findByRecruitment_IdAndOrganizationRoleIsNull(Long recruitmentId); Long countByRecruitment_IdAndOrganizationRole_Id(Long recruitmentId, Long organizationRoleId); List findDistinctByRecruitment_IdAndEvaluators_Evaluator_IdAndEvaluators_EvaluationType(Long recruitmentId, Long evaluatorId, EvaluationType evaluationType); Long countByRecruitmentIdAndStatusIn(Long recruitmentId, List statuses); diff --git a/src/main/java/KUSITMS/WITHUS/domain/application/application/repository/ApplicationRepository.java b/src/main/java/KUSITMS/WITHUS/domain/application/application/repository/ApplicationRepository.java index e72af6ff..ce07414c 100644 --- a/src/main/java/KUSITMS/WITHUS/domain/application/application/repository/ApplicationRepository.java +++ b/src/main/java/KUSITMS/WITHUS/domain/application/application/repository/ApplicationRepository.java @@ -14,6 +14,7 @@ public interface ApplicationRepository { List findPassedByRecruitment(Long recruitmentId); List findByRecruitmentIdAndStatusIn(Long recruitmentId, List statuses); List findByRecruitment_IdAndOrganizationRole_Id(Long recruitmentId, Long organizationRoleId); + List findByRecruitment_IdAndOrganizationRoleIsNull(Long recruitmentId); Long countByRecruitment_IdAndOrganizationRole_Id(Long recruitmentId, Long organizationRoleId); List findAllById(List longs); List findDistinctByRecruitment_IdAndEvaluators_Evaluator_IdAndEvaluators_EvaluationType(Long recruitmentId, Long evaluatorId, EvaluationType evaluationType); @@ -22,4 +23,5 @@ public interface ApplicationRepository { List findForTimeSlot(Long timeSlotId); Long findPreviousIdInRecruitment(Long recruitmentId, Long currentId); Long findNextIdInRecruitment(Long recruitmentId, Long currentId); + List findByRecruitmentIdAndNameOrEmail(Long recruitmentId, String keyword); } diff --git a/src/main/java/KUSITMS/WITHUS/domain/application/application/repository/ApplicationRepositoryImpl.java b/src/main/java/KUSITMS/WITHUS/domain/application/application/repository/ApplicationRepositoryImpl.java index a0fe64d5..3ad97fb3 100644 --- a/src/main/java/KUSITMS/WITHUS/domain/application/application/repository/ApplicationRepositoryImpl.java +++ b/src/main/java/KUSITMS/WITHUS/domain/application/application/repository/ApplicationRepositoryImpl.java @@ -62,6 +62,11 @@ public List findByRecruitment_IdAndOrganizationRole_Id(Long recruit return applicationJpaRepository.findByRecruitment_IdAndOrganizationRole_Id(recruitmentId, organizationRoleId); } + @Override + public List findByRecruitment_IdAndOrganizationRoleIsNull(Long recruitmentId) { + return applicationJpaRepository.findByRecruitment_IdAndOrganizationRoleIsNull(recruitmentId); + } + @Override public Long countByRecruitment_IdAndOrganizationRole_Id(Long recruitmentId, Long organizationRoleId) { return applicationJpaRepository.countByRecruitment_IdAndOrganizationRole_Id(recruitmentId, organizationRoleId); @@ -154,4 +159,25 @@ public Long findNextIdInRecruitment(Long recruitmentId, Long currentId) { ) .fetchOne(); } + + @Override + public List findByRecruitmentIdAndNameOrEmail(Long recruitmentId, String keyword) { + com.querydsl.core.types.dsl.BooleanExpression searchPredicate = null; + + // 키워드가 있으면 이름 또는 이메일로 검색, 없으면 전체 목록 조회 + if (keyword != null && !keyword.isBlank()) { + String searchKeyword = keyword.trim(); + searchPredicate = application.name.containsIgnoreCase(searchKeyword) + .or(application.email.containsIgnoreCase(searchKeyword)); + } + + return queryFactory + .selectFrom(application) + .where( + application.recruitment.id.eq(recruitmentId), + searchPredicate // null이면 검색 조건 무시되어 전체 목록 조회 + ) + .orderBy(application.name.asc()) + .fetch(); + } } diff --git a/src/main/java/KUSITMS/WITHUS/domain/application/application/service/ApplicationService.java b/src/main/java/KUSITMS/WITHUS/domain/application/application/service/ApplicationService.java index 9c63749a..7d4262f5 100644 --- a/src/main/java/KUSITMS/WITHUS/domain/application/application/service/ApplicationService.java +++ b/src/main/java/KUSITMS/WITHUS/domain/application/application/service/ApplicationService.java @@ -28,4 +28,5 @@ public interface ApplicationService { boolean toggleAcquaintance(Long applicationId, Long userId); List findTimeslotCandidates(Long recruitmentId, Long timeslotId, String query, boolean excludeCurrent); List getAllDetailForExcel(Long recruitmentId, AdminStageFilter stage, AdminApplicationSortField sortBy, Sort.Direction direction, List organizationRoleIds, List statuses, String keyword, Long id); + List searchApplicantsForMailSms(Long recruitmentId, String keyword); } diff --git a/src/main/java/KUSITMS/WITHUS/domain/application/application/service/ApplicationServiceImpl.java b/src/main/java/KUSITMS/WITHUS/domain/application/application/service/ApplicationServiceImpl.java index cbcfdcbc..6af7a19a 100644 --- a/src/main/java/KUSITMS/WITHUS/domain/application/application/service/ApplicationServiceImpl.java +++ b/src/main/java/KUSITMS/WITHUS/domain/application/application/service/ApplicationServiceImpl.java @@ -206,10 +206,13 @@ public ApplicationResponseDTO.Detail getById(Long id, Long currentUserId) { applicantAvailabilityRepository.findByApplicationId(id); List evaluationList = evaluationRepository.findEvaluationsForApplication(id); + + // 공통 평가 기준(organizationRole이 null) + 해당 지원서의 organizationRole과 일치하는 평가 기준만 조회 List criteriaList = - evaluationCriteriaRepository.findByTypeAndRecruitment( + evaluationCriteriaRepository.findCommonAndByOrganizationRole( + recruitmentId, EvaluationType.DOCUMENT, - recruitmentId + app.getOrganizationRole() ); return assembler.toDetail( @@ -466,6 +469,20 @@ public List findTimeslotCandidates( return applicationRepository.findEligibleCandidates(recruitmentId, timeslotId, q, excludeCurrent); } + /** + * 메일/문자 발송용 지원자 검색 + * @param recruitmentId 공고 ID + * @param keyword 검색어 (지원자 이름 또는 이메일) + * @return 지원자 목록 (지원서 ID, 이름, 이메일, 프로필 사진 URL) + */ + @Override + public List searchApplicantsForMailSms(Long recruitmentId, String keyword) { + List applications = applicationRepository.findByRecruitmentIdAndNameOrEmail(recruitmentId, keyword); + return applications.stream() + .map(ApplicationResponseDTO.ApplicantForMailSms::from) + .toList(); + } + @Override public List getAllDetailForExcel( Long recruitmentId, diff --git a/src/main/java/KUSITMS/WITHUS/domain/application/application/service/evaluator/EvaluatorAssignmentService.java b/src/main/java/KUSITMS/WITHUS/domain/application/application/service/evaluator/EvaluatorAssignmentService.java index 3797bde1..b5f3529b 100644 --- a/src/main/java/KUSITMS/WITHUS/domain/application/application/service/evaluator/EvaluatorAssignmentService.java +++ b/src/main/java/KUSITMS/WITHUS/domain/application/application/service/evaluator/EvaluatorAssignmentService.java @@ -46,7 +46,9 @@ public void distributeEvaluators(ApplicationEvaluatorRequestDTO.Distribute reque // 요청 이력 dto -> 엔티티 매핑 List assignments = request.assignments().stream() .map(dto -> { - OrganizationRole role = organizationRoleRepository.getById(dto.organizationRoleId()); + OrganizationRole role = dto.organizationRoleId() != null + ? organizationRoleRepository.getById(dto.organizationRoleId()) + : null; return DistributionAssignment.builder() .organizationRole(role) .evaluationType(dto.evaluationType()) @@ -77,9 +79,10 @@ public void distributeEvaluators(ApplicationEvaluatorRequestDTO.Distribute reque throw new CustomException(ErrorCode.INSUFFICIENT_EVALUATORS); } - // 이 역할을 지원한 지원서 리스트 - List apps = applicationRepository - .findByRecruitment_IdAndOrganizationRole_Id(recruitmentId, part.organizationRoleId()); + // 이 역할을 지원한 지원서 리스트 (organizationRoleId가 null이면 공통(역할 미지정) 지원서 조회) + List apps = part.organizationRoleId() == null + ? applicationRepository.findByRecruitment_IdAndOrganizationRoleIsNull(recruitmentId) + : applicationRepository.findByRecruitment_IdAndOrganizationRole_Id(recruitmentId, part.organizationRoleId()); // 각 지원서마다 랜덤 n명 배정 for (Application app : apps) { diff --git a/src/main/java/KUSITMS/WITHUS/domain/application/applicationEvaluator/dto/ApplicationEvaluatorRequestDTO.java b/src/main/java/KUSITMS/WITHUS/domain/application/applicationEvaluator/dto/ApplicationEvaluatorRequestDTO.java index cdf4434e..dc7fa1c7 100644 --- a/src/main/java/KUSITMS/WITHUS/domain/application/applicationEvaluator/dto/ApplicationEvaluatorRequestDTO.java +++ b/src/main/java/KUSITMS/WITHUS/domain/application/applicationEvaluator/dto/ApplicationEvaluatorRequestDTO.java @@ -27,8 +27,7 @@ public record Distribute( ) { @Schema(description = "지원 역할(OrganizationRole)별 평가 담당자 배정 정보") public record PartAssignment( - @Schema(description = "지원 역할(OrganizationRole) ID - 지원서가 지원한 역할", example = "4") - @NotNull + @Schema(description = "지원 역할(OrganizationRole) ID - null이면 공통(역할 미지정 지원서) 대상", example = "4") Long organizationRoleId, @Schema(description = "평가 담당자 Role(OrganizationRole) ID - 평가를 담당할 역할", example = "7") diff --git a/src/main/java/KUSITMS/WITHUS/domain/application/distributionRequest/dto/DistributionRequestResponseDTO.java b/src/main/java/KUSITMS/WITHUS/domain/application/distributionRequest/dto/DistributionRequestResponseDTO.java index 8a13b26f..adbe0b31 100644 --- a/src/main/java/KUSITMS/WITHUS/domain/application/distributionRequest/dto/DistributionRequestResponseDTO.java +++ b/src/main/java/KUSITMS/WITHUS/domain/application/distributionRequest/dto/DistributionRequestResponseDTO.java @@ -41,7 +41,7 @@ public record Assignment( ) { public static Assignment from(DistributionAssignment a) { return new Assignment( - a.getOrganizationRole().getName(), + a.getOrganizationRole() != null ? a.getOrganizationRole().getName() : "공통", a.getEvaluationType(), a.getCount() ); diff --git a/src/main/java/KUSITMS/WITHUS/domain/application/distributionRequest/entity/DistributionAssignment.java b/src/main/java/KUSITMS/WITHUS/domain/application/distributionRequest/entity/DistributionAssignment.java index 2e5d798b..d8d1f7c1 100644 --- a/src/main/java/KUSITMS/WITHUS/domain/application/distributionRequest/entity/DistributionAssignment.java +++ b/src/main/java/KUSITMS/WITHUS/domain/application/distributionRequest/entity/DistributionAssignment.java @@ -22,7 +22,7 @@ public class DistributionAssignment extends BaseEntity { private DistributionRequest request; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "ORGANIZATION_ROLE_ID", nullable = false) + @JoinColumn(name = "ORGANIZATION_ROLE_ID") private OrganizationRole organizationRole; @Enumerated(EnumType.STRING) diff --git a/src/main/java/KUSITMS/WITHUS/domain/application/distributionRequest/repository/DistributionRequestRepositoryImpl.java b/src/main/java/KUSITMS/WITHUS/domain/application/distributionRequest/repository/DistributionRequestRepositoryImpl.java index 93b3d9be..75afa737 100644 --- a/src/main/java/KUSITMS/WITHUS/domain/application/distributionRequest/repository/DistributionRequestRepositoryImpl.java +++ b/src/main/java/KUSITMS/WITHUS/domain/application/distributionRequest/repository/DistributionRequestRepositoryImpl.java @@ -1,18 +1,22 @@ package KUSITMS.WITHUS.domain.application.distributionRequest.repository; import KUSITMS.WITHUS.domain.application.distributionRequest.entity.DistributionRequest; -import KUSITMS.WITHUS.global.exception.CustomException; -import KUSITMS.WITHUS.global.exception.ErrorCode; +import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; import java.util.List; +import static KUSITMS.WITHUS.domain.application.distributionRequest.entity.QDistributionRequest.distributionRequest; +import static KUSITMS.WITHUS.domain.application.distributionRequest.entity.QDistributionAssignment.distributionAssignment; +import static KUSITMS.WITHUS.domain.organization.organizationRole.entity.QOrganizationRole.organizationRole; + @Repository @RequiredArgsConstructor public class DistributionRequestRepositoryImpl implements DistributionRequestRepository { private final DistributionRequestJpaRepository distributionRequestJpaRepository; + private final JPAQueryFactory queryFactory; @Override public DistributionRequest findTopByRecruitmentIdOrderByCreatedAtDesc(Long recruitmentId) { @@ -31,7 +35,14 @@ public DistributionRequest save(DistributionRequest distributionRequest) { } public List findAllByRecruitmentIdOrderByCreatedAtDesc(Long recruitmentId) { - return distributionRequestJpaRepository.findAllByRecruitmentIdOrderByCreatedAtDesc(recruitmentId); + return queryFactory + .selectFrom(distributionRequest) + .distinct() + .leftJoin(distributionRequest.assignments, distributionAssignment).fetchJoin() + .leftJoin(distributionAssignment.organizationRole, organizationRole).fetchJoin() + .where(distributionRequest.recruitmentId.eq(recruitmentId)) + .orderBy(distributionRequest.createdAt.desc()) + .fetch(); } } diff --git a/src/main/java/KUSITMS/WITHUS/domain/evaluation/evaluationCriteria/repository/EvaluationCriteriaRepository.java b/src/main/java/KUSITMS/WITHUS/domain/evaluation/evaluationCriteria/repository/EvaluationCriteriaRepository.java index 129b352c..19de19ac 100644 --- a/src/main/java/KUSITMS/WITHUS/domain/evaluation/evaluationCriteria/repository/EvaluationCriteriaRepository.java +++ b/src/main/java/KUSITMS/WITHUS/domain/evaluation/evaluationCriteria/repository/EvaluationCriteriaRepository.java @@ -2,6 +2,7 @@ import KUSITMS.WITHUS.domain.evaluation.evaluationCriteria.entity.EvaluationCriteria; import KUSITMS.WITHUS.domain.evaluation.evaluationCriteria.enumerate.EvaluationType; +import KUSITMS.WITHUS.domain.organization.organizationRole.entity.OrganizationRole; import java.util.List; @@ -10,5 +11,6 @@ public interface EvaluationCriteriaRepository { List findByTypeAndRecruitment(EvaluationType type, Long recruitmentId); Long countByRecruitment_IdAndEvaluationType(Long recruitmentId, EvaluationType stage); List findByRecruitment_IdAndEvaluationType(Long recruitmentId, EvaluationType stage); + List findCommonAndByOrganizationRole(Long recruitmentId, EvaluationType type, OrganizationRole organizationRole); List findAllById(List criteriaIds); } diff --git a/src/main/java/KUSITMS/WITHUS/domain/evaluation/evaluationCriteria/repository/EvaluationCriteriaRepositoryImpl.java b/src/main/java/KUSITMS/WITHUS/domain/evaluation/evaluationCriteria/repository/EvaluationCriteriaRepositoryImpl.java index 26c497b3..66b2f4e5 100644 --- a/src/main/java/KUSITMS/WITHUS/domain/evaluation/evaluationCriteria/repository/EvaluationCriteriaRepositoryImpl.java +++ b/src/main/java/KUSITMS/WITHUS/domain/evaluation/evaluationCriteria/repository/EvaluationCriteriaRepositoryImpl.java @@ -2,18 +2,24 @@ import KUSITMS.WITHUS.domain.evaluation.evaluationCriteria.entity.EvaluationCriteria; import KUSITMS.WITHUS.domain.evaluation.evaluationCriteria.enumerate.EvaluationType; +import KUSITMS.WITHUS.domain.organization.organizationRole.entity.OrganizationRole; import KUSITMS.WITHUS.global.exception.CustomException; import KUSITMS.WITHUS.global.exception.ErrorCode; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; import java.util.List; +import static KUSITMS.WITHUS.domain.evaluation.evaluationCriteria.entity.QEvaluationCriteria.evaluationCriteria; + @Repository @RequiredArgsConstructor public class EvaluationCriteriaRepositoryImpl implements EvaluationCriteriaRepository { private final EvaluationCriteriaJpaRepository evaluationCriteriaJpaRepository; + private final JPAQueryFactory queryFactory; @Override public EvaluationCriteria getById(Long id) { @@ -35,6 +41,23 @@ public List findByRecruitment_IdAndEvaluationType(Long recru return evaluationCriteriaJpaRepository.findByRecruitment_IdAndEvaluationType(recruitmentId, stage); } + @Override + public List findCommonAndByOrganizationRole(Long recruitmentId, EvaluationType type, OrganizationRole organizationRole) { + BooleanExpression roleFilter = organizationRole == null + ? evaluationCriteria.organizationRole.isNull() + : evaluationCriteria.organizationRole.isNull() + .or(evaluationCriteria.organizationRole.eq(organizationRole)); + + return queryFactory + .selectFrom(evaluationCriteria) + .where( + evaluationCriteria.recruitment.id.eq(recruitmentId) + .and(evaluationCriteria.evaluationType.eq(type)) + .and(roleFilter) + ) + .fetch(); + } + @Override public List findAllById(List criteriaIds) { return evaluationCriteriaJpaRepository.findAllById(criteriaIds); diff --git a/src/main/java/KUSITMS/WITHUS/domain/recruitment/position/dto/PositionResponseDTO.java b/src/main/java/KUSITMS/WITHUS/domain/recruitment/position/dto/PositionResponseDTO.java index 98e31f9a..3a6a4d90 100644 --- a/src/main/java/KUSITMS/WITHUS/domain/recruitment/position/dto/PositionResponseDTO.java +++ b/src/main/java/KUSITMS/WITHUS/domain/recruitment/position/dto/PositionResponseDTO.java @@ -1,5 +1,6 @@ package KUSITMS.WITHUS.domain.recruitment.position.dto; +import KUSITMS.WITHUS.domain.organization.organizationRole.entity.OrganizationRole; import KUSITMS.WITHUS.domain.recruitment.position.entity.Position; import io.swagger.v3.oas.annotations.media.Schema; @@ -23,5 +24,17 @@ public static Detail from(Position position) { position.getColor() ); } + + public static Detail from(OrganizationRole organizationRole) { + if (organizationRole == null) { + return null; + } + + return new Detail( + organizationRole.getId(), + organizationRole.getName(), + organizationRole.getColor() + ); + } } } diff --git a/src/main/java/KUSITMS/WITHUS/domain/recruitment/position/service/PositionServiceImpl.java b/src/main/java/KUSITMS/WITHUS/domain/recruitment/position/service/PositionServiceImpl.java index f9989093..b2596e78 100644 --- a/src/main/java/KUSITMS/WITHUS/domain/recruitment/position/service/PositionServiceImpl.java +++ b/src/main/java/KUSITMS/WITHUS/domain/recruitment/position/service/PositionServiceImpl.java @@ -7,12 +7,20 @@ import KUSITMS.WITHUS.domain.recruitment.position.repository.PositionRepository; import KUSITMS.WITHUS.domain.recruitment.recruitment.entity.Recruitment; import KUSITMS.WITHUS.domain.recruitment.recruitment.repository.RecruitmentRepository; +import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; +import static KUSITMS.WITHUS.domain.recruitment.recruitment.entity.QRecruitment.recruitment; +import static KUSITMS.WITHUS.domain.recruitment.recruitmentOrganizationRole.entity.QRecruitmentOrganizationRole.recruitmentOrganizationRole; +import static KUSITMS.WITHUS.domain.organization.organizationRole.entity.QOrganizationRole.organizationRole; + +import KUSITMS.WITHUS.global.exception.CustomException; +import KUSITMS.WITHUS.global.exception.ErrorCode; + @Service @Transactional(readOnly = true) @RequiredArgsConstructor @@ -20,6 +28,7 @@ public class PositionServiceImpl implements PositionService { private final PositionRepository positionRepository; private final RecruitmentRepository recruitmentRepository; + private final JPAQueryFactory queryFactory; /** * 파트 생성 @@ -53,8 +62,20 @@ public void delete(Long id) { @Override public List findAllByRecruitmentId(Long recruitmentId) { - return positionRepository.findAllByRecruitmentId(recruitmentId).stream() - .map(PositionResponseDTO.Detail::from) + // Recruitment의 RecruitmentOrganizationRole 리스트와 각각의 OrganizationRole을 함께 조회하기 위해 fetch join 사용 + Recruitment found = queryFactory + .selectFrom(recruitment) + .leftJoin(recruitment.positions, recruitmentOrganizationRole).fetchJoin() + .leftJoin(recruitmentOrganizationRole.organizationRole, organizationRole).fetchJoin() + .where(recruitment.id.eq(recruitmentId)) + .fetchOne(); + + if (found == null) { + throw new CustomException(ErrorCode.RECRUITMENT_NOT_EXIST); + } + + return found.getPositions().stream() + .map(ror -> PositionResponseDTO.Detail.from(ror.getOrganizationRole())) .toList(); } } diff --git a/src/main/java/KUSITMS/WITHUS/domain/recruitment/recruitment/dto/RecruitmentResponseDTO.java b/src/main/java/KUSITMS/WITHUS/domain/recruitment/recruitment/dto/RecruitmentResponseDTO.java index 485dad80..8f1f04d4 100644 --- a/src/main/java/KUSITMS/WITHUS/domain/recruitment/recruitment/dto/RecruitmentResponseDTO.java +++ b/src/main/java/KUSITMS/WITHUS/domain/recruitment/recruitment/dto/RecruitmentResponseDTO.java @@ -271,12 +271,14 @@ public static TaskProgress from(String positionName, Long daysToDeadline, Long t @Schema(description = "공고 최소한의 정보 응답 DTO") public record Simple( @Schema(description = "공고 Id") Long recruitmentId, - @Schema(description = "공고 제목") String title + @Schema(description = "공고 제목") String title, + @Schema(description = "면접 유무") Boolean isInterviewRequired ) { public static Simple from(Recruitment recruitment) { return new Simple( recruitment.getId(), - recruitment.getTitle() + recruitment.getTitle(), + recruitment.isInterviewRequired() ); } } diff --git a/src/main/java/KUSITMS/WITHUS/domain/template/controller/TemplateController.java b/src/main/java/KUSITMS/WITHUS/domain/template/controller/TemplateController.java index bb83ab71..39885bdb 100644 --- a/src/main/java/KUSITMS/WITHUS/domain/template/controller/TemplateController.java +++ b/src/main/java/KUSITMS/WITHUS/domain/template/controller/TemplateController.java @@ -52,14 +52,25 @@ public SuccessResponse create( } @PutMapping("/{templateId}") - @Operation(summary = "문자/메일 템플릿 수정", description = "기존에 등록된 템플릿의 정보를 수정합니다.") + @Operation(summary = "문자/메일 템플릿 수정", description = "기존에 등록된 템플릿의 정보를 수정합니다. 자신이 속한 조직의 템플릿만 수정 가능합니다.") public SuccessResponse update( @PathVariable Long templateId, - @RequestBody @Valid TemplateRequestDTO.Update dto + @RequestBody @Valid TemplateRequestDTO.Update dto, + @CurrentUser User user ) { - TemplateResponseDTO.Detail updated = templateService.update(templateId, dto); + TemplateResponseDTO.Detail updated = templateService.update(templateId, dto, user); return SuccessResponse.ok(updated); } + @DeleteMapping("/{templateId}") + @Operation(summary = "문자/메일 템플릿 삭제", description = "등록된 템플릿을 삭제합니다. 자신이 속한 조직의 템플릿만 삭제 가능합니다.") + public SuccessResponse delete( + @PathVariable Long templateId, + @CurrentUser User user + ) { + templateService.delete(templateId, user); + return SuccessResponse.ok("템플릿이 삭제되었습니다."); + } + } diff --git a/src/main/java/KUSITMS/WITHUS/domain/template/repository/TemplateRepository.java b/src/main/java/KUSITMS/WITHUS/domain/template/repository/TemplateRepository.java index fa064f28..09bf1ad6 100644 --- a/src/main/java/KUSITMS/WITHUS/domain/template/repository/TemplateRepository.java +++ b/src/main/java/KUSITMS/WITHUS/domain/template/repository/TemplateRepository.java @@ -9,4 +9,5 @@ public interface TemplateRepository { Template getById(Long templateId); List