diff --git a/src/main/java/dmu/dasom/api/domain/applicant/dto/ApplicantCreateRequestDto.java b/src/main/java/dmu/dasom/api/domain/applicant/dto/ApplicantCreateRequestDto.java new file mode 100644 index 0000000..02fa342 --- /dev/null +++ b/src/main/java/dmu/dasom/api/domain/applicant/dto/ApplicantCreateRequestDto.java @@ -0,0 +1,61 @@ +package dmu.dasom.api.domain.applicant.dto; + +import dmu.dasom.api.domain.applicant.entity.Applicant; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.*; +import lombok.Getter; + +@Getter +@Schema(name = "ApplicantCreateRequestDto", description = "지원자 생성 요청 DTO") +public class ApplicantCreateRequestDto { + + @NotNull + @Pattern(regexp = "^[0-9]{8}$") + @Size(min = 8, max = 8) + @Schema(description = "학번", example = "20231234") + private String studentNo; + + @NotNull + @Pattern(regexp = "^\\d{3}-\\d{4}-\\d{4}$") + @Size(min = 13, max = 13) + @Schema(description = "연락처", example = "010-1234-5678") + private String contact; + + @Email + @NotNull + @Size(max = 64) + @Schema(description = "이메일 주소", example = "example@example.com") + private String email; + + @Min(value = 1) + @Max(value = 4) + @NotNull + @Schema(description = "학년", example = "3") + private Integer grade; + + @NotNull + @Size(max = 500) + @Schema(description = "지원 동기", example = "동아리 활동에 관심이 있어서 지원합니다.") + private String reasonForApply; + + @Size(max = 200) + @Schema(description = "활동 희망사항", example = "동아리 활동 참여") + private String activityWish; + + @NotNull + @Schema(description = "개인정보 처리방침 동의 여부", example = "true") + private Boolean isPrivacyPolicyAgreed; + + public Applicant toEntity() { + return Applicant.builder() + .studentNo(this.studentNo) + .contact(this.contact) + .email(this.email) + .grade(this.grade) + .reasonForApply(this.reasonForApply) + .activityWish(this.activityWish) + .isPrivacyPolicyAgreed(this.isPrivacyPolicyAgreed) + .build(); + } + +} diff --git a/src/main/java/dmu/dasom/api/domain/applicant/entity/Applicant.java b/src/main/java/dmu/dasom/api/domain/applicant/entity/Applicant.java new file mode 100644 index 0000000..7c31e43 --- /dev/null +++ b/src/main/java/dmu/dasom/api/domain/applicant/entity/Applicant.java @@ -0,0 +1,76 @@ +package dmu.dasom.api.domain.applicant.entity; + +import dmu.dasom.api.domain.applicant.enums.ApplicantStatus; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import java.time.LocalDateTime; + +@AllArgsConstructor +@Builder +@Entity +@EntityListeners(AuditingEntityListener.class) +@Getter +@NoArgsConstructor +public class Applicant { + + @Column(name = "id") + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Id + private Long id; + + @Column(name = "student_no", nullable = false, length = 8) + @Pattern(regexp = "^[0-9]{8}$") + @Size(min = 8, max = 8) + private String studentNo; + + @Column(name = "contact", nullable = false, length = 13) + @Pattern(regexp = "^\\d{3}-\\d{4}-\\d{4}$") + @Size(min = 13, max = 13) + private String contact; + + @Column(name = "email", nullable = false, length = 64) + @Email + @Size(max = 64) + private String email; + + @Column(name = "grade", nullable = false) + @Min(1) @Max(4) + private int grade; + + @Column(name = "reason_for_apply", nullable = false, length = 500) + @Size(max = 500) + private String reasonForApply; + + @Column(name = "activity_wish", nullable = true, length = 200) + @Size(max = 200) + private String activityWish; + + @Column(name = "is_privacy_policy_agreed", nullable = false) + private Boolean isPrivacyPolicyAgreed; + + @Builder.Default + @Column(name = "status", nullable = false, length = 16) + @Enumerated(EnumType.STRING) + private ApplicantStatus status = ApplicantStatus.PENDING; + + @CreatedDate + @Column(name = "created_at", nullable = false, updatable = false) + private LocalDateTime createdAt; + + @Column(name = "updated_at", nullable = false) + @LastModifiedDate + private LocalDateTime updatedAt; + + public void updateStatus(final ApplicantStatus status) { + this.status = status; + } + +} diff --git a/src/main/java/dmu/dasom/api/domain/applicant/enums/ApplicantStatus.java b/src/main/java/dmu/dasom/api/domain/applicant/enums/ApplicantStatus.java new file mode 100644 index 0000000..b0a1ae8 --- /dev/null +++ b/src/main/java/dmu/dasom/api/domain/applicant/enums/ApplicantStatus.java @@ -0,0 +1,9 @@ +package dmu.dasom.api.domain.applicant.enums; + +public enum ApplicantStatus { + PENDING, // 초기 상태 + DOCUMENT_FAILED, // 서류 심사 불합격 + DOCUMENT_PASSED, // 서류 심사 합격 + INTERVIEW_FAILED, // 면접 불합격 + INTERVIEW_PASSED // 면접 합격 +} diff --git a/src/main/java/dmu/dasom/api/domain/applicant/repository/ApplicantRepository.java b/src/main/java/dmu/dasom/api/domain/applicant/repository/ApplicantRepository.java new file mode 100644 index 0000000..de6b1e8 --- /dev/null +++ b/src/main/java/dmu/dasom/api/domain/applicant/repository/ApplicantRepository.java @@ -0,0 +1,7 @@ +package dmu.dasom.api.domain.applicant.repository; + +import dmu.dasom.api.domain.applicant.entity.Applicant; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ApplicantRepository extends JpaRepository { +} diff --git a/src/main/java/dmu/dasom/api/domain/applicant/service/ApplicantService.java b/src/main/java/dmu/dasom/api/domain/applicant/service/ApplicantService.java new file mode 100644 index 0000000..2e0da88 --- /dev/null +++ b/src/main/java/dmu/dasom/api/domain/applicant/service/ApplicantService.java @@ -0,0 +1,9 @@ +package dmu.dasom.api.domain.applicant.service; + +import dmu.dasom.api.domain.applicant.dto.ApplicantCreateRequestDto; + +public interface ApplicantService { + + void apply(final ApplicantCreateRequestDto request); + +} diff --git a/src/main/java/dmu/dasom/api/domain/applicant/service/ApplicantServiceImpl.java b/src/main/java/dmu/dasom/api/domain/applicant/service/ApplicantServiceImpl.java new file mode 100644 index 0000000..0792fba --- /dev/null +++ b/src/main/java/dmu/dasom/api/domain/applicant/service/ApplicantServiceImpl.java @@ -0,0 +1,20 @@ +package dmu.dasom.api.domain.applicant.service; + +import dmu.dasom.api.domain.applicant.dto.ApplicantCreateRequestDto; +import dmu.dasom.api.domain.applicant.repository.ApplicantRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@RequiredArgsConstructor +@Service +public class ApplicantServiceImpl implements ApplicantService { + + private final ApplicantRepository applicantRepository; + + // 지원자 저장 + @Override + public void apply(final ApplicantCreateRequestDto request) { + applicantRepository.save(request.toEntity()); + } + +} diff --git a/src/main/java/dmu/dasom/api/domain/common/exception/CustomControllerAdvice.java b/src/main/java/dmu/dasom/api/domain/common/exception/CustomControllerAdvice.java index 4864a58..1b753a0 100644 --- a/src/main/java/dmu/dasom/api/domain/common/exception/CustomControllerAdvice.java +++ b/src/main/java/dmu/dasom/api/domain/common/exception/CustomControllerAdvice.java @@ -1,5 +1,6 @@ package dmu.dasom.api.domain.common.exception; +import jakarta.validation.ConstraintViolationException; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.MethodArgumentNotValidException; @@ -19,4 +20,9 @@ public ResponseEntity methodArgumentNotValidException(final Metho return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ErrorResponse(ErrorCode.ARGUMENT_NOT_VALID)); } + @ExceptionHandler(ConstraintViolationException.class) + public ResponseEntity constraintViolationException(final ConstraintViolationException e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ErrorResponse(ErrorCode.ARGUMENT_NOT_VALID)); + } + }