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

✨ SMS 인증 API 구현 #19

Merged
merged 5 commits into from
Oct 2, 2024
Merged

✨ SMS 인증 API 구현 #19

merged 5 commits into from
Oct 2, 2024

Conversation

waterfogSW
Copy link
Member

@waterfogSW waterfogSW commented Oct 2, 2024

Summary by CodeRabbit

  • 새로운 기능

    • 전화번호 기반으로 사용자를 검색할 수 있는 기능 추가.
    • 인증 코드 발송 시 신규 사용자와 기존 사용자를 구분하여 결과를 반환하는 기능 개선.
    • 인증 코드 요청 시 새로운 요청 형식으로 변경.
  • 버그 수정

    • 인증 코드 생성 및 검증 로직 개선.
  • 문서화

    • 데이터베이스 스키마에 전화번호의 고유성 제약 조건 추가.
  • 테스트

    • 사용자 등록 및 인증 코드 생성에 대한 테스트 케이스 업데이트.

Copy link

coderabbitai bot commented Oct 2, 2024

Walkthrough

이 변경 사항은 SendAuthCode 인터페이스 및 관련 서비스와 클래스의 반환 유형과 데이터 구조를 수정하여 인증 코드 전송 및 사용자 관리 기능을 개선합니다. SendAuthCodeinvoke 메서드는 이제 Result 타입을 반환하며, Command 데이터 클래스의 phoneNumber 속성은 String에서 PhoneNumber로 변경되었습니다. 또한, 새로운 Result 클래스가 도입되어 사용자 유형에 따라 결과를 구분할 수 있게 되었습니다.

Changes

파일 경로 변경 요약
application/src/main/kotlin/com/threedays/application/auth/port/inbound/SendAuthCode.kt invoke 메서드의 반환 타입을 AuthCode에서 Result로 변경, CommandphoneNumber 속성을 String에서 PhoneNumber로 수정, 새로운 sealed class Result 추가
application/src/main/kotlin/com/threedays/application/auth/service/AuthCodeService.kt invoke 메서드의 반환 타입을 AuthCode에서 SendAuthCode.Result로 변경, UserRepository 의존성 추가
application/src/test/kotlin/com/threedays/application/auth/service/AuthCodeServiceTest.kt 테스트 케이스 수정, UserRepositorySpy 추가, PhoneNumber 객체 사용으로 변경
domain/src/main/kotlin/com/threedays/domain/auth/entity/AuthCode.kt create 메서드의 phoneNumber 파라미터 타입을 String에서 PhoneNumber로 변경
domain/src/main/kotlin/com/threedays/domain/user/repository/UserRepository.kt findByPhoneNumber(phoneNumber: PhoneNumber): User? 메서드 추가
infrastructure/persistence/src/main/kotlin/com/threedays/persistence/user/adapter/UserPersistenceAdapter.kt findByPhoneNumber(phoneNumber: PhoneNumber): User? 메서드 추가
infrastructure/persistence/src/main/kotlin/com/threedays/persistence/user/entity/UserJpaEntity.kt phoneNumber 속성에 unique = true 추가
infrastructure/persistence/src/main/kotlin/com/threedays/persistence/user/repository/UserJpaRepository.kt findByPhoneNumber(phoneNumber: String): UserJpaEntity? 메서드 추가
infrastructure/persistence/src/main/resources/db/migration/V1__init_user.sql users 테이블에 phone_number에 대한 고유 제약 조건 추가
bootstrap/api/src/main/kotlin/com/threedays/bootstrap/api/auth/AuthController.kt verifyCode 메서드 제거, requestVerification 메서드의 파라미터 타입을 변경
domain/src/testFixtures/kotlin/com/threedays/domain/support/base/QueryRepositorySpyBase.kt 클래스 이름 변경 및 새로운 메서드 추가
domain/src/testFixtures/kotlin/com/threedays/domain/support/base/RepositorySpyBase.kt 새로운 추상 클래스 추가, 여러 메서드 구현

Possibly related PRs

Suggested reviewers

  • dojinyou

🐇 새로운 코드로 가득한 이 땅,
인증 코드가 춤추는 환상!
전화번호도 이제는 뚜렷해,
사용자 구분은 더 이상 걱정 없네.
변경된 구조로 모두가 행복해,
Rabbit의 기쁨이 여기서 피어 나네! 🐇✨


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 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.

@waterfogSW waterfogSW self-assigned this Oct 2, 2024
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: 5

🧹 Outside diff range and nitpick comments (14)
domain/src/main/kotlin/com/threedays/domain/user/repository/UserRepository.kt (1)

3-11: 변경 사항이 적절해 보입니다.

이 변경은 SMS 인증 API 구현을 위한 좋은 첫 단계입니다. findByPhoneNumber 메서드의 추가는 전화번호로 사용자를 조회하는 기능을 제공하여 SMS 인증 프로세스를 지원합니다.

몇 가지 긍정적인 점:

  1. PhoneNumber 타입을 사용하여 타입 안전성을 보장합니다.
  2. 반환 타입이 User?로 설정되어 사용자가 존재하지 않을 수 있는 상황을 고려합니다.

코드 일관성을 위해 다음과 같은 작은 개선을 제안합니다:

 interface UserRepository : Repository<User, User.Id> {
-
     fun findByPhoneNumber(phoneNumber: PhoneNumber): User?
-
 }

