Skip to content

Commit 3c98cc7

Browse files
committed
feat: 면접 예약 API
1 parent 6b966e8 commit 3c98cc7

File tree

15 files changed

+121
-41
lines changed

15 files changed

+121
-41
lines changed

src/main/java/dmu/dasom/api/domain/applicant/repository/ApplicantRepository.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import dmu.dasom.api.domain.applicant.entity.Applicant;
44
import dmu.dasom.api.domain.applicant.enums.ApplicantStatus;
5+
import io.lettuce.core.dynamic.annotation.Param;
56
import org.springframework.data.domain.Page;
67
import org.springframework.data.domain.Pageable;
78
import org.springframework.data.jpa.repository.JpaRepository;
@@ -20,4 +21,8 @@ public interface ApplicantRepository extends JpaRepository<Applicant, Long> {
2021

2122
Optional<Applicant> findByStudentNo(final String studentNo);
2223

24+
@Query("SELECT a FROM Applicant a WHERE a.studentNo = :studentNo AND a.contact LIKE %:contactLastDigits")
25+
Optional<Applicant> findByStudentNoAndContactEndsWith(@Param("studentNo") String studentNo,
26+
@Param("contactLastDigits") String contactLastDigits);
27+
2328
}
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package dmu.dasom.api.domain.interview.dto;
22

3+
import jakarta.validation.constraints.NotNull;
4+
import jakarta.validation.constraints.Pattern;
35
import lombok.*;
46

57
@Getter
@@ -9,9 +11,10 @@
911
@Builder
1012
public class InterviewReservationRequestDto {
1113

14+
@NotNull(message = "슬롯 ID는 필수 값입니다.")
1215
private Long slotId; // 예약할 슬롯 ID
1316

14-
private Long applicantId; // 지원자 ID
15-
16-
private String reservationCode; // 학번 뒤 4자리 + 전화번호 뒤 4자리 조합 코드
17+
@NotNull(message = "예약 코드는 필수 값입니다.")
18+
@Pattern(regexp = "^[0-9]{8}[0-9]{4}$", message = "예약 코드는 학번 전체와 전화번호 뒤 4자리로 구성되어야 합니다.")
19+
private String reservationCode; // 학번 전체 + 전화번호 뒤 4자리 조합 코드
1720
}

src/main/java/dmu/dasom/api/domain/interview/dto/InterviewReservationResponseDto.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package dmu.dasom.api.domain.interview.dto;
22

3+
import jakarta.validation.constraints.NotNull;
34
import lombok.*;
45

56
@Getter
@@ -9,12 +10,16 @@
910
@Builder
1011
public class InterviewReservationResponseDto {
1112

13+
@NotNull(message = "예약 ID는 필수 값입니다.")
1214
private Long reservationId; // 예약 ID
1315

16+
@NotNull(message = "슬롯 ID는 필수 값입니다.")
1417
private Long slotId; // 슬롯 ID
1518

19+
@NotNull(message = "지원자 ID는 필수 값입니다.")
1620
private Long applicantId; // 지원자 ID
1721

22+
@NotNull(message = "예약 코드는 필수 값입니다.")
1823
private String reservationCode; // 예약 코드 (학번+전화번호 조합)
1924

2025
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package dmu.dasom.api.domain.interview.dto;
2+
3+
import jakarta.validation.constraints.NotNull;
4+
import lombok.*;
5+
6+
import java.time.LocalDate;
7+
import java.time.LocalTime;
8+
9+
@Getter
10+
@Setter
11+
@NoArgsConstructor
12+
@AllArgsConstructor
13+
@Builder
14+
public class InterviewSlotCreateRequestDto {
15+
16+
@NotNull(message = "시작 날짜는 필수 값입니다.")
17+
private LocalDate startDate; // 면접 시작 날짜
18+
19+
@NotNull(message = "종료 날짜는 필수 값입니다.")
20+
private LocalDate endDate; // 면접 종료 날짜
21+
22+
@NotNull(message = "시작 시간은 필수 값입니다.")
23+
private LocalTime startTime; // 하루의 시작 시간
24+
25+
@NotNull(message = "종료 시간은 필수 값입니다.")
26+
private LocalTime endTime; // 하루의 종료 시간
27+
}

src/main/java/dmu/dasom/api/domain/interview/dto/InterviewSlotRequestDto.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package dmu.dasom.api.domain.interview.dto;
22

3+
import jakarta.validation.constraints.Max;
4+
import jakarta.validation.constraints.Min;
5+
import jakarta.validation.constraints.NotNull;
36
import lombok.*;
47

58
import java.time.LocalDate;
@@ -12,11 +15,17 @@
1215
@Builder
1316
public class InterviewSlotRequestDto {
1417

18+
@NotNull(message = "면접 날짜는 필수 입력 값입니다.")
1519
private LocalDate interviewDate; // 면접 날짜
1620

21+
@NotNull(message = "시작 시간은 필수 입력 값입니다.")
1722
private LocalTime startTime; // 시작 시간
1823

24+
@NotNull(message = "종료 시간은 필수 입력 값입니다.")
1925
private LocalTime endTime; // 종료 시간
2026

27+
@NotNull(message = "최대 지원자 수는 필수 입력 값입니다.")
28+
@Min(value = 1, message = "최대 지원자 수는 최소 1명 이상이어야 합니다.")
29+
@Max(value = 100, message = "최대 지원자 수는 최대 100명까지 가능합니다.") // 필요에 따라 수정 가능
2130
private Integer maxCandidates; // 최대 지원자 수
2231
}

src/main/java/dmu/dasom/api/domain/interview/dto/InterviewSlotResponseDto.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package dmu.dasom.api.domain.interview.dto;
22

33
import dmu.dasom.api.domain.interview.entity.InterviewSlot;
4+
import jakarta.validation.constraints.Max;
5+
import jakarta.validation.constraints.Min;
6+
import jakarta.validation.constraints.NotNull;
47
import lombok.*;
58

69
import java.time.LocalDate;
@@ -13,11 +16,25 @@
1316
@Builder
1417
public class InterviewSlotResponseDto {
1518

19+
@NotNull(message = "슬롯 ID는 필수 입력 값입니다.")
1620
private Long id; // 슬롯 ID
21+
22+
@NotNull(message = "면접 날짜는 필수 입력 값입니다.")
1723
private LocalDate interviewDate; // 면접 날짜
24+
25+
@NotNull(message = "시작 시간은 필수 입력 값입니다.")
1826
private LocalTime startTime; // 시작 시간
27+
28+
@NotNull(message = "종료 시간은 필수 입력 값입니다.")
1929
private LocalTime endTime; // 종료 시간
30+
31+
@NotNull(message = "최대 지원자 수는 필수 입력 값입니다.")
32+
@Min(value = 1, message = "최대 지원자 수는 최소 1명 이상이어야 합니다.")
33+
@Max(value = 100, message = "최대 지원자 수는 최대 100명까지 가능합니다.")
2034
private Integer maxCandidates; // 최대 지원자 수
35+
36+
@NotNull(message = "현재 예약된 지원자 수는 필수 입력 값입니다.")
37+
@Min(value = 0, message = "현재 예약된 지원자 수는 0명 이상이어야 합니다.")
2138
private Integer currentCandidates; // 현재 예약된 지원자 수
2239

2340
public InterviewSlotResponseDto(InterviewSlot slot){

src/main/java/dmu/dasom/api/domain/interview/entity/InterviewReservation.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,6 @@ public class InterviewReservation {
2424
@JoinColumn(name = "applicant_id", nullable = false)
2525
private Applicant applicant; // 지원자
2626

27-
@Column(nullable = false, unique = true, length = 8)
28-
private String reservationCode; // 학번 뒤 4자리 + 전화번호 뒤 4자리 조합 코드
27+
@Column(nullable = false, unique = true, length = 12)
28+
private String reservationCode; // 학번 전체 + 전화번호 뒤 4자리 조합 코드
2929
}

src/main/java/dmu/dasom/api/domain/interview/entity/InterviewSlot.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package dmu.dasom.api.domain.interview.entity;
22

3-
import dmu.dasom.api.domain.interview.enums.Status;
3+
import dmu.dasom.api.domain.interview.enums.InterviewStatus;
44
import jakarta.persistence.*;
55
import lombok.*;
66

@@ -35,19 +35,19 @@ public class InterviewSlot {
3535

3636
@Enumerated(EnumType.STRING)
3737
@Column(nullable = false, length = 16)
38-
private Status status; // 면접 슬롯 상태 (ACTIVE, INACTIVE, CLOSED)
38+
private InterviewStatus interviewStatus; // 면접 슬롯 상태 (ACTIVE, INACTIVE, CLOSED)
3939

4040
public void incrementCurrentCandidates() {
4141
this.currentCandidates++;
4242
if (this.currentCandidates >= this.maxCandidates) {
43-
this.status = Status.CLOSED; // 최대 지원자 수에 도달하면 상태 변경
43+
this.interviewStatus = InterviewStatus.CLOSED; // 최대 지원자 수에 도달하면 상태 변경
4444
}
4545
}
4646

4747
public void decrementCurrentCandidates() {
4848
this.currentCandidates--;
49-
if (status == Status.CLOSED && this.currentCandidates < this.maxCandidates) {
50-
this.status = Status.ACTIVE; // 지원자 수가 줄어들면 다시 활성화
49+
if (interviewStatus == InterviewStatus.CLOSED && this.currentCandidates < this.maxCandidates) {
50+
this.interviewStatus = InterviewStatus.ACTIVE; // 지원자 수가 줄어들면 다시 활성화
5151
}
5252
}
5353

src/main/java/dmu/dasom/api/domain/interview/enums/Status.java renamed to src/main/java/dmu/dasom/api/domain/interview/enums/InterviewStatus.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package dmu.dasom.api.domain.interview.enums;
22

3-
public enum Status {
3+
public enum InterviewStatus {
44
ACTIVE, // 활성화된 슬롯
55
INACTIVE, // 비활성화된 슬롯
66
CLOSED // 예약 마감된 슬롯

src/main/java/dmu/dasom/api/domain/interview/repositoty/InterviewSlotRepository.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package dmu.dasom.api.domain.interview.repositoty;
22

33
import dmu.dasom.api.domain.interview.entity.InterviewSlot;
4-
import dmu.dasom.api.domain.interview.enums.Status;
4+
import dmu.dasom.api.domain.interview.enums.InterviewStatus;
55
import org.springframework.data.jpa.repository.JpaRepository;
66
import org.springframework.data.jpa.repository.Query;
77
import org.springframework.stereotype.Repository;
@@ -17,8 +17,8 @@ public interface InterviewSlotRepository extends JpaRepository<InterviewSlot, Lo
1717
Collection<InterviewSlot> findAllByCurrentCandidatesLessThanMaxCandidates();
1818

1919
// 상태에 따른 슬롯 조회
20-
@Query("SELECT s FROM InterviewSlot s WHERE s.status = :status AND s.currentCandidates < s.maxCandidates")
21-
List<InterviewSlot> findAllByStatusAndCurrentCandidatesLessThanMaxCandidates(Status status);
20+
@Query("SELECT s FROM InterviewSlot s WHERE s.interviewStatus = :status AND s.currentCandidates < s.maxCandidates")
21+
List<InterviewSlot> findAllByStatusAndCurrentCandidatesLessThanMaxCandidates(InterviewStatus interviewStatus);
2222

2323
// 슬롯이 하나라도 존재하는지 확인
2424
@Query("SELECT COUNT(s) > 0 FROM InterviewSlot s")

0 commit comments

Comments
 (0)