diff --git a/src/main/java/com/example/solidconnection/common/exception/ErrorCode.java b/src/main/java/com/example/solidconnection/common/exception/ErrorCode.java index fae3c4980..17661fe2d 100644 --- a/src/main/java/com/example/solidconnection/common/exception/ErrorCode.java +++ b/src/main/java/com/example/solidconnection/common/exception/ErrorCode.java @@ -118,6 +118,7 @@ public enum ErrorCode { CHANNEL_SEQUENCE_NOT_UNIQUE(HttpStatus.BAD_REQUEST.value(), "채널의 순서가 중복되었습니다."), CHANNEL_REGISTRATION_LIMIT_EXCEEDED(HttpStatus.BAD_REQUEST.value(), "등록 가능한 채널 수를 초과하였습니다."), ALREADY_MENTOR(HttpStatus.BAD_REQUEST.value(), "이미 멘토로 등록된 사용자입니다."), + ALREADY_EXIST_MENTORING(HttpStatus.BAD_REQUEST.value(), "이미 신청된 멘티, 멘토입니다."), MENTORING_NOT_FOUND(HttpStatus.NOT_FOUND.value(), "해당 멘토링 신청을 찾을 수 없습니다."), UNAUTHORIZED_MENTORING(HttpStatus.FORBIDDEN.value(), "멘토링 권한이 없습니다."), MENTORING_ALREADY_CONFIRMED(HttpStatus.BAD_REQUEST.value(), "이미 승인 또는 거절된 멘토링입니다."), diff --git a/src/main/java/com/example/solidconnection/mentor/domain/Mentoring.java b/src/main/java/com/example/solidconnection/mentor/domain/Mentoring.java index a839d8122..4dcae29bf 100644 --- a/src/main/java/com/example/solidconnection/mentor/domain/Mentoring.java +++ b/src/main/java/com/example/solidconnection/mentor/domain/Mentoring.java @@ -13,6 +13,8 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import jakarta.persistence.Table; +import jakarta.persistence.UniqueConstraint; import java.time.ZonedDateTime; import lombok.AccessLevel; import lombok.AllArgsConstructor; @@ -27,29 +29,35 @@ @DynamicInsert @AllArgsConstructor @NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table(name = "mentoring", uniqueConstraints = { + @UniqueConstraint( + name = "uk_mentoring_mentor_id_mentee_id", + columnNames = {"mentor_id", "mentee_id"} + ) +}) public class Mentoring extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Column + @Column(name="confirmed_at") private ZonedDateTime confirmedAt; - @Column + @Column(name = "checked_at_by_mentor") private ZonedDateTime checkedAtByMentor; - @Column + @Column(name = "checked_at_by_mentee") private ZonedDateTime checkedAtByMentee; - @Column(nullable = false) + @Column(nullable = false, name="verify_status") @Enumerated(EnumType.STRING) private VerifyStatus verifyStatus = VerifyStatus.PENDING; - @Column + @Column(name = "mentor_id") private long mentorId; - @Column + @Column(name = "mentee_id") private long menteeId; public Mentoring(long mentorId, long menteeId, VerifyStatus verifyStatus) { diff --git a/src/main/java/com/example/solidconnection/mentor/service/MentoringCommandService.java b/src/main/java/com/example/solidconnection/mentor/service/MentoringCommandService.java index 254323127..884526c1b 100644 --- a/src/main/java/com/example/solidconnection/mentor/service/MentoringCommandService.java +++ b/src/main/java/com/example/solidconnection/mentor/service/MentoringCommandService.java @@ -1,5 +1,6 @@ package com.example.solidconnection.mentor.service; +import static com.example.solidconnection.common.exception.ErrorCode.ALREADY_EXIST_MENTORING; import static com.example.solidconnection.common.exception.ErrorCode.MENTORING_ALREADY_CONFIRMED; import static com.example.solidconnection.common.exception.ErrorCode.MENTORING_NOT_FOUND; import static com.example.solidconnection.common.exception.ErrorCode.MENTOR_NOT_FOUND; @@ -30,8 +31,13 @@ public class MentoringCommandService { @Transactional public MentoringApplyResponse applyMentoring(long siteUserId, MentoringApplyRequest mentoringApplyRequest) { - Mentoring mentoring = new Mentoring(mentoringApplyRequest.mentorId(), siteUserId, VerifyStatus.PENDING); + long mentorId = mentoringApplyRequest.mentorId(); + + if (mentoringRepository.existsByMentorIdAndMenteeId(mentorId, siteUserId)) { + throw new CustomException(ALREADY_EXIST_MENTORING); + } + Mentoring mentoring = new Mentoring(mentoringApplyRequest.mentorId(), siteUserId, VerifyStatus.PENDING); return MentoringApplyResponse.from(mentoringRepository.save(mentoring)); } diff --git a/src/main/resources/db/migration/V37__add_unique_constraint_to_mentor_id_mentee_id.sql b/src/main/resources/db/migration/V37__add_unique_constraint_to_mentor_id_mentee_id.sql new file mode 100644 index 000000000..98968fbb1 --- /dev/null +++ b/src/main/resources/db/migration/V37__add_unique_constraint_to_mentor_id_mentee_id.sql @@ -0,0 +1,3 @@ +ALTER TABLE mentoring +ADD CONSTRAINT uk_mentoring_mentor_id_mentee_id +UNIQUE (mentor_id, mentee_id); diff --git a/src/test/java/com/example/solidconnection/mentor/service/MentoringCommandServiceTest.java b/src/test/java/com/example/solidconnection/mentor/service/MentoringCommandServiceTest.java index 8c6a78468..002dfa6a5 100644 --- a/src/test/java/com/example/solidconnection/mentor/service/MentoringCommandServiceTest.java +++ b/src/test/java/com/example/solidconnection/mentor/service/MentoringCommandServiceTest.java @@ -1,5 +1,6 @@ package com.example.solidconnection.mentor.service; +import static com.example.solidconnection.common.exception.ErrorCode.ALREADY_EXIST_MENTORING; import static com.example.solidconnection.common.exception.ErrorCode.MENTORING_ALREADY_CONFIRMED; import static com.example.solidconnection.common.exception.ErrorCode.MENTORING_NOT_FOUND; import static com.example.solidconnection.common.exception.ErrorCode.UNAUTHORIZED_MENTORING; @@ -96,6 +97,18 @@ class 멘토링_신청_테스트 { () -> assertThat(mentoring.getVerifyStatus()).isEqualTo(VerifyStatus.PENDING) ); } + + @Test + void 동일_멘티_멘토끼리는_재신청되지않는다() { + // given + mentoringFixture.대기중_멘토링(mentor1.getId(), menteeUser.getId()); + MentoringApplyRequest request = new MentoringApplyRequest(mentor1.getId()); + + // when & then + assertThatThrownBy(() -> mentoringCommandService.applyMentoring(menteeUser.getId(), request)) + .isInstanceOf(CustomException.class) + .hasMessage(ALREADY_EXIST_MENTORING.getMessage()); + } } @Nested