불필요한 빈 줄을 제거하여 코드를 더 간결하게 만들 수 있습니다.

infrastructure/persistence/src/main/kotlin/com/threedays/persistence/user/repository/UserJpaRepository.kt (1)

9-13: LGTM! 메서드 추가가 적절합니다.

findByPhoneNumber 메서드의 추가는 SMS 인증 API 구현을 위한 적절한 변경사항입니다. 메서드 시그니처가 정확하고 Spring Data JPA 명명 규칙을 따르고 있습니다.

보안을 강화하기 위해 다음과 같은 작은 개선을 고려해 보세요:

fun findByPhoneNumber(phoneNumber: String): UserJpaEntity?

대신에:

fun findByPhoneNumber(phoneNumber: String): Optional<UserJpaEntity>

이렇게 하면 null 안전성이 향상되고 호출하는 쪽에서 결과를 더 명시적으로 처리할 수 있습니다.

domain/src/testFixtures/kotlin/com/threedays/domain/support/base/QueryRepositorySpyBase.kt (3)

13-13: find 메서드 구현이 간결하고 명확합니다.

저장소를 사용하여 ID로 엔티티를 검색하는 구현이 적절합니다. 엔티티가 존재하지 않을 수 있는 경우를 고려하여 nullable 반환 타입 E?를 사용한 것도 좋습니다.

다만, 이 메서드를 open으로 선언하는 것을 고려해 보시는 것은 어떨까요? 이렇게 하면 하위 클래스에서 필요한 경우 이 동작을 재정의할 수 있어 더 큰 유연성을 제공할 수 있습니다.


15-15: init 메서드의 목적을 명확히 해주세요.

init 메서드를 open으로 선언한 것은 하위 클래스에서 필요한 초기화 로직을 제공할 수 있게 하는 좋은 방법입니다.

하지만 이 메서드의 목적이 다른 개발자들에게 즉시 명확하지 않을 수 있습니다. 메서드 위에 간단한 주석을 추가하여 이 메서드의 용도를 설명하는 것이 좋겠습니다. 예를 들면:

// Initialization hook for subclasses. Override this method to provide custom initialization logic.
open fun init() {}

17-17: clear 메서드 구현이 적절합니다만, 주의가 필요합니다.

저장소를 비우는 clear 메서드의 구현이 간단하고 명확합니다. 이를 open으로 선언하여 하위 클래스에서 필요한 경우 동작을 재정의할 수 있게 한 것도 좋습니다.

다만, 전체 저장소를 비우는 작업은 일부 상황에서 위험할 수 있습니다. 이 메서드 사용 시 주의가 필요하다는 경고 주석을 추가하는 것이 좋겠습니다. 예를 들면:

// Warning: This method clears all data from the storage. Use with caution.
open fun clear() = storage.clear()
infrastructure/persistence/src/main/kotlin/com/threedays/persistence/user/adapter/UserPersistenceAdapter.kt (1)

17-21: findByPhoneNumber 메서드가 올바르게 구현되었습니다.

새로운 메서드가 UserRepository 인터페이스를 올바르게 구현하고 있습니다. JPA 리포지토리를 사용하여 전화번호로 사용자를 찾고, 결과를 도메인 엔티티로 변환하는 것이 잘 되어 있습니다.

한 가지 제안사항:

null 안전성을 더욱 명시적으로 처리하기 위해 다음과 같이 변경을 고려해 보세요:

override fun findByPhoneNumber(phoneNumber: PhoneNumber): User? =
    userJpaRepository.findByPhoneNumber(phoneNumber.value)?.toDomainEntity()

이렇게 하면 코드가 더 간결해지고 null 처리가 명확해집니다.

application/src/test/kotlin/com/threedays/application/auth/service/AuthCodeServiceTest.kt (4)

33-41: LGTM: UserRepositorySpy 추가 및 서비스 설정 업데이트

UserRepositorySpy의 추가와 AuthCodeService 생성자 매개변수 업데이트가 적절히 이루어졌습니다. 이는 새로운 테스트 시나리오를 지원하기 위한 필요한 변경사항입니다.

가독성 향상을 위해 userRepository를 다른 의존성들과 함께 알파벳 순서로 정렬하는 것을 고려해보세요.


53-69: LGTM: 새 사용자에 대한 테스트 케이스 추가

새로운 사용자 시나리오에 대한 테스트 케이스가 잘 구현되었습니다. PhoneNumber 객체의 사용, 인증 코드 생성 및 SMS 발송 확인, 그리고 올바른 결과 타입 검증이 포함되어 있습니다.

테스트의 가독성을 높이기 위해 // arrange, // act, // assert 주석을 한 줄씩 띄워 구분하는 것을 고려해보세요.


71-93: LGTM: 기존 사용자에 대한 테스트 케이스 추가

기존 사용자 시나리오에 대한 테스트 케이스가 잘 구현되었습니다. 사용자 생성 및 저장, 인증 코드 생성 및 SMS 발송 확인, 그리고 올바른 결과 타입 검증이 포함되어 있습니다.

테스트 케이스 간의 일관성을 위해 이 테스트에서도 fixtureMonkey를 사용하여 phoneNumber를 생성하는 것을 고려해보세요.


Line range hint 1-143: 전반적인 변경사항에 대한 긍정적 평가

이 PR은 AuthCodeServiceTest를 성공적으로 개선했습니다:

  1. 새 사용자와 기존 사용자 시나리오에 대한 명확한 테스트 구조
  2. PhoneNumber 객체의 일관된 사용으로 타입 안전성 향상
  3. UserRepositorySpy 추가로 사용자 등록 상태 테스트 가능

이러한 변경으로 테스트 커버리지가 향상되고 코드의 견고성이 개선되었습니다.

향후 개선사항으로, 테스트 데이터 생성을 위한 팩토리 메서드나 빌더 패턴의 도입을 고려해보세요. 이는 테스트 코드의 재사용성과 유지보수성을 더욱 향상시킬 수 있습니다.

domain/src/testFixtures/kotlin/com/threedays/domain/support/base/RepositorySpyBase.kt (1)

29-31: 'clear' 메서드의 필요성 검토

clear() 메서드는 현재 클래스 내부에서만 사용되며, Repository 인터페이스에 정의되어 있지 않습니다. 이 메서드의 사용 목적이 테스트를 위한 것이라면, 해당 용도를 명확히 하기 위해 주석을 추가하거나 메서드 명을 변경하는 것을 고려해보세요.

application/src/main/kotlin/com/threedays/application/auth/service/AuthCodeService.kt (1)

51-51: TODO 주석에 대한 구현 필요

51번째 라인에 "기존에 가입한 유저일 경우 분기 처리"라는 TODO 주석이 있습니다. 이 부분의 구현을 도와드릴까요? 새로운 GitHub 이슈를 생성하여 작업을 추적할 수 있습니다.

domain/src/testFixtures/kotlin/com/threedays/domain/auth/repository/LocationQueryRepositorySpy.kt (2)

12-13: [성능 개선 제안] 컬렉션 변환 시 불필요한 연산 최소화

storage.values.toList()를 호출하여 새로운 리스트를 생성하고 있습니다. 만약 storage.values가 이미 컬렉션이라면 바로 반환하여 불필요한 리스트 생성을 피할 수 있습니다.

-    return storage.values.toList()
+    return storage.values

Line range hint 17-85: [코드 가독성 개선] 지역 데이터 초기화 로직 간소화

addSeoulRegions() 메서드에서 여러 개의 Location 객체를 storage에 추가하고 있습니다. 이 부분을 반복문이나 데이터 구조를 활용하여 간소화하면 코드의 가독성을 높일 수 있습니다.

예를 들어, 지역 데이터 리스트를 미리 선언하고 이를 순회하면서 storage에 추가하는 방식으로 변경할 수 있습니다.

private fun addSeoulRegions() {
    val locations = listOf(
        Triple("0191cd0e-a061-7213-b39e-51274c1e7c71", "서울특별시", "종로구"),
        Triple("0191cd0e-a061-7213-b39e-51274c1e7c72", "서울특별시", "중구"),
        // ... 나머지 지역들
    )

    locations.forEach { (idStr, region, subRegion) ->
        val id = Location.Id(UUID.fromString(idStr))
        storage[id] = Location(id, Location.Region(region), Location.SubRegion(subRegion))
    }
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between d9b4d71 and 7d3fcfc.

📒 Files selected for processing (17)
  • application/src/main/kotlin/com/threedays/application/auth/port/inbound/SendAuthCode.kt (1 hunks)
  • application/src/main/kotlin/com/threedays/application/auth/service/AuthCodeService.kt (2 hunks)
  • application/src/test/kotlin/com/threedays/application/auth/service/AuthCodeServiceTest.kt (5 hunks)
  • bootstrap/api/src/main/kotlin/com/threedays/bootstrap/api/auth/AuthController.kt (1 hunks)
  • domain/src/main/kotlin/com/threedays/domain/auth/entity/AuthCode.kt (1 hunks)
  • domain/src/main/kotlin/com/threedays/domain/user/repository/UserRepository.kt (1 hunks)
  • domain/src/testFixtures/kotlin/com/threedays/domain/auth/repository/AbstractTestRepositorySpy.kt (0 hunks)
  • domain/src/testFixtures/kotlin/com/threedays/domain/auth/repository/AuthCodeRepositorySpy.kt (1 hunks)
  • domain/src/testFixtures/kotlin/com/threedays/domain/auth/repository/LocationQueryRepositorySpy.kt (1 hunks)
  • domain/src/testFixtures/kotlin/com/threedays/domain/support/base/QueryRepositorySpyBase.kt (1 hunks)
  • domain/src/testFixtures/kotlin/com/threedays/domain/support/base/RepositorySpyBase.kt (1 hunks)
  • domain/src/testFixtures/kotlin/com/threedays/domain/user/repository/UserRepositorySpy.kt (1 hunks)
  • infrastructure/persistence/src/main/kotlin/com/threedays/persistence/user/adapter/UserPersistenceAdapter.kt (2 hunks)
  • infrastructure/persistence/src/main/kotlin/com/threedays/persistence/user/entity/UserJpaEntity.kt (1 hunks)
  • infrastructure/persistence/src/main/kotlin/com/threedays/persistence/user/repository/UserJpaRepository.kt (1 hunks)
  • infrastructure/persistence/src/main/resources/db/migration/V1__init_user.sql (1 hunks)
  • openapi (1 hunks)
💤 Files with no reviewable changes (1)
  • domain/src/testFixtures/kotlin/com/threedays/domain/auth/repository/AbstractTestRepositorySpy.kt
✅ Files skipped from review due to trivial changes (1)
  • openapi
🔇 Additional comments (27)
domain/src/testFixtures/kotlin/com/threedays/domain/auth/repository/AuthCodeRepositorySpy.kt (2)

4-6: 리팩토링이 잘 되었습니다!

RepositorySpyBase를 상속받아 클래스를 간소화한 것은 좋은 접근 방식입니다. 이로 인해 코드 중복이 줄어들고 유지보수성이 향상됩니다. 또한 단일 책임 원칙을 잘 따르고 있습니다.


6-6: 기능 검증 필요

RepositorySpyBaseAuthCodeRepository의 모든 필요한 기능을 제공하는지 확인해 주세요. 만약 누락된 기능이 있다면, 이를 추가로 구현해야 할 수 있습니다.

다음 스크립트를 실행하여 AuthCodeRepositoryRepositorySpyBase의 메서드를 비교해 주세요:

domain/src/testFixtures/kotlin/com/threedays/domain/user/repository/UserRepositorySpy.kt (3)

1-5: 패키지 선언과 임포트가 적절합니다.

패키지 선언이 파일 위치와 일치하며, 필요한 클래스들이 올바르게 임포트되어 있습니다. 불필요한 임포트도 없어 깔끔합니다.


7-7: 클래스 선언이 적절합니다.

UserRepositorySpy 클래스가 UserRepository 인터페이스를 구현하고 RepositorySpyBase<User, User.Id>를 상속받는 것이 적절합니다. 이는 사용자 저장소의 스파이 객체로서의 역할을 잘 나타내고 있습니다.


9-11: findByPhoneNumber 메서드 구현이 적절합니다.

메서드 구현이 올바르게 UserRepository 인터페이스를 오버라이드하고 있습니다. super.entities를 사용하여 기본 클래스의 엔티티 맵에 접근하는 것이 적절합니다.

하나의 제안사항이 있습니다:

  • 현재 구현은 전화번호가 고유하다고 가정합니다. 만약 동일한 전화번호를 가진 여러 사용자가 있을 수 있다면, 이를 처리하는 로직을 고려해 보시기 바랍니다.

전화번호의 고유성을 확인하기 위해 다음 스크립트를 실행해 보세요:

domain/src/testFixtures/kotlin/com/threedays/domain/support/base/QueryRepositorySpyBase.kt (2)

8-9: 클래스 선언과 상속이 적절합니다.

제네릭을 사용하여 유연성과 타입 안전성을 확보했습니다. 추상 클래스로 선언하여 특정 엔티티 타입에 대해 확장할 수 있게 했고, QueryRepository 인터페이스를 구현하여 도메인 모델과의 일관성을 유지했습니다.


11-11: 스레드 안전한 저장소 구현이 좋습니다.

ConcurrentHashMap을 사용하여 멀티스레드 환경에서의 스레드 안전성을 확보했습니다. 속성을 open으로 선언하여 필요한 경우 하위 클래스에서 오버라이드할 수 있게 한 점도 좋습니다.

infrastructure/persistence/src/main/kotlin/com/threedays/persistence/user/adapter/UserPersistenceAdapter.kt (3)

3-3: 새로운 import 문이 올바르게 추가되었습니다.

PhoneNumber 클래스의 import가 적절하게 추가되었습니다. 이는 새로 구현된 findByPhoneNumber 메서드에 필요한 것으로 보입니다.


17-21: 새로운 메서드가 기존 코드와 잘 통합되었습니다.

findByPhoneNumber 메서드가 클래스의 다른 메서드들과 일관된 패턴을 따르고 있습니다. 특히 find(id: User.Id) 메서드와 유사한 구조를 가지고 있어, 코드의 일관성을 잘 유지하고 있습니다.


Line range hint 1-43: 전반적인 구현이 잘 되었습니다.

이 PR에서 UserPersistenceAdapter 클래스에 findByPhoneNumber 메서드를 추가한 것은 적절해 보입니다. 새로운 메서드는 기존 코드 스타일과 패턴을 잘 따르고 있으며, UserRepository 인터페이스를 올바르게 구현하고 있습니다.

주요 변경 사항:

  1. PhoneNumber 클래스의 import 추가
  2. findByPhoneNumber 메서드 구현

이 변경사항들은 SMS 인증 API 구현이라는 PR의 목적에 부합하는 것으로 보입니다. 코드는 간결하고 명확하며, 기존 구조와 잘 어울립니다.

infrastructure/persistence/src/main/resources/db/migration/V1__init_user.sql (1)

57-58: 전화번호에 대한 고유 제약 조건 추가 승인

phone_number 열에 고유 제약 조건을 추가한 것은 좋은 변경사항입니다.

이 변경의 장점:

  • 사용자 레코드 전체에서 각 전화번호의 고유성을 보장합니다.
  • 중복 전화번호를 방지하여 데이터 무결성을 향상시킵니다.
  • 전화번호를 사용자의 고유 식별자로 사용하는 일반적인 관행과 일치합니다.

구현 시 고려사항:

  • 기존 데이터베이스에 중복된 전화번호가 있는 경우 마이그레이션 계획을 세워야 합니다.
  • 사용자 등록 또는 업데이트를 처리하는 애플리케이션 로직을 업데이트해야 할 수 있습니다.
  • 중복 전화번호 삽입 시도에 대한 적절한 오류 처리가 구현되어 있는지 확인하세요.

다음 스크립트를 실행하여 users 테이블의 구조와 제약 조건을 확인하세요:

✅ Verification successful

유니크 제약 조건의 존재를 확인하기 위해 다음 스크립트를 실행하세요:


유니크 제약 조건 확인 완료

users 테이블의 phone_number 열에 대한 UNIQUE 제약 조건이 성공적으로 추가되었습니다. 모든 것이 의도한 대로 구현된 것으로 확인됩니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 설명: users 테이블의 구조와 제약 조건을 확인합니다.

# 테스트: users 테이블의 구조를 검색합니다. 예상 결과: phone_number 열에 UNIQUE 제약 조건이 있어야 합니다.
rg --type sql -i "create table users|alter table users"

Length of output: 153


Script:

#!/bin/bash
# 설명: users 테이블의 phone_number 열에 UNIQUE 제약 조건이 있는지 확인합니다.

rg --type sql -i "CONSTRAINT uq_users_phone_number UNIQUE" infrastructure/persistence/src/main/resources/db/migration/V1__init_user.sql

Length of output: 196

infrastructure/persistence/src/main/kotlin/com/threedays/persistence/user/entity/UserJpaEntity.kt (1)

34-34: 전화번호의 고유성 제약 조건 추가에 대한 고려사항

phoneNumber 필드에 unique = true 속성을 추가한 것은 좋은 변경사항입니다. 이는 사용자 식별에 도움이 되며 데이터 무결성을 향상시킵니다. 그러나 다음 사항들을 고려해야 합니다:

  1. 기존 데이터베이스에 중복된 전화번호가 있다면 정리가 필요할 수 있습니다.
  2. 애플리케이션 코드에서 고유 제약 조건 위반을 적절히 처리하는지 확인해야 합니다.
  3. 이 변경사항을 위한 데이터베이스 마이그레이션 스크립트가 필요할 수 있습니다.
  4. 고유성이 제대로 적용되고 처리되는지 확인하기 위한 새로운 테스트 케이스를 추가해야 할 수 있습니다.

이러한 점들을 고려하여 변경사항을 완전히 구현하고 테스트하시기 바랍니다.

다음 스크립트를 실행하여 관련 변경사항을 확인해 주세요:

application/src/test/kotlin/com/threedays/application/auth/service/AuthCodeServiceTest.kt (3)

14-17: LGTM: 필요한 임포트 추가됨

새로운 의존성들이 적절하게 추가되었습니다. 이는 테스트 케이스의 변경사항과 일치합니다.


104-104: LGTM: PhoneNumber 객체 사용

AuthCode.create 호출에서 phoneNumber 매개변수가 문자열 대신 PhoneNumber 객체를 사용하도록 적절히 수정되었습니다. 이는 타입 안전성을 보장하고 도메인 모델과 일치합니다.


126-126: LGTM: PhoneNumber 객체 사용 일관성

이전 변경사항과 일관되게, 여기서도 AuthCode.create 호출에서 phoneNumber 매개변수가 PhoneNumber 객체를 사용하도록 수정되었습니다. 이는 전체적인 코드 일관성과 타입 안전성을 유지합니다.

application/src/main/kotlin/com/threedays/application/auth/port/inbound/SendAuthCode.kt (4)

4-4: PhoneNumber 클래스 임포트 추가 확인

PhoneNumber 클래스를 임포트하여 전화번호를 보다 명확하게 표현하고 있습니다. 좋은 접근입니다.


16-28: Result sealed class 추가에 대한 검토

새로운 Result sealed class와 그 하위 클래스인 ExistingUserNewUser를 추가하여 결과를 명확하게 표현하고 있습니다. 이는 결과 타입의 확장성과 유지보수성을 높이는 좋은 접근입니다.


13-13: phoneNumber 타입 변경에 따른 영향 확인 필요

Command 데이터 클래스의 phoneNumber 속성이 String에서 PhoneNumber로 변경되었습니다. 이로 인해 Command 객체를 생성하거나 사용하는 부분에서 타입 불일치로 인한 오류가 발생할 수 있으므로 전체 코드베이스에서 해당 변경 사항이 올바르게 반영되었는지 확인하세요.

다음 스크립트를 실행하여 Command 객체 생성 부분을 찾아서 확인하세요:

#!/bin/bash
# Description: 'SendAuthCode.Command' 객체 생성 시 'phoneNumber' 타입 사용 확인

# 'SendAuthCode.Command' 객체를 생성하는 코드 검색
rg --type kotlin 'SendAuthCode\.Command\(' -A 5

9-9: invoke 함수의 반환 타입 변경에 따른 영향 확인 필요

SendAuthCode 인터페이스의 invoke 함수 반환 타입이 AuthCode에서 Result로 변경되었습니다. 이로 인해 해당 인터페이스를 구현하는 클래스들과 이 함수를 호출하는 부분에서 수정이 필요할 수 있으므로 확인이 필요합니다.

다음 스크립트를 실행하여 변경 사항이 코드베이스 전체에 올바르게 반영되었는지 확인하세요:

✅ Verification successful

SendAuthCode 인터페이스의 invoke 함수 반환 타입 변경 확인 완료

SendAuthCode 인터페이스의 invoke 함수 반환 타입이 Result로 변경된 사항이 코드베이스 전체에 올바르게 반영되었습니다. 현재 이 인터페이스를 구현하는 클래스가 존재하지 않으므로 추가적인 수정이 필요하지 않습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: 'SendAuthCode' 인터페이스의 'invoke' 함수 구현 및 호출 부분 확인

# 'SendAuthCode' 인터페이스를 구현하는 클래스에서 'invoke' 함수 확인
rg --type kotlin 'class\s+\w+\s*:\s*SendAuthCode' -A 10 | rg 'fun\s+invoke\('

# 'invoke' 함수를 호출하는 부분 확인
rg --type kotlin 'sendAuthCode\.invoke\(' -A 5

Length of output: 1858


Script:

#!/bin/bash
# Description: 'SendAuthCode' 인터페이스를 구현하는 클래스에서 'invoke' 함수 확인 및 호출 부분 확인

# 'SendAuthCode' 인터페이스를 구현하는 클래스에서 'invoke' 함수 확인
rg --type kotlin 'class\s+\w+\s*:\s*SendAuthCode' -A 10 | rg 'fun\s+invoke\s*\('

# 'invoke' 함수를 호출하는 부분 확인
rg --type kotlin 'sendAuthCode\.invoke\s*\(' -A 5

Length of output: 946


Script:

#!/bin/bash
# Description: 'SendAuthCode' 인터페이스를 구현하는 모든 클래스 확인

# 'SendAuthCode' 인터페이스를 구현하는 클래스 검색
ast-grep --lang kotlin --pattern 'class $_: SendAuthCode { $$ }'

Length of output: 66


Script:

#!/bin/bash
# Description: 'SendAuthCode' 인터페이스를 구현하는 모든 클래스 확인 (유연한 패턴 사용)

# 'SendAuthCode' 인터페이스를 구현하는 클래스 검색 (ast-grep 패턴 수정)
ast-grep --lang kotlin --pattern 'class $_: .*SendAuthCode.* { $$ }'

# 'SendAuthCode' 인터페이스를 구현하는 클래스 검색 (ripgrep 사용, 더 유연한 패턴)
rg --type kotlin 'class\s+\w+\s*:\s*[^,{]*SendAuthCode[^,{]*' -A 5

# 'SendAuthCode'를 구현하는 객체 혹은 다른 방식의 구현 검색
rg --type kotlin '(object|data class)\s+\w+\s*:\s*SendAuthCode' -A 5

Length of output: 210

domain/src/testFixtures/kotlin/com/threedays/domain/support/base/RepositorySpyBase.kt (1)

8-33: 전반적으로 잘 구현된 Repository 스파이 클래스입니다

클래스가 Repository 인터페이스를 적절히 구현하고 있으며, 스레드 안전성을 위한 ConcurrentHashMap을 사용하는 등 전체적인 설계가 우수합니다.

application/src/main/kotlin/com/threedays/application/auth/service/AuthCodeService.kt (4)

10-10: UserRepository 임포트 확인

UserRepository가 추가로 임포트되어, 유저 정보를 조회할 수 있게 되었습니다.


16-16: UserRepository 의존성 주입 확인

UserRepository를 의존성으로 추가하여 기존 유저 확인 로직 구현을 위한 준비를 완료하셨습니다.


23-23: 메소드 반환 타입 변경 확인

SendAuthCode의 invoke 메소드의 반환 타입이 AuthCode에서 SendAuthCode.Result로 변경되어, 결과에 대한 추가 정보를 제공할 수 있게 되었습니다.


37-41: 기존 유저와 신규 유저 구분 로직 추가

userRepository를 활용하여 전화번호로 유저를 조회하고, 그 결과에 따라 NewUser 또는 ExistingUser를 반환하는 로직이 추가되었습니다. 기능 구현이 명확하고 적절합니다.

domain/src/testFixtures/kotlin/com/threedays/domain/auth/repository/LocationQueryRepositorySpy.kt (3)

9-9: [중복 코멘트] 메서드 제거에 따른 영향 검토 필요

find 메서드가 제거되었습니다. 이로 인해 해당 메서드를 호출하는 부분에서 컴파일 오류나 런타임 에러가 발생할 수 있으니, 이 메서드를 사용하는 모든 부분을 확인하고 필요한 경우 대체 구현이나 수정이 필요합니다.


3-3: 🛠️ Refactor suggestion

[코드 개선 제안] 사용하지 않는 import 문 정리

import com.threedays.domain.support.base.QueryRepositorySpyBase를 추가하셨는데, 기존에 사용하던 import com.threedays.domain.support.base.AbstractTestRepositorySpy는 더 이상 필요 없으므로 제거하시는 것이 좋습니다.

-import com.threedays.domain.support.base.AbstractTestRepositorySpy
+import com.threedays.domain.support.base.QueryRepositorySpyBase

Likely invalid or redundant comment.


9-9: [클래스 상속 변경 확인] 상속 구조 변경에 따른 영향 검토 필요

클래스가 AbstractTestRepositorySpy에서 QueryRepositorySpyBase로 변경되었습니다. 이로 인해 해당 클래스의 동작이나 다른 종속 클래스 및 인터페이스에 영향이 있을 수 있으므로, 전체적인 영향 범위를 검토해 주시길 바랍니다.

검토를 위해 다음 스크립트를 실행하여 이 클래스의 사용처를 확인하세요:

✅ Verification successful

상속 변경 검증 완료

LocationQueryRepositorySpy 클래스의 상속 변경이 테스트 코드에만 영향을 미치며, 다른 부분에는 영향을 주지 않는 것으로 확인되었습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: LocationQueryRepositorySpy 클래스의 사용 위치 확인

# Test: 클래스 사용 위치 검색
rg --type kotlin -A 5 'LocationQueryRepositorySpy'

Length of output: 2353

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

🧹 Outside diff range and nitpick comments (2)
infrastructure/sms/src/test/kotlin/com/threedays/sms/auth/adapter/AuthCodeSmsSenderCoolSmsAdapterTest.kt (1)

Line range hint 20-57: 일관성 및 유지보수성 개선 제안

테스트의 나머지 부분에서 일관성과 유지보수성을 개선할 수 있는 몇 가지 사항이 있습니다:

  1. smsPropertiesSingleMessageSentResponse에서 사용되는 하드코딩된 전화번호 문자열을 PhoneNumber 객체로 변경하는 것을 고려해보세요.

  2. 테스트에서 사용되는 전화번호를 상수로 정의하여 재사용하는 것이 좋습니다. 예를 들어:

private const val TEST_PHONE_NUMBER = "01012345678"

이렇게 하면 테스트 케이스 전체에서 일관성을 유지하고 향후 변경 사항을 쉽게 관리할 수 있습니다.

이러한 변경을 적용하시겠습니까? 필요하다면 구체적인 리팩토링 제안을 제공해 드릴 수 있습니다.

domain/src/test/kotlin/com/threedays/domain/auth/entity/AuthCodeTest.kt (1)

79-79: PhoneNumber 값 객체의 일관된 사용 및 개선 제안

"만료된 인증 코드로" 테스트 케이스에서도 PhoneNumber 값 객체를 일관되게 사용하고 있어 좋습니다. 이로써 모든 테스트 케이스에서 PhoneNumber 값 객체로의 전환이 완료되었습니다.

개선 제안: 테스트 코드에서 반복적으로 사용되는 "01012345678"과 같은 하드코딩된 값을 피하고, 테스트용 전화번호를 생성하는 팩토리 메서드나 테스트 픽스처를 사용하는 것을 고려해보세요. 이는 테스트의 유지보수성과 가독성을 향상시킬 수 있습니다.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 7d3fcfc and 1c16b40.

📒 Files selected for processing (2)
  • domain/src/test/kotlin/com/threedays/domain/auth/entity/AuthCodeTest.kt (5 hunks)
  • infrastructure/sms/src/test/kotlin/com/threedays/sms/auth/adapter/AuthCodeSmsSenderCoolSmsAdapterTest.kt (2 hunks)
🔇 Additional comments (6)
infrastructure/sms/src/test/kotlin/com/threedays/sms/auth/adapter/AuthCodeSmsSenderCoolSmsAdapterTest.kt (2)

4-4: LGTM: PhoneNumber 클래스 import 추가

PhoneNumber 클래스의 import 추가는 적절합니다. 이는 테스트에서 PhoneNumber 객체를 사용하기 위해 필요한 변경사항입니다.


37-37: phoneNumber 매개변수 타입 변경 승인 및 검증 제안

AuthCode.create() 메서드에서 phoneNumber 매개변수를 문자열에서 PhoneNumber 객체로 변경한 것은 좋은 개선입니다. 이는 타입 안정성을 높이고 도메인 주도 설계 원칙에 더 잘 부합합니다.

다만, 이 변경이 AuthCode를 사용하는 다른 부분에 영향을 미칠 수 있습니다. 다음 스크립트를 실행하여 AuthCode.create() 메서드의 다른 사용 사례를 확인하고, 필요한 경우 업데이트하세요:

domain/src/test/kotlin/com/threedays/domain/auth/entity/AuthCodeTest.kt (4)

6-6: LGTM: PhoneNumber 값 객체 import 추가

PhoneNumber 값 객체의 import가 올바르게 추가되었습니다.


28-28: PhoneNumber 값 객체 사용으로 타입 안전성 향상

PhoneNumber 값 객체를 사용하여 phoneNumber를 초기화하는 것은 좋은 변경입니다. 이는 다음과 같은 이점을 제공합니다:

  1. 타입 안전성 향상
  2. 전화번호와 관련된 유효성 검사 및 비즈니스 로직의 중앙화
  3. 도메인 모델의 명확성 증가

47-47: 일관된 PhoneNumber 값 객체 사용

"유효한 인증 코드로" 테스트 케이스에서도 PhoneNumber 값 객체를 일관되게 사용하고 있습니다. 이는 테스트 코드의 일관성을 유지하고 실제 도메인 로직을 정확히 반영하는 좋은 사례입니다.


Line range hint 1-138: 전체 변경사항 요약 및 영향 평가

이번 PR에서 AuthCodeTest.kt 파일의 주요 변경사항은 PhoneNumber 값 객체의 도입입니다. 이 변경은 다음과 같은 긍정적인 영향을 미칩니다:

  1. 타입 안전성 향상: 문자열 대신 전용 값 객체를 사용함으로써 타입 관련 오류를 줄일 수 있습니다.
  2. 도메인 모델의 명확성 증가: PhoneNumber라는 명확한 의미를 가진 객체를 사용함으로써 코드의 의도가 더 명확해집니다.
  3. 비즈니스 로직의 중앙화: 전화번호와 관련된 유효성 검사 및 기타 로직을 PhoneNumber 객체에 캡슐화할 수 있습니다.

이 변경은 테스트 코드 전반에 걸쳐 일관되게 적용되었으며, 전반적인 코드 품질을 향상시켰습니다.

추가 개선사항으로, 테스트 데이터 생성을 위한 팩토리 메서드나 테스트 픽스처의 도입을 고려해볼 수 있습니다. 이는 테스트 코드의 유지보수성과 가독성을 더욱 향상시킬 것입니다.

Copy link

sonarcloud bot commented Oct 2, 2024

1 similar comment
Copy link

sonarcloud bot commented Oct 2, 2024

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: 1

🧹 Outside diff range and nitpick comments (3)
domain/src/testFixtures/kotlin/com/threedays/domain/support/base/QueryRepositorySpyBase.kt (1)

Line range hint 13-19: 메서드 구현이 대체로 적절합니다만, init 메서드에 대한 설명이 필요합니다.

find 메서드와 clear 메서드의 구현이 간단하고 정확합니다. 그러나 init 메서드의 목적이 명확하지 않습니다.

init 메서드에 주석을 추가하여 그 목적과 사용 방법을 설명해 주세요. 예를 들어:

/**
 * 테스트를 위한 초기 설정을 수행합니다.
 * 하위 클래스에서 필요한 경우 이 메서드를 오버라이드하여 사용하세요.
 */
open fun init() {}
bootstrap/api/src/main/kotlin/com/threedays/bootstrap/api/auth/AuthController.kt (2)

20-21: 메서드 시그니처 변경 승인 및 문서화 제안

PhoneNumberRequest에서 SendAuthCodeRequest로의 매개변수 타입 변경이 적절합니다. 이는 전화번호 처리에서 인증 코드 전송으로의 기능 변경을 잘 반영하고 있습니다.

이 변경사항에 대한 API 문서(예: Swagger 또는 OpenAPI 명세)를 업데이트했는지 확인해주세요.


27-37: 결과 처리 로직 승인 및 가독성 개선 제안

결과 처리 로직이 적절히 구현되었습니다. 기존 사용자와 신규 사용자 케이스를 모두 올바르게 처리하고 있습니다.

가독성을 더욱 높이기 위해 다음과 같이 변수 추출을 고려해보세요:

val response = when (val result = sendAuthCode.invoke(command)) {
    is SendAuthCode.Result.ExistingUser -> SendAuthCodeResponse(
        authCodeId = result.authCode.id.value,
        userStatus = SendAuthCodeResponse.UserStatus.EXISTING
    )
    is SendAuthCode.Result.NewUser -> SendAuthCodeResponse(
        authCodeId = result.authCode.id.value,
        userStatus = SendAuthCodeResponse.UserStatus.NEW
    )
}

이렇게 하면 result 변수를 명시적으로 선언하여 코드의 의도가 더 명확해집니다.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 1c16b40 and 39d68dd.

📒 Files selected for processing (3)
  • bootstrap/api/src/main/kotlin/com/threedays/bootstrap/api/auth/AuthController.kt (1 hunks)
  • domain/src/testFixtures/kotlin/com/threedays/domain/support/base/QueryRepositorySpyBase.kt (1 hunks)
  • domain/src/testFixtures/kotlin/com/threedays/domain/support/base/RepositorySpyBase.kt (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • domain/src/testFixtures/kotlin/com/threedays/domain/support/base/RepositorySpyBase.kt
🔇 Additional comments (5)
domain/src/testFixtures/kotlin/com/threedays/domain/support/base/QueryRepositorySpyBase.kt (3)

1-7: 패키지 선언 및 임포트가 적절합니다.

패키지 이름 변경과 필요한 클래스들의 임포트가 잘 되어 있습니다. 베이스 클래스를 위한 적절한 위치로 보입니다.


8-9: 클래스 선언이 잘 구조화되어 있습니다.

추상 클래스로 선언되어 있고, QueryRepository 인터페이스를 구현하고 있습니다. 제네릭 타입 EID에 대한 제약 조건이 적절히 설정되어 있어 타입 안전성을 보장합니다.


11-11: 스토리지 프로퍼티가 적절히 선언되었습니다.

storage 프로퍼티가 protected로 선언되어 있어 하위 클래스에서 접근 가능하며, ConcurrentHashMap을 사용하여 스레드 안전성을 보장하고 있습니다. 이는 동시 접근 상황에서 적절한 선택입니다.

bootstrap/api/src/main/kotlin/com/threedays/bootstrap/api/auth/AuthController.kt (2)

4-4: import 문 변경 승인

새로운 import 문들이 requestVerification 메서드의 변경사항과 일치하며 적절히 추가되었습니다.

Also applies to: 8-9


40-40: 응답 반환 승인

ResponseEntity.ok(response)를 사용한 응답 반환이 적절합니다. Spring에서 성공적인 응답을 반환하는 표준적인 방법을 따르고 있습니다.

@waterfogSW waterfogSW merged commit ae970a7 into main Oct 2, 2024
3 checks passed
@waterfogSW waterfogSW deleted the feat-verify branch October 2, 2024 23:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants