Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[YS-256] feat: 회원가입 연락 받을 이메일 중복 비허용 로직 추가 #80

Merged
merged 11 commits into from
Feb 6, 2025

Conversation

chock-cho
Copy link
Member

@chock-cho chock-cho commented Feb 4, 2025

💡 작업 내용

  • 변경된 기획안에 따라, 회원가입 시에 연락받을 이메일 (contactEmail)에 대한 중복을 비허용하는 로직을 구현했습니다.
  • 프론트와 협의 하에 API를 추가로 개설(/signup/validate/contact-email) 했습니다.

✅ 셀프 체크리스트

  • PR 제목을 형식에 맞게 작성했나요?
  • 브랜치 전략에 맞는 브랜치에 PR을 올리고 있나요?
  • 테스트는 잘 통과했나요?
  • 빌드에 성공했나요?
  • 본인을 assign 해주세요.
  • 해당 PR에 맞는 label을 붙여주세요.

🙋🏻‍ 확인해주세요

  • 관련된 Discussion 등이 있다면 첨부해주세요

case 1) 가입 가능한 이메일일 때 - 200 OK


case 2) 이미 가입하여 불가능한 이메일일 때 - 403 CONFLICT

🔗 Jira 티켓


https://yappsocks.atlassian.net/browse/YS-256

Summary by CodeRabbit

Summary by CodeRabbit

  • 신규 기능
    • 회원가입 시 이메일 중복 여부를 실시간으로 확인할 수 있는 기능이 추가되었습니다.
    • 이메일 형식 검증을 위한 새로운 요청 데이터 클래스가 도입되었습니다.
    • 이메일 중복 확인을 위한 API 엔드포인트가 추가되었습니다.
    • 이메일 중복 검증 프로세스를 지원하는 매퍼 기능이 추가되었습니다.
  • 버그 수정
    • 이메일 중복 시 명확한 예외 처리가 추가되었습니다.
  • 변경 사항
    • 데이터베이스에서 이메일 필드의 고유성 제약 조건이 추가되었습니다.

🔗 Jira 티켓


https://yappsocks.atlassian.net/browse/YS-256

@chock-cho chock-cho added ✅ TEST 테스트 코드 추가 ✨ FEATURE 기능 추가 labels Feb 4, 2025
@chock-cho chock-cho self-assigned this Feb 4, 2025
@chock-cho chock-cho requested a review from Ji-soo708 February 4, 2025 16:52
Copy link

coderabbitai bot commented Feb 4, 2025

Walkthrough

이 PR은 회원 서비스에 중복 이메일 검증 기능을 추가합니다. 새로운 VerifyContactEmailUseCase 클래스가 도입되어 입력받은 이메일을 검증하고, 존재하는 경우 ContactEmailDuplicateException 예외를 발생시킵니다. MemberServicevalidateDuplicatedContactEmail 메소드가 추가되어 이를 이용하며, 관련 인터페이스 및 데이터베이스 레이어에서 이메일 조회 메소드가 확장되었습니다. 또한, 새로운 API 엔드포인트와 DTO, 매퍼 함수가 추가되어 이메일 검증 요청을 처리하며, 이를 검증하는 단위 테스트 또한 포함되어 있습니다.

Changes

