Skip to content

Commit 294a278

Browse files
authored
Merge pull request #321 from CSE-Shaco/develop
feat: block closed core recruitment submissions
2 parents a303288 + dec629a commit 294a278

4 files changed

Lines changed: 44 additions & 0 deletions

File tree

src/main/java/inha/gdgoc/domain/recruit/core/exception/RecruitCoreApplicationErrorCode.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
@Getter
77
public enum RecruitCoreApplicationErrorCode {
8+
RECRUITMENT_CLOSED("RECRUITMENT_CLOSED", "코어 지원 기간이 종료되었습니다.", HttpStatus.FORBIDDEN),
89
ALREADY_APPLIED("ALREADY_APPLIED", "이미 지원이 완료되었습니다.", HttpStatus.CONFLICT),
910
APPLICATION_NOT_FOUND("APPLICATION_NOT_FOUND", "제출된 운영진 지원서가 없습니다.", HttpStatus.NOT_FOUND);
1011

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package inha.gdgoc.domain.recruit.core.exception;
2+
3+
import java.time.Instant;
4+
import lombok.Getter;
5+
6+
@Getter
7+
public class RecruitCoreClosedException extends RuntimeException {
8+
9+
private final RecruitCoreApplicationErrorCode errorCode;
10+
private final Instant deadline;
11+
12+
public RecruitCoreClosedException(Instant deadline) {
13+
super(RecruitCoreApplicationErrorCode.RECRUITMENT_CLOSED.getMessage());
14+
this.errorCode = RecruitCoreApplicationErrorCode.RECRUITMENT_CLOSED;
15+
this.deadline = deadline;
16+
}
17+
}

src/main/java/inha/gdgoc/domain/recruit/core/exception/RecruitCoreControllerExceptionHandler.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,19 @@ public ResponseEntity<RecruitCoreApplicationErrorResponse> handleAlreadyApplied(
2727
return ResponseEntity.status(code.getStatus()).body(body);
2828
}
2929

30+
@ExceptionHandler(RecruitCoreClosedException.class)
31+
public ResponseEntity<RecruitCoreApplicationErrorResponse> handleClosed(
32+
RecruitCoreClosedException ex
33+
) {
34+
log.debug("RecruitCoreClosedException: {}", ex.getMessage());
35+
var code = ex.getErrorCode();
36+
RecruitCoreApplicationErrorResponse body = RecruitCoreApplicationErrorResponse.of(
37+
code.getCode(),
38+
code.getMessage()
39+
);
40+
return ResponseEntity.status(code.getStatus()).body(body);
41+
}
42+
3043
@ExceptionHandler(RecruitCoreApplicationNotFoundException.class)
3144
public ResponseEntity<RecruitCoreApplicationErrorResponse> handleNotFound(
3245
RecruitCoreApplicationNotFoundException ex

src/main/java/inha/gdgoc/domain/recruit/core/service/RecruitCoreApplicationService.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,14 @@
1111
import inha.gdgoc.domain.recruit.core.enums.RecruitCoreResultStatus;
1212
import inha.gdgoc.domain.recruit.core.exception.RecruitCoreAlreadyAppliedException;
1313
import inha.gdgoc.domain.recruit.core.exception.RecruitCoreApplicationNotFoundException;
14+
import inha.gdgoc.domain.recruit.core.exception.RecruitCoreClosedException;
1415
import inha.gdgoc.domain.recruit.core.repository.RecruitCoreApplicationRepository;
1516
import inha.gdgoc.domain.user.entity.User;
1617
import inha.gdgoc.domain.user.enums.UserRole;
1718
import inha.gdgoc.domain.user.repository.UserRepository;
1819
import inha.gdgoc.global.exception.BusinessException;
1920
import inha.gdgoc.global.exception.GlobalErrorCode;
21+
import java.time.Instant;
2022
import java.util.List;
2123
import lombok.RequiredArgsConstructor;
2224
import org.springframework.stereotype.Service;
@@ -26,6 +28,8 @@
2628
@RequiredArgsConstructor
2729
public class RecruitCoreApplicationService {
2830

31+
private static final Instant RECRUITMENT_DEADLINE = Instant.parse("2026-03-14T14:59:59Z");
32+
2933
private final RecruitCoreApplicationRepository repository;
3034
private final UserRepository userRepository;
3135
private final RecruitCoreSessionResolver recruitCoreSessionResolver;
@@ -38,6 +42,7 @@ public RecruitCoreApplicantDetailResponse getApplicantDetail(Long id) {
3842

3943
@Transactional(readOnly = true)
4044
public RecruitCoreEligibilityResponse checkEligibility(Long userId) {
45+
validateRecruitmentOpen();
4146
String session = recruitCoreSessionResolver.currentSession();
4247
return repository.findByUserIdAndSession(userId, session)
4348
.map(app -> RecruitCoreEligibilityResponse.ineligible(session, "ALREADY_APPLIED", app.getId()))
@@ -46,6 +51,7 @@ public RecruitCoreEligibilityResponse checkEligibility(Long userId) {
4651

4752
@Transactional(readOnly = true)
4853
public RecruitCorePrefillResponse prefill(Long userId) {
54+
validateRecruitmentOpen();
4955
String session = recruitCoreSessionResolver.currentSession();
5056
repository.findByUserIdAndSession(userId, session)
5157
.ifPresent(existing -> {
@@ -58,6 +64,7 @@ public RecruitCorePrefillResponse prefill(Long userId) {
5864

5965
@Transactional
6066
public RecruitCoreApplicationCreateResponse submit(Long userId, RecruitCoreApplicationCreateRequest request) {
67+
validateRecruitmentOpen();
6168
String session = recruitCoreSessionResolver.currentSession();
6269
repository.findByUserIdAndSession(userId, session)
6370
.ifPresent(existing -> {
@@ -123,4 +130,10 @@ private User getUser(Long userId) {
123130
.orElseThrow(() -> new BusinessException(GlobalErrorCode.RESOURCE_NOT_FOUND));
124131
}
125132

133+
private void validateRecruitmentOpen() {
134+
if (Instant.now().isAfter(RECRUITMENT_DEADLINE)) {
135+
throw new RecruitCoreClosedException(RECRUITMENT_DEADLINE);
136+
}
137+
}
138+
126139
}

0 commit comments

Comments
 (0)