diff --git a/src/main/java/com/jobdri/jobdri_api/domain/mockapply/controller/MockApplyController.java b/src/main/java/com/jobdri/jobdri_api/domain/mockapply/controller/MockApplyController.java index 873b89a..48ee421 100644 --- a/src/main/java/com/jobdri/jobdri_api/domain/mockapply/controller/MockApplyController.java +++ b/src/main/java/com/jobdri/jobdri_api/domain/mockapply/controller/MockApplyController.java @@ -199,7 +199,7 @@ public ApiResponse createMockApply( } @Operation( - summary = "모의 서류 지원 재도전 - ", + summary = "모의 서류 지원 재도전", description = "기존 모의 서류 지원의 공고와 선택 문항을 복사해 새 회차의 모의 서류 지원을 생성합니다. 답변은 비워진 상태로 자소서 입력 단계부터 다시 진행합니다." ) @ApiResponses(value = { diff --git a/src/main/java/com/jobdri/jobdri_api/domain/mockapply/entity/MockApplySequence.java b/src/main/java/com/jobdri/jobdri_api/domain/mockapply/entity/MockApplySequence.java index 3245e8d..c443134 100644 --- a/src/main/java/com/jobdri/jobdri_api/domain/mockapply/entity/MockApplySequence.java +++ b/src/main/java/com/jobdri/jobdri_api/domain/mockapply/entity/MockApplySequence.java @@ -16,7 +16,7 @@ name = "mock_apply_sequences", uniqueConstraints = @UniqueConstraint( name = "uk_mock_apply_sequences_key", - columnNames = {"user_id", "company_id", "detail_classification_id"} + columnNames = {"user_id", "job_posting_id"} ) ) public class MockApplySequence { @@ -28,25 +28,20 @@ public class MockApplySequence { @Column(name = "user_id", nullable = false) private Long userId; - @Column(name = "company_id", nullable = false) - private Long companyId; - - @Column(name = "detail_classification_id", nullable = false) - private Long detailClassificationId; + @Column(name = "job_posting_id", nullable = false) + private Long jobPostingId; @Column(nullable = false) private int lastSequence; public static MockApplySequence create( Long userId, - Long companyId, - Long detailClassificationId, + Long jobPostingId, int lastSequence ) { return MockApplySequence.builder() .userId(userId) - .companyId(companyId) - .detailClassificationId(detailClassificationId) + .jobPostingId(jobPostingId) .lastSequence(lastSequence) .build(); } diff --git a/src/main/java/com/jobdri/jobdri_api/domain/mockapply/repository/MockApplyRepository.java b/src/main/java/com/jobdri/jobdri_api/domain/mockapply/repository/MockApplyRepository.java index 48b7183..cb758ce 100644 --- a/src/main/java/com/jobdri/jobdri_api/domain/mockapply/repository/MockApplyRepository.java +++ b/src/main/java/com/jobdri/jobdri_api/domain/mockapply/repository/MockApplyRepository.java @@ -25,6 +25,17 @@ public interface MockApplyRepository extends JpaRepository { """) Optional findByIdWithJobPosting(@Param("mockApplyId") Long mockApplyId); + @Query(""" + select coalesce(max(ma.sequence), 0) + from MockApply ma + where ma.user.id = :userId + and ma.jobPosting.id = :jobPostingId + """) + int findMaxSequenceByUserIdAndJobPostingId( + @Param("userId") Long userId, + @Param("jobPostingId") Long jobPostingId + ); + @Query(""" select coalesce(max(ma.sequence), 0) from MockApply ma diff --git a/src/main/java/com/jobdri/jobdri_api/domain/mockapply/repository/MockApplySequenceRepository.java b/src/main/java/com/jobdri/jobdri_api/domain/mockapply/repository/MockApplySequenceRepository.java index f519d1a..8a11c41 100644 --- a/src/main/java/com/jobdri/jobdri_api/domain/mockapply/repository/MockApplySequenceRepository.java +++ b/src/main/java/com/jobdri/jobdri_api/domain/mockapply/repository/MockApplySequenceRepository.java @@ -16,12 +16,10 @@ public interface MockApplySequenceRepository extends JpaRepository findByKeyForUpdate( @Param("userId") Long userId, - @Param("companyId") Long companyId, - @Param("detailClassificationId") Long detailClassificationId + @Param("jobPostingId") Long jobPostingId ); } diff --git a/src/main/java/com/jobdri/jobdri_api/domain/mockapply/service/MockApplySequenceService.java b/src/main/java/com/jobdri/jobdri_api/domain/mockapply/service/MockApplySequenceService.java index d6cf1a8..54f332f 100644 --- a/src/main/java/com/jobdri/jobdri_api/domain/mockapply/service/MockApplySequenceService.java +++ b/src/main/java/com/jobdri/jobdri_api/domain/mockapply/service/MockApplySequenceService.java @@ -16,18 +16,16 @@ public class MockApplySequenceService { private final MockApplyRepository mockApplyRepository; @Transactional(propagation = Propagation.REQUIRES_NEW) - public int allocate(Long userId, Long companyId, Long detailClassificationId) { + public int allocate(Long userId, Long jobPostingId) { MockApplySequence sequence = mockApplySequenceRepository - .findByKeyForUpdate(userId, companyId, detailClassificationId) + .findByKeyForUpdate(userId, jobPostingId) .orElseGet(() -> mockApplySequenceRepository.saveAndFlush( MockApplySequence.create( userId, - companyId, - detailClassificationId, - mockApplyRepository.findMaxSequenceByUserIdAndCompanyIdAndDetailClassificationId( + jobPostingId, + mockApplyRepository.findMaxSequenceByUserIdAndJobPostingId( userId, - companyId, - detailClassificationId + jobPostingId ) ) )); diff --git a/src/main/java/com/jobdri/jobdri_api/domain/mockapply/service/MockApplyService.java b/src/main/java/com/jobdri/jobdri_api/domain/mockapply/service/MockApplyService.java index d5838e4..dce7cc9 100644 --- a/src/main/java/com/jobdri/jobdri_api/domain/mockapply/service/MockApplyService.java +++ b/src/main/java/com/jobdri/jobdri_api/domain/mockapply/service/MockApplyService.java @@ -85,18 +85,9 @@ public MockApplyRetryResponse retryMockApply(User user, Long mockApplyId) { MockApply sourceMockApply = getOwnedMockApplyWithJobPosting(validatedUser, mockApplyId); JobPosting sourceJobPosting = sourceMockApply.getJobPosting(); - JobPosting clonedJobPosting = jobPostingRepository.save(JobPosting.create( - validatedUser, - sourceJobPosting.getCompany(), - sourceJobPosting.getDetailClassification(), - sourceJobPosting.getTask(), - sourceJobPosting.getRequirement(), - sourceJobPosting.getPreferred() - )); - MockApply retryMockApply = saveMockApplyWithSequence( validatedUser, - clonedJobPosting, + sourceJobPosting, sourceMockApply.getApplyType(), null ); @@ -269,11 +260,7 @@ private int resolveSequence(User user, JobPosting jobPosting, Integer requestedS private int allocateSequence(User user, JobPosting jobPosting) { for (int attempt = 0; attempt < SEQUENCE_ALLOCATE_MAX_RETRY; attempt++) { try { - return mockApplySequenceService.allocate( - user.getId(), - jobPosting.getCompany().getId(), - jobPosting.getDetailClassification().getId() - ); + return mockApplySequenceService.allocate(user.getId(), jobPosting.getId()); } catch (DataIntegrityViolationException e) { if (attempt == SEQUENCE_ALLOCATE_MAX_RETRY - 1) { throw new GeneralException( diff --git a/src/test/java/com/jobdri/jobdri_api/domain/mockapply/service/MockApplyServiceTest.java b/src/test/java/com/jobdri/jobdri_api/domain/mockapply/service/MockApplyServiceTest.java index 39c3bbc..ec8741f 100644 --- a/src/test/java/com/jobdri/jobdri_api/domain/mockapply/service/MockApplyServiceTest.java +++ b/src/test/java/com/jobdri/jobdri_api/domain/mockapply/service/MockApplyServiceTest.java @@ -125,8 +125,8 @@ void createActualApplyWithRequestedSequence() { } @Test - @DisplayName("같은 회사와 직무의 다른 공고로 재지원하면 다음 순번을 저장한다") - void createActualApplySequencesAcrossSameCompanyAndDetailJobPostings() { + @DisplayName("같은 회사와 직무여도 다른 공고이면 순번을 따로 계산한다") + void createActualApplySequencesByJobPosting() { User user = saveUser("actual-apply-retry-sequence@example.com"); Company company = saveCompany("재지원 기업 " + UUID.randomUUID(), CompanySize.MEDIUM); DetailClassification detailClassification = saveDetailClassification("백엔드 개발"); @@ -138,8 +138,8 @@ void createActualApplySequencesAcrossSameCompanyAndDetailJobPostings() { MockApply secondMockApply = mockApplyRepository.findById(secondResponse.mockApplyId()).orElseThrow(); assertThat(firstResponse.sequence()).isEqualTo(1); - assertThat(secondResponse.sequence()).isEqualTo(2); - assertThat(secondMockApply.getSequence()).isEqualTo(2); + assertThat(secondResponse.sequence()).isEqualTo(1); + assertThat(secondMockApply.getSequence()).isEqualTo(1); } @Test @@ -236,7 +236,7 @@ void createMockApplyFromJobPosting() { } @Test - @DisplayName("기존 지원의 공고와 문항을 복사해 재도전 지원을 생성한다") + @DisplayName("기존 지원의 공고에 새 회차와 문항을 생성한다") void retryMockApply() { User user = saveUser("retry-mock-apply@example.com"); JobPosting jobPosting = saveJobPosting(user, "백엔드 개발"); @@ -250,12 +250,14 @@ void retryMockApply() { JobPosting retryJobPosting = jobPostingRepository.findById(response.jobPostingId()).orElseThrow(); List retryQuestions = questionRepository.findAllByMockApplyIdOrderByIdAsc(response.mockApplyId()); assertThat(response.sourceMockApplyId()).isEqualTo(sourceMockApply.getId()); + assertThat(response.jobPostingId()).isEqualTo(jobPosting.getId()); assertThat(response.sequence()).isEqualTo(2); assertThat(response.status()).isEqualTo(MockApplyStatus.ANSWER_WRITE); assertThat(retryMockApply.getApplyType()).isEqualTo(ApplyType.MOCK); + assertThat(retryMockApply.getJobPosting().getId()).isEqualTo(jobPosting.getId()); assertThat(retryMockApply.getSequence()).isEqualTo(2); assertThat(retryMockApply.getStatus()).isEqualTo(MockApplyStatus.ANSWER_WRITE); - assertThat(retryJobPosting.getId()).isNotEqualTo(jobPosting.getId()); + assertThat(retryJobPosting.getId()).isEqualTo(jobPosting.getId()); assertThat(retryJobPosting.getCompany().getId()).isEqualTo(jobPosting.getCompany().getId()); assertThat(retryJobPosting.getDetailClassification().getId()).isEqualTo(jobPosting.getDetailClassification().getId()); assertThat(retryJobPosting.getTask()).isEqualTo(jobPosting.getTask());