File(s) Change Summary
src/main/kotlin/com/dobby/backend/application/service/MemberService.kt verifyContactEmailUseCase 의존성 주입 및 validateDuplicatedContactEmail 메소드 추가
src/main/kotlin/com/dobby/backend/application/usecase/member/VerifyContactEmailUseCase.kt 새 클래스 도입, 이메일 검증을 위한 Input, Output 데이터 클래스와 execute 메소드 구현 (회원 조회 및 예외 처리 포함)
src/main/kotlin/com/dobby/backend/domain/exception/DobbyException.kt ContactEmailDuplicateException 예외 객체 추가 (코드: "ME0007", 메시지 및 HTTP 상태 설정)
src/main/kotlin/com/dobby/backend/domain/gateway/member/MemberGateway.kt,
src/main/kotlin/com/dobby/backend/infrastructure/database/repository/MemberRepository.kt,
src/main/kotlin/com/dobby/backend/infrastructure/gateway/member/MemberGatewayImpl.kt
existsByContactEmail 메소드 추가: 도메인, 데이터베이스 레포지토리, 구현체에 이메일 조회 기능 확장
src/main/kotlin/com/dobby/backend/presentation/api/controller/MemberController.kt 새 엔드포인트 emailAvailableCheck 추가, 이메일 검증 요청 처리 및 응답 매핑, 관련 import 문 업데이트
src/main/kotlin/com/dobby/backend/presentation/api/dto/request/member/ContactEmailVerificationRequest.kt,
src/main/kotlin/com/dobby/backend/presentation/api/mapper/MemberMapper.kt
ContactEmailVerificationRequest DTO와 매퍼 함수(toContactEmailVerificationInput, toContactEmailVerificationResponse) 추가하여 이메일 검증 요청/응답 변환 지원
src/test/kotlin/com/dobby/backend/application/usecase/member/VerifyContactEmailUseCaseTest.kt 새로운 유닛 테스트 클래스 추가, 존재하지 않는 이메일과 중복 이메일 시나리오 테스트

Suggested reviewers

  • Ji-soo708

Poem

나는 토끼, 코드 숲을 누비며
이메일 중복 검증, 척척 해결하네
Service와 UseCase, 깔끔히 연결되어
Exception이 날리면, 실패도 확인해
🐇 점프하며 축하해, 변화의 승리를!

Tip

🌐 Web search-backed reviews and chat
  • We have enabled web search-based reviews and chat for all users. This feature allows CodeRabbit to access the latest documentation and information on the web.
  • You can disable this feature by setting web_search: false in the knowledge_base settings.
  • Please share any feedback in the Discord discussion.

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 796b069 and 09c9ea3.

📒 Files selected for processing (1)
  • src/main/kotlin/com/dobby/backend/infrastructure/database/entity/member/MemberEntity.kt (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build
🔇 Additional comments (1)
src/main/kotlin/com/dobby/backend/infrastructure/database/entity/member/MemberEntity.kt (1)

33-34: contactEmail 필드에 유니크 제약 조건 추가 승인

contactEmail 필드에 유니크 제약 조건을 추가하는 것은 회원가입 시 연락 이메일 중복을 방지하는 요구사항에 부합합니다.

데이터베이스 마이그레이션 고려사항

유니크 제약 조건 추가는 데이터베이스 스키마 변경을 수반합니다. 다음 사항들을 확인해 주세요:

  1. 기존 데이터베이스에 중복된 contact_email 값이 있는지 확인
  2. 마이그레이션 스크립트 준비
  3. 롤백 계획 수립

다음 스크립트를 실행하여 중복된 contact_email 값이 있는지 확인해 주세요:


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (8)
src/main/kotlin/com/dobby/backend/infrastructure/database/repository/MemberRepository.kt (1)

9-9: 성능 최적화를 위한 인덱스 추가를 검토해주세요.

contactEmail 컬럼에 대한 조회가 자주 발생할 것으로 예상되므로, 해당 컬럼에 인덱스를 추가하는 것이 좋을 것 같습니다. 또한 동시성 제어를 위해 @Lock(LockModeType.PESSIMISTIC_WRITE) 어노테이션 추가도 고려해주세요.

src/main/kotlin/com/dobby/backend/application/usecase/member/VerifyContactEmailUseCase.kt (2)

18-21: 에러 처리와 로깅을 보강해주세요.

  1. 디버깅과 모니터링을 위한 로깅 추가가 필요합니다.
  2. 예외 발생 시 중복된 이메일 값을 포함하면 디버깅에 도움이 될 것 같습니다.
 override fun execute(input: Input): Output {
-    if(memberGateway.findByContactEmail(input.contactEmail) == null) return Output(success = true)
-    else throw SignupContactEmailDuplicateException
+    logger.debug("Verifying contact email: ${input.contactEmail}")
+    val existingMember = memberGateway.findByContactEmail(input.contactEmail)
+    
+    return if (existingMember == null) {
+        logger.debug("Email verification successful: ${input.contactEmail}")
+        Output(success = true)
+    } else {
+        logger.debug("Duplicate email found: ${input.contactEmail}")
+        throw SignupContactEmailDuplicateException.withEmail(input.contactEmail)
+    }
 }

7-9: 클래스 레벨 로거 선언을 추가해주세요.

+import org.slf4j.LoggerFactory
+
 class VerifyContactEmailUseCase(
     private val memberGateway: MemberGateway
-): UseCase<VerifyContactEmailUseCase.Input, VerifyContactEmailUseCase.Output> {
+): UseCase<VerifyContactEmailUseCase.Input, VerifyContactEmailUseCase.Output> {
+    private val logger = LoggerFactory.getLogger(javaClass)
src/test/kotlin/com/dobby/backend/application/usecase/member/VerifyContactEmailUseCaseTest.kt (1)

11-41: 테스트 케이스 보완 제안

현재 구현된 테스트는 기본적인 성공/실패 케이스를 잘 커버하고 있습니다. 다음과 같은 추가 테스트 케이스 구현을 고려해보시기 바랍니다:

  • 잘못된 이메일 형식 검증
  • 공백이나 null 값 처리
  • 대소문자 구분 여부 검증
src/main/kotlin/com/dobby/backend/application/service/MemberService.kt (1)

36-39: 트랜잭션 설정 최적화 필요

이메일 중복 확인은 읽기 전용 작업이므로, 현재 설정된 트랜잭션 어노테이션을 최적화할 수 있습니다.

다음과 같이 수정하는 것을 추천드립니다:

-    @Transactional
+    @Transactional(readOnly = true)
     fun validateDuplicatedContactEmail(input: VerifyContactEmailUseCase.Input) : VerifyContactEmailUseCase.Output{
         return verifyContactEmailUseCase.execute(input)
     }
src/main/kotlin/com/dobby/backend/presentation/api/controller/MemberController.kt (1)

51-62: HTTP 상태 코드 개선 필요

이메일 검증 API의 응답이 더 명확한 HTTP 상태 코드를 사용할 수 있습니다:

  • 이메일 사용 가능: 200 OK
  • 이메일 중복: 409 Conflict (현재 403 대신)

또한 API 응답 형식을 더 구체적으로 정의하여 DefaultResponse 대신 전용 응답 클래스를 사용하는 것을 고려해보세요.

src/main/kotlin/com/dobby/backend/presentation/api/mapper/MemberMapper.kt (2)

7-7: 와일드카드 임포트 사용 검토 필요

와일드카드 임포트(.*)를 사용하면 코드의 명확성이 떨어질 수 있습니다. 특히 여러 패키지에서 동일한 이름의 클래스를 사용할 경우 혼란을 야기할 수 있습니다. 명시적인 임포트 사용을 고려해 주세요.


61-71: 이메일 검증 매핑 구현이 잘 되었습니다!

새로 추가된 이메일 검증 매핑 함수들이 기존 코드 스타일을 잘 따르고 있으며, 간단하고 명확하게 구현되었습니다.

다만, 다음과 같은 개선사항을 고려해보시면 좋을 것 같습니다:

  1. DefaultResponse의 success 필드만 사용하는 것이 충분한지 검토가 필요합니다.
  2. 실패 케이스에 대한 추가 정보를 제공하는 것이 사용자 경험 향상에 도움이 될 수 있습니다.
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1bcfe61 and 5877588.

📒 Files selected for processing (10)
  • src/main/kotlin/com/dobby/backend/application/service/MemberService.kt (2 hunks)
  • src/main/kotlin/com/dobby/backend/application/usecase/member/VerifyContactEmailUseCase.kt (1 hunks)
  • src/main/kotlin/com/dobby/backend/domain/exception/DobbyException.kt (1 hunks)
  • src/main/kotlin/com/dobby/backend/domain/gateway/member/MemberGateway.kt (1 hunks)
  • src/main/kotlin/com/dobby/backend/infrastructure/database/repository/MemberRepository.kt (1 hunks)
  • src/main/kotlin/com/dobby/backend/infrastructure/gateway/member/MemberGatewayImpl.kt (1 hunks)
  • src/main/kotlin/com/dobby/backend/presentation/api/controller/MemberController.kt (2 hunks)
  • src/main/kotlin/com/dobby/backend/presentation/api/dto/request/member/ContactEmailVerificationRequest.kt (1 hunks)
  • src/main/kotlin/com/dobby/backend/presentation/api/mapper/MemberMapper.kt (2 hunks)
  • src/test/kotlin/com/dobby/backend/application/usecase/member/VerifyContactEmailUseCaseTest.kt (1 hunks)
🧰 Additional context used
📓 Learnings (1)
src/main/kotlin/com/dobby/backend/application/usecase/member/VerifyContactEmailUseCase.kt (2)
Learnt from: chock-cho
PR: YAPP-Github/25th-Web-Team-2-BE#67
File: src/main/kotlin/com/dobby/backend/application/usecase/member/email/EmailCodeSendUseCase.kt:44-56
Timestamp: 2025-01-29T16:14:08.389Z
Learning: The VerificationRepository in this codebase implements a robust concurrency control mechanism with:
1. Pessimistic write locking (@Lock(LockModeType.PESSIMISTIC_WRITE)) on findByUnivEmail
2. Proper transaction boundaries using @Modifying annotations
3. Automatic timestamp updates in native queries for code updates
Learnt from: chock-cho
PR: YAPP-Github/25th-Web-Team-2-BE#67
File: src/main/kotlin/com/dobby/backend/application/usecase/member/email/EmailCodeSendUseCase.kt:44-56
Timestamp: 2025-01-29T16:14:08.389Z
Learning: The email verification system in this codebase uses pessimistic locking (@Lock(LockModeType.PESSIMISTIC_WRITE)) on findByUnivEmail method to handle concurrent verification requests.
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build
🔇 Additional comments (2)
src/main/kotlin/com/dobby/backend/presentation/api/dto/request/member/ContactEmailVerificationRequest.kt (1)

7-12: 적절한 유효성 검사와 문서화가 구현되었습니다!

이메일 형식 검증과 필수값 검사가 잘 구현되어 있으며, 한글 에러 메시지도 명확합니다.

src/main/kotlin/com/dobby/backend/domain/gateway/member/MemberGateway.kt (1)

9-9: 동시성 제어 메커니즘 추가 검토가 필요합니다.

이전 이메일 검증 구현에서 사용된 @Lock(LockModeType.PESSIMISTIC_WRITE) 메커니즘을 이 메소드에도 적용하는 것이 좋을 것 같습니다. 동시에 여러 사용자가 같은 이메일로 가입을 시도할 경우를 대비하여 동시성 제어가 필요합니다.

Copy link
Member

@Ji-soo708 Ji-soo708 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

비즈니스 규칙이 변경되어 이메일 중복 검증 로직이 추가되었네요! 👍
기능적으로는 잘 구현해주셨는데 조금 개선하면 좋은 점들이 있어서 코멘트 남겼습니다. 확인해주시면 감사합니다. 고생하셨어요~

Comment on lines 19 to 20
if(memberGateway.findByContactEmail(input.contactEmail) == null) return Output(success = true)
else throw SignupContactEmailDuplicateException
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Member 엔티티를 반환하는 findBy 보다는 Boolean 값을 반환하는 exists를 이용해 필요한 데이터만 가져오는 건 어떨까요?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

음, 제가 exists가 아니라 findBy 로 조회한 이유는 해당 부분이 지난 PR에서 매칭 공고 이메일 전송 시 멤버 이름을 조회하는 로직 에 활용하기 위해서 통합적으로 해당 메서드를 활용한 것이었는데요. (memberName을 가져올 때 findBy 메서드로 가져올 수 있게 하기 위해서)
오늘 올리신 PR 보니까 '참여자 수정' 에서의 중복 이메일 검증 로직에서 이미 exists 메서드를 이용하신 걸로 확인했습니다. 그래서 그거랑 통합해도 될 것 같네요!

Copy link
Member

@Ji-soo708 Ji-soo708 Feb 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아하, 제가 생각하기에는 해당 유즈케이스에서는 중복된 이메일이 존재하는지만 확인하면 되므로, Member 엔티티를 조회하는 findBy보다 existsBy를 사용하여 최소한의 연산만 수행하도록 최적화 가능할 거라 기대해 코멘트를 남겼습니다!

@@ -51,7 +51,7 @@ data object ResearcherNotFoundException : ClientException("ME0003", "Researcher
data object ParticipantNotFoundException : ClientException("ME0004", "Participant Not Found.", HttpStatus.NOT_FOUND)
data object EmailNotValidateException : ClientException("ME0005", "You should validate your school email first", HttpStatus.BAD_REQUEST)
data object SignupOauthEmailDuplicateException : ClientException("ME0006", "You've already joined with requested oauth email", HttpStatus.CONFLICT)

data object SignupContactEmailDuplicateException: ClientException("ME0007", "You've already joined with requested contact email", HttpStatus.CONFLICT)
Copy link
Member

@Ji-soo708 Ji-soo708 Feb 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 예외는 회원가입 뿐만 아니라 회원 정보 수정 시에도 필요합니다. 그래서 조금 더 범용적으로 아래처럼 통일하는 건 어떨까요??

data object ContactEmailDuplicateException: ClientException("ME0007", "This contact email is already in use.", HttpStatus.CONFLICT)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

넵 반영하겠습니다 :D

Comment on lines 51 to 53
@PostMapping("/signup/validate/contact-email")
@Operation(
summary = "연락 받을 이메일 주소 검증 API - 회원가입 시 필수 API",
Copy link
Member

@Ji-soo708 Ji-soo708 Feb 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 API는 회원 정보를 수정할 때도 사용할 거 같습니다. 그래서 API URI를 /validate/contact-email 로 변경하는 방향은 어떨까요?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

회원가입 시 중복 이메일 검증 부분과 참여자 회원정보 수정은 필터 검증 부분에서 헤더의 액세스 토큰의 유무가 달라질 것같은데, 인증을 어떻게 처리해야 할까요? 필터단에서 건드리면 api 하나로 통합할 수 있을 것 같은데, 지수님께서 생각하신 방향성이 이게 맞을까요??🙋‍♀️

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

중복 이메일 검증 API를 OAuth 로그인처럼 아예 인증없이 사용할 수 있게 처리하면 된다고 생각하는데 어떻게 생각하실까요?
프론트에서 해당 API를 회원정보 수정 기능에서 활용할 때 단순히 이메일 검증 용도로 사용할 테니 저희 서비스 회원인지 토큰으로 검증하는 부분은 생략해도 좋을 거 같아요!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

생각해보니 회원정보 수정 기능에서 검증할 때는 본인 이메일에 대해서는 검증 범위에 빼야하네요... 이걸 하나의 API로 처리할지 두 개의 API로 처리할지는 서버 회의때 얘기해봅시다!

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오늘 서버 회의를 통해 두 개의 API로 분리하기로 결정했습니다~

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@chock-cho 수정님 혹시 email을 리퀘스트 바디로 받는 것보다 파라미터로 받고 Get 요청으로 처리하는 건 어떨까요? email 하나에 대해 검증만 수행하는 API라 파라미터로 처리해도 좋을 거 같아서요!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

와우 그렇네요!!. 검증 로직은 어차피 조회하는 로직밖에 없기 때문에 POST보다 GET 요청이 좋겠군요. 쿼리 파라미터+GET으로 수정하겠습니다:)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
src/main/kotlin/com/dobby/backend/presentation/api/controller/MemberController.kt (1)

51-62: API 구현이 잘 되었습니다!

이전 리뷰 논의사항들이 모두 반영되어 있습니다:

  • GET 메소드 사용
  • 쿼리 파라미터로 이메일 전달
  • 인증 없이 호출 가능

API 문서화를 조금 더 개선하면 좋을 것 같습니다. description에 다음 내용을 추가하는 것은 어떨까요?:

-        description = "연락 받을 이메일이 사용 가능한지 검증해주는 API입니다. 사용가능하면 true, 아니면 예외를 던집니다."
+        description = """
+            연락 받을 이메일이 사용 가능한지 검증해주는 API입니다. 사용가능하면 true, 아니면 예외를 던집니다.
+            - 성공 응답: 200 OK (이메일 사용 가능)
+            - 실패 응답: 403 CONFLICT (이미 사용 중인 이메일)
+            """
src/test/kotlin/com/dobby/backend/application/usecase/member/VerifyContactEmailUseCaseTest.kt (3)

11-15: 클래스 레벨 KDoc 문서화를 추가하면 좋을 것 같습니다.

테스트 클래스의 목적과 책임을 명확히 하기 위해 KDoc 문서를 추가하는 것이 좋습니다.

다음과 같이 문서화를 추가해보세요:

+/**
+ * 회원가입 시 연락 받을 이메일 중복 검증 유스케이스 테스트
+ *
+ * @see VerifyContactEmailUseCase
+ */
 class VerifyContactEmailUseCaseTest : BehaviorSpec({

16-28: 이메일 유효성 검증 테스트 케이스를 추가하면 좋을 것 같습니다.

현재 테스트는 기본적인 시나리오만 다루고 있습니다. 다음과 같은 엣지 케이스들도 고려해보시면 좋을 것 같습니다:

  • 잘못된 이메일 형식
  • 빈 문자열
  • 최대 길이 초과

29-41: 예외 메시지 검증을 추가하면 좋을 것 같습니다.

예외가 발생하는 것을 확인하는 것 외에도, 적절한 에러 메시지가 포함되어 있는지 검증하면 좋을 것 같습니다.

다음과 같이 수정해보세요:

 then("ContactEmailDuplication 예외가 발생해야 한다") {
-    shouldThrow<ContactEmailDuplicateException> {
+    val exception = shouldThrow<ContactEmailDuplicateException> {
         verifyContactEmailUseCase.execute(input)
     }
+    exception.message shouldBe "이미 등록된 이메일입니다: ${input.contactEmail}"
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b7b180a and 796b069.

📒 Files selected for processing (8)
  • src/main/kotlin/com/dobby/backend/application/usecase/member/VerifyContactEmailUseCase.kt (1 hunks)
  • src/main/kotlin/com/dobby/backend/domain/exception/DobbyException.kt (1 hunks)
  • src/main/kotlin/com/dobby/backend/domain/gateway/member/MemberGateway.kt (1 hunks)
  • src/main/kotlin/com/dobby/backend/infrastructure/database/repository/MemberRepository.kt (1 hunks)
  • src/main/kotlin/com/dobby/backend/infrastructure/gateway/member/MemberGatewayImpl.kt (1 hunks)
  • src/main/kotlin/com/dobby/backend/presentation/api/controller/MemberController.kt (2 hunks)
  • src/main/kotlin/com/dobby/backend/presentation/api/mapper/MemberMapper.kt (2 hunks)
  • src/test/kotlin/com/dobby/backend/application/usecase/member/VerifyContactEmailUseCaseTest.kt (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/main/kotlin/com/dobby/backend/infrastructure/database/repository/MemberRepository.kt
  • src/main/kotlin/com/dobby/backend/domain/exception/DobbyException.kt
  • src/main/kotlin/com/dobby/backend/domain/gateway/member/MemberGateway.kt
  • src/main/kotlin/com/dobby/backend/presentation/api/mapper/MemberMapper.kt
  • src/main/kotlin/com/dobby/backend/application/usecase/member/VerifyContactEmailUseCase.kt
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build
🔇 Additional comments (3)
src/main/kotlin/com/dobby/backend/infrastructure/gateway/member/MemberGatewayImpl.kt (1)

27-29: 구현이 깔끔하고 목적에 부합합니다!

existsByContactEmail 메서드가 회원가입 시 연락 이메일 중복 검증이라는 요구사항을 잘 구현하고 있습니다. 구현이 간단명료하고 기존 코드 스타일을 잘 따르고 있습니다.

src/main/kotlin/com/dobby/backend/presentation/api/controller/MemberController.kt (1)

4-5: 임포트 변경이 적절해 보입니다!

member 관련 DTO들을 와일드카드로 임포트하는 것이 코드를 더 간결하게 만들어줍니다.

src/test/kotlin/com/dobby/backend/application/usecase/member/VerifyContactEmailUseCaseTest.kt (1)

1-10: 패키지 구조와 임포트가 잘 구성되어 있습니다!

테스트에 필요한 모든 의존성이 적절하게 임포트되어 있으며, 패키지 구조도 도메인 계층을 잘 반영하고 있습니다.

@chock-cho chock-cho requested a review from Ji-soo708 February 5, 2025 13:30
Copy link
Member

@Ji-soo708 Ji-soo708 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 리뷰 반영 잘해주셔서 approve합니다. 코멘트도 남겼으니 확인해주시면 감사해요~ 고생하셨습니다!

@@ -51,7 +51,7 @@ data object ResearcherNotFoundException : ClientException("ME0003", "Researcher
data object ParticipantNotFoundException : ClientException("ME0004", "Participant Not Found.", HttpStatus.NOT_FOUND)
data object EmailNotValidateException : ClientException("ME0005", "You should validate your school email first", HttpStatus.BAD_REQUEST)
data object SignupOauthEmailDuplicateException : ClientException("ME0006", "You've already joined with requested oauth email", HttpStatus.CONFLICT)

data object ContactEmailDuplicateException: ClientException("ME0007", "This contact email is already in use", HttpStatus.CONFLICT)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저번 PR에서랑 이번 PR에서 추가된 예외들은 노션에 있는 예외 코드 정리에 업데이트 해주시면 감사합니다~

Comment on lines +56 to +57
fun emailAvailableCheck(
@RequestParam contactEmail: String
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

validateContactEmailForSignUp 이라는 함수명으로 변경하는 것은 어떨까요? 추후에 회원정보 수정을 위한 API도 추가해야 해서 함수명으로 구분이 가능하면 좋을 거 같아요!

@chock-cho chock-cho merged commit 2a8c19c into dev Feb 6, 2025
3 checks passed
@chock-cho chock-cho deleted the feat/YS-256 branch February 6, 2025 13:12
Ji-soo708 pushed a commit that referenced this pull request Feb 7, 2025
* feat: implement gateway to add duplicate signup verification

- 회원가입 시 연락 이메일 중복 가입 방지를 위한 조회 구현

* feat: define contactEmailVerificationRequest dto

* feat: define application level and exception

* feat: define presentation level(controller, mapper)

* test: add test codes for VerifyContactEmailUseCase

* refact: rename appropriate parameter naming

* refact: rename appropriate exception message to meet the convention

* refact: convert find method to exists method for optimization

* fix: fix test codes to reflect updation

* fix: convert PostMapping to GetMapping

* fix: add unique constraint in field value to prevent race condition
Ji-soo708 pushed a commit that referenced this pull request Feb 7, 2025
* feat: implement gateway to add duplicate signup verification

- 회원가입 시 연락 이메일 중복 가입 방지를 위한 조회 구현

* feat: define contactEmailVerificationRequest dto

* feat: define application level and exception

* feat: define presentation level(controller, mapper)

* test: add test codes for VerifyContactEmailUseCase

* refact: rename appropriate parameter naming

* refact: rename appropriate exception message to meet the convention

* refact: convert find method to exists method for optimization

* fix: fix test codes to reflect updation

* fix: convert PostMapping to GetMapping

* fix: add unique constraint in field value to prevent race condition
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
✨ FEATURE 기능 추가 ✅ TEST 테스트 코드 추가
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants