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

✨ 회원 가입 API 구현 #22

Merged
merged 1 commit into from
Oct 6, 2024
Merged

✨ 회원 가입 API 구현 #22

merged 1 commit into from
Oct 6, 2024

Conversation

waterfogSW
Copy link
Member

@waterfogSW waterfogSW commented Oct 6, 2024

Summary by CodeRabbit

  • 새로운 기능

    • 사용자 등록을 위한 REST 컨트롤러가 추가되었습니다.
    • 로그인 토큰 발급을 위한 새로운 인터페이스와 서비스가 도입되었습니다.
    • 사용자 등록 시 인증 토큰과 만료 시간을 반환하도록 변경되었습니다.
  • 버그 수정

    • 생년 범위와 관련된 파라미터를 nullable로 변경하여 유연성을 향상시켰습니다.
  • 문서화

    • 새로운 데이터 클래스와 메서드에 대한 문서 주석이 추가되었습니다.
  • 테스트

    • 인증 코드 서비스 테스트가 새로운 토큰 발급 로직을 반영하도록 업데이트되었습니다.

@waterfogSW waterfogSW self-assigned this Oct 6, 2024
Copy link

coderabbitai bot commented Oct 6, 2024

Walkthrough

이 변경 사항은 IssueLoginTokens라는 새로운 인터페이스를 도입하고, 이를 통해 로그인 토큰 발급을 처리하는 메서드를 정의합니다. AuthCodeServiceUserService 클래스는 이 인터페이스를 사용하여 토큰 생성 로직을 모듈화하고, 사용자 등록 및 인증 과정에서의 토큰 발급을 통합하는 방식으로 업데이트되었습니다. 또한, 관련 데이터 클래스와 메서드의 반환 타입이 변경되어 더 많은 정보를 포함하도록 개선되었습니다.

Changes

파일 경로 변경 요약
application/src/main/kotlin/com/threedays/application/auth/port/inbound/IssueLoginTokens.kt 새로운 인터페이스 IssueLoginTokens 추가, 메서드 invoke(command: Command): Result 및 데이터 클래스 Command, Result 추가
application/src/main/kotlin/com/threedays/application/auth/service/AuthCodeService.kt AuthCodeService 클래스의 생성자에 IssueLoginTokens 의존성 추가, invoke 메서드에서 직접 토큰 생성을 호출하는 대신 issueLoginTokens.invoke 호출로 변경
application/src/main/kotlin/com/threedays/application/auth/service/AuthTokenService.kt 새로운 클래스 AuthTokenService 추가, IssueLoginTokens 인터페이스 구현, invoke 메서드에서 토큰 생성 로직 추가
application/src/main/kotlin/com/threedays/application/user/port/inbound/RegisterUser.kt RegisterUser 인터페이스의 invoke 메서드 반환 타입을 User에서 Result로 변경, 새로운 데이터 클래스 Result 추가
application/src/main/kotlin/com/threedays/application/user/service/UserService.kt UserService 클래스의 생성자에 IssueLoginTokensAuthProperties 의존성 추가, invoke 메서드 반환 타입 변경
application/src/test/kotlin/com/threedays/application/auth/service/AuthCodeServiceTest.kt AuthCodeServiceTest 클래스에서 issueLoginTokens 변수 추가 및 AuthCodeService 인스턴스화 수정
application/src/testFixtures/kotlin/com/threedays/application/auth/service/IssueLoginTokensStub.kt 새로운 클래스 IssueLoginTokensStub 추가, invoke 메서드 구현
bootstrap/api/src/main/kotlin/com/threedays/bootstrap/api/user/UserController.kt 새로운 REST 컨트롤러 UserController 추가, 사용자 등록 요청 처리 메서드 registerUser 구현
build.gradle.kts 테스트 픽스처에 대한 새로운 의존성 추가
domain/src/main/kotlin/com/threedays/domain/auth/entity/RegisterToken.kt RegisterToken 데이터 클래스에 phoneNumber 속성 추가
domain/src/main/kotlin/com/threedays/domain/user/entity/User.kt create 메서드의 partnerBirthYearRange 매개변수 타입을 nullable로 변경
domain/src/main/kotlin/com/threedays/domain/user/entity/UserDesiredPartner.kt birthYearRange 속성을 nullable로 변경
infrastructure/persistence/src/main/kotlin/com/threedays/persistence/user/entity/UserDesiredPartnerJpaEntity.kt birthYearRangeStartbirthYearRangeEnd 속성을 nullable로 변경
infrastructure/persistence/src/main/resources/db/migration/V1__init_user.sql user_desired_partners 테이블의 birth_year_range_startbirth_year_range_end 컬럼을 nullable로 변경
openapi 서브프로젝트 커밋 식별자 변경

Possibly related PRs

Suggested labels

기능구현

Suggested reviewers

  • dojinyou

🐇 변화의 길을 따라
새로운 인터페이스가 피어나네
토큰 발급, 사용자 등록이
함께 손잡고 나아가네!
모듈화된 세상 속에서
우리 모두의 꿈을 이루길! 🌟


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.

Copy link

sonarcloud bot commented Oct 6, 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: 9

🧹 Outside diff range and nitpick comments (12)
application/src/main/kotlin/com/threedays/application/auth/port/inbound/IssueLoginTokens.kt (2)

7-9: 인터페이스 정의가 명확합니다.

IssueLoginTokens 인터페이스가 목적을 잘 나타내고 있습니다. invoke 메서드 사용은 깔끔한 함수 호출 구문을 가능하게 합니다.

제안: 인터페이스에 간단한 KDoc 주석을 추가하여 이 인터페이스의 목적과 사용법을 문서화하는 것이 좋겠습니다.

다음과 같이 KDoc 주석을 추가할 수 있습니다:

/**
 * 로그인 토큰 발급을 위한 인터페이스.
 * 사용자 정보를 받아 액세스 토큰과 리프레시 토큰을 생성합니다.
 */
interface IssueLoginTokens {
    // ... 현재 코드 ...
}

13-18: Result 데이터 클래스가 잘 정의되었습니다.

Result 데이터 클래스가 invoke 메서드의 출력을 효과적으로 캡슐화하고 있습니다. 액세스 토큰과 리프레시 토큰의 만료 시간을 포함한 것은 토큰 관리에 좋은 방식입니다.

제안: accessTokenExpiresInrefreshTokenExpiresIn의 단위(예: 초, 밀리초)를 명확히 하는 것이 좋겠습니다. 이는 주석이나 더 구체적인 타입을 사용하여 할 수 있습니다.

예를 들어, 다음과 같이 주석을 추가할 수 있습니다:

data class Result(
    val accessToken: AccessToken,
    val refreshToken: RefreshToken,
    val accessTokenExpiresIn: Long, // 초 단위
    val refreshTokenExpiresIn: Long // 초 단위
)

또는 더 명시적인 타입을 사용할 수 있습니다:

import java.time.Duration

data class Result(
    val accessToken: AccessToken,
    val refreshToken: RefreshToken,
    val accessTokenExpiresIn: Duration,
    val refreshTokenExpiresIn: Duration
)
application/src/testFixtures/kotlin/com/threedays/application/auth/service/IssueLoginTokensStub.kt (2)

8-10: 클래스 선언이 잘 되어 있습니다. 문서화를 추가하면 좋겠습니다.

IssueLoginTokensStub 클래스가 IssueLoginTokens 인터페이스를 올바르게 구현하고 있습니다. AuthProperties를 사용하여 설정을 분리한 것은 좋은 접근 방식입니다.

클래스에 KDoc 주석을 추가하여 이 스텁의 목적과 사용 방법을 설명하면 더욱 좋을 것 같습니다. 예를 들어:

/**
 * IssueLoginTokens의 스텁 구현체입니다.
 * 테스트 환경에서 로그인 토큰 발급을 시뮬레이션하는 데 사용됩니다.
 *
 * @property authProperties 인증 관련 설정을 포함하는 객체
 */
class IssueLoginTokensStub(
    private val authProperties: AuthProperties
) : IssueLoginTokens {
    // ...
}

12-31: invoke 메서드 구현이 잘 되어 있습니다. 몇 가지 개선 사항을 제안드립니다.

invoke 메서드가 AccessTokenRefreshToken을 올바르게 생성하고 있습니다. authProperties를 사용하여 애플리케이션의 설정과 일관성을 유지하는 것도 좋습니다.

다음과 같은 개선 사항을 고려해 보시기 바랍니다:

  1. 입력 유효성 검사: command.user.id가 유효한지 확인하는 로직을 추가하세요.
  2. 예외 처리: 토큰 생성 중 발생할 수 있는 예외를 처리하는 로직을 추가하세요.
  3. 로깅: 디버깅을 위해 토큰 생성 과정에 로그를 추가하는 것이 좋습니다.

예시 코드:

override fun invoke(command: IssueLoginTokens.Command): IssueLoginTokens.Result {
    require(command.user.id > 0) { "사용자 ID는 양수여야 합니다." }

    val accessToken: AccessToken = try {
        AccessToken.generate(
            secret = authProperties.tokenSecret,
            expirationSeconds = authProperties.accessTokenExpirationSeconds,
            userId = command.user.id
        )
    } catch (e: Exception) {
        logger.error("액세스 토큰 생성 중 오류 발생", e)
        throw RuntimeException("액세스 토큰을 생성할 수 없습니다.", e)
    }

    // RefreshToken에 대해서도 비슷한 처리를 추가하세요.

    logger.info("사용자 ID ${command.user.id}에 대한 로그인 토큰이 생성되었습니다.")

    return IssueLoginTokens.Result(
        accessToken = accessToken,
        refreshToken = refreshToken,
        accessTokenExpiresIn = authProperties.accessTokenExpirationSeconds,
        refreshTokenExpiresIn = authProperties.refreshTokenExpirationSeconds
    )
}

이러한 변경사항들은 코드의 안정성과 디버깅 용이성을 향상시킬 것입니다.

application/src/main/kotlin/com/threedays/application/auth/service/AuthTokenService.kt (2)

10-13: 클래스 선언과 생성자가 잘 구현되었습니다.

@Service 어노테이션과 IssueLoginTokens 인터페이스 구현이 적절합니다. 생성자 주입을 통해 AuthProperties를 받고 있어 좋습니다.

개선 제안: authPropertiesprivate val 대신 private val과 함께 @Autowired를 사용하는 것이 Spring의 일반적인 관행입니다. 다음과 같이 변경을 고려해 보세요:

class AuthTokenService @Autowired constructor(
    private val authProperties: AuthProperties,
) : IssueLoginTokens {
    // ...
}

이렇게 하면 의존성 주입이 명시적으로 표시되어 코드의 의도가 더 명확해집니다.


15-36: invoke 메서드가 잘 구현되었습니다.

토큰 생성 로직이 명확하고 간결하게 구현되어 있습니다. authProperties를 사용하여 토큰 시크릿과 만료 시간을 가져오는 것이 좋습니다.

개선 제안: 예외 처리를 추가하는 것이 좋겠습니다. 토큰 생성 과정에서 발생할 수 있는 예외를 처리하여 더 견고한 코드를 만들 수 있습니다. 예를 들어:

override fun invoke(command: IssueLoginTokens.Command): IssueLoginTokens.Result {
    val user: User = command.user

    try {
        val accessToken: AccessToken = AccessToken.generate(
            secret = authProperties.tokenSecret,
            expirationSeconds = authProperties.accessTokenExpirationSeconds,
            userId = user.id
        )

        val refreshToken: RefreshToken = RefreshToken.generate(
            secret = authProperties.tokenSecret,
            expirationSeconds = authProperties.refreshTokenExpirationSeconds,
            userId = user.id
        )

        return IssueLoginTokens.Result(
            accessToken = accessToken,
            refreshToken = refreshToken,
            accessTokenExpiresIn = authProperties.accessTokenExpirationSeconds,
            refreshTokenExpiresIn = authProperties.refreshTokenExpirationSeconds
        )
    } catch (e: Exception) {
        // 로그 기록
        logger.error("토큰 생성 중 오류 발생", e)
        throw TokenGenerationException("토큰을 생성하는 동안 오류가 발생했습니다", e)
    }
}

이렇게 하면 토큰 생성 중 발생할 수 있는 예외를 잡아 적절히 처리할 수 있습니다.

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

82-96: LGTM: toDomainEntity 함수의 null 처리, 가독성 개선 제안

toDomainEntity 함수에서 birthYearRange를 nullable ClosedRange<Year>?로 처리한 것은 적절합니다. 이는 birthYearRangeStartbirthYearRangeEnd의 nullable 특성을 올바르게 다룹니다.

하지만 중첩된 let 구조가 약간 복잡해 보입니다. 가독성을 높이기 위해 다음과 같은 리팩토링을 고려해 보세요:

fun toDomainEntity(): UserDesiredPartner {
    val birthYearRange = birthYearRangeStart?.let { start ->
        birthYearRangeEnd?.let { end ->
            Year.of(start)..Year.of(end)
        }
    }

    return UserDesiredPartner(
        id = UUIDTypeId.from(id),
        birthYearRange = birthYearRange,
        jobOccupations = jobOccupations,
        preferDistance = preferDistance
    )
}

이렇게 하면 birthYearRange 생성 로직이 분리되어 더 읽기 쉬워집니다.

domain/src/test/kotlin/com/threedays/domain/auth/entity/RegisterTokenTest.kt (3)

22-29: 토큰 생성 테스트 업데이트 승인 및 개선 제안

phoneNumber 매개변수가 RegisterToken.generate 메서드에 올바르게 추가되었습니다. 이는 새로운 메서드 시그니처를 정확히 반영합니다.

개선 제안: 전화번호가 토큰 클레임에 올바르게 포함되었는지 확인하는 assertion을 추가하는 것이 좋습니다. 예를 들어:

token.getOrNull()?.get("phoneNumber") shouldBe "01012345678"

이렇게 하면 전화번호가 토큰에 올바르게 인코딩되었는지 확인할 수 있습니다.


47-52: 토큰 검증 테스트 업데이트 승인 및 개선 제안

phoneNumber 매개변수가 RegisterToken.generate 메서드에 올바르게 추가되었습니다. 이는 새로운 메서드 시그니처를 정확히 반영합니다.

개선 제안: 토큰 검증 과정에서 전화번호가 올바르게 처리되는지 확인하는 단계를 추가하는 것이 좋습니다. 예를 들어:

val verifiedToken = RegisterToken.verify(registerToken.value, secret)
verifiedToken.phoneNumber shouldBe phoneNumber

이렇게 하면 생성된 토큰에서 전화번호가 올바르게 추출되고 검증되는지 확인할 수 있습니다.


Line range hint 1-134: 전체 테스트 스위트 변경 검토 및 제안

RegisterToken 클래스의 generate 메서드에 phoneNumber 매개변수를 추가한 변경사항이 모든 관련 테스트 케이스에 일관되게 적용되었습니다. 이는 회원 가입 API 구현이라는 PR의 목적과 잘 부합합니다.

개선 제안:

  1. phoneNumber의 유효성 검사 테스트 추가: 잘못된 형식의 전화번호를 사용할 때 예외가 발생하는지 확인하는 테스트를 추가하세요.
  2. 다양한 phoneNumber 값 테스트: 다양한 유효한 전화번호 형식(예: 국제 번호)에 대한 테스트를 추가하여 호환성을 확인하세요.
  3. phoneNumber 없이 토큰 생성 시도: phoneNumber가 null이거나 누락된 경우 적절한 예외가 발생하는지 확인하는 테스트를 추가하세요.

이러한 추가 테스트들은 RegisterToken 클래스의 견고성과 신뢰성을 더욱 향상시킬 것입니다.

application/src/main/kotlin/com/threedays/application/user/port/inbound/RegisterUser.kt (2)

18-31: Command 데이터 클래스의 주석에서 불필요한 @return 제거 필요

@return 회원 주석은 데이터 클래스에서는 필요하지 않습니다. @return은 함수의 반환 값을 설명할 때 사용되며, 데이터 클래스에서는 일반적으로 사용되지 않습니다. 해당 주석을 제거해주세요.

적용 제안:

-     * @return 회원

45-55: expiresIn 필드의 의미 명확화

expiresIn은 액세스 토큰의 만료 시간을 나타냅니다. 해당 값이 만료 시각(타임스탬프)인지, 또는 남은 시간(초 단위)인지를 명확히 하기 위해 변수명이나 주석을 보완해주시면 좋겠습니다.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 40f3d4a and b27ba98.

📒 Files selected for processing (16)
  • application/src/main/kotlin/com/threedays/application/auth/port/inbound/IssueLoginTokens.kt (1 hunks)
  • application/src/main/kotlin/com/threedays/application/auth/service/AuthCodeService.kt (4 hunks)
  • application/src/main/kotlin/com/threedays/application/auth/service/AuthTokenService.kt (1 hunks)
  • application/src/main/kotlin/com/threedays/application/user/port/inbound/RegisterUser.kt (2 hunks)
  • application/src/main/kotlin/com/threedays/application/user/service/UserService.kt (3 hunks)
  • application/src/test/kotlin/com/threedays/application/auth/service/AuthCodeServiceTest.kt (1 hunks)
  • application/src/testFixtures/kotlin/com/threedays/application/auth/service/IssueLoginTokensStub.kt (1 hunks)
  • bootstrap/api/src/main/kotlin/com/threedays/bootstrap/api/user/UserController.kt (1 hunks)
  • build.gradle.kts (1 hunks)
  • domain/src/main/kotlin/com/threedays/domain/auth/entity/RegisterToken.kt (3 hunks)
  • domain/src/main/kotlin/com/threedays/domain/user/entity/User.kt (1 hunks)
  • domain/src/main/kotlin/com/threedays/domain/user/entity/UserDesiredPartner.kt (1 hunks)
  • domain/src/test/kotlin/com/threedays/domain/auth/entity/RegisterTokenTest.kt (4 hunks)
  • infrastructure/persistence/src/main/kotlin/com/threedays/persistence/user/entity/UserDesiredPartnerJpaEntity.kt (4 hunks)
  • infrastructure/persistence/src/main/resources/db/migration/V1__init_user.sql (1 hunks)
  • openapi (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • openapi
🔇 Additional comments (35)
domain/src/main/kotlin/com/threedays/domain/user/entity/UserDesiredPartner.kt (1)

8-8: birthYearRange 속성을 nullable로 변경한 것에 대한 검토

이 변경은 사용자가 원하는 파트너의 생년 범위를 선택적으로 지정할 수 있게 해주어 회원 가입 API에 더 많은 유연성을 제공합니다. 그러나 다음 사항들을 고려해야 합니다:

  1. 기존 코드에서 birthYearRange가 항상 존재한다고 가정하는 부분이 있다면 수정이 필요할 수 있습니다.
  2. 이 속성을 사용하는 코드에서 null 체크를 추가해야 할 수 있습니다.
  3. 이 엔티티가 데이터베이스에 저장된다면 스키마 변경이 필요할 수 있습니다.

다음 스크립트를 실행하여 birthYearRange 사용 현황을 확인하세요:

이 결과를 바탕으로 필요한 코드 수정을 진행하세요.

application/src/main/kotlin/com/threedays/application/auth/port/inbound/IssueLoginTokens.kt (2)

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

패키지 구조와 임포트가 클린 아키텍처 원칙을 잘 따르고 있습니다. 애플리케이션 계층과 도메인 계층이 명확히 분리되어 있어 좋습니다.


11-11: Command 데이터 클래스가 적절히 정의되었습니다.

Command 데이터 클래스가 invoke 메서드의 입력을 효과적으로 캡슐화하고 있습니다. 인터페이스 내부에 중첩하여 정의한 것도 관련 코드를 함께 유지하는 좋은 방법입니다.

application/src/testFixtures/kotlin/com/threedays/application/auth/service/IssueLoginTokensStub.kt (1)

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

패키지 선언과 필요한 모든 클래스들이 올바르게 임포트되어 있습니다. 코드의 구조가 잘 정리되어 있습니다.

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

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

패키지 선언과 임포트 문이 클래스의 기능에 맞게 잘 구성되어 있습니다. 불필요한 임포트가 없고, 필요한 모든 클래스가 임포트되어 있습니다.

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

34-35: birth_year_range_startbirth_year_range_end 컬럼이 nullable로 변경되었습니다.

이 변경으로 인해 파트너 선호도 설정에 더 많은 유연성이 생겼습니다. 하지만 이로 인해 애플리케이션 로직에 영향을 줄 수 있습니다.

다음 사항들을 확인해 주세요:

  1. 애플리케이션 코드가 이 필드들의 null 값을 적절히 처리할 수 있는지 확인하세요.
  2. 이 변경이 기존 데이터나 쿼리에 영향을 주지 않는지 확인하세요.
  3. 필요하다면 마이그레이션 스크립트를 통해 기존 데이터를 업데이트하는 것을 고려해 보세요.

이 변경사항과 관련된 애플리케이션 코드 업데이트나 마이그레이션 스크립트 작성에 도움이 필요하시면 말씀해 주세요.


Line range hint 1-63: 전체적인 스키마 설계에 대한 검토 의견

스키마 설계가 전반적으로 잘 되어 있지만, 몇 가지 개선할 점이 있습니다:

  1. 외래 키 제약 조건:
    현재 테이블 간의 관계가 명시적으로 정의되어 있지 않습니다. 데이터 무결성을 위해 외래 키 제약 조건을 추가하는 것이 좋습니다.

  2. 명명 규칙:
    user_desired_partner_job_occupations 테이블은 다른 테이블들과 명명 규칙이 다릅니다. 일관성을 위해 user_desired_partner_jobs로 변경을 고려해 보세요.

  3. locations 테이블:
    user_profile 컬럼이 locations 테이블에 있는 것이 이상해 보입니다. 이 관계를 user_profiles 테이블에서 관리하는 것이 더 적절할 것 같습니다.

다음과 같은 변경을 고려해 보세요:

  1. 외래 키 제약 조건 추가:
ALTER TABLE user_profiles
ADD CONSTRAINT fk_user_profiles_company
FOREIGN KEY (company) REFERENCES companies(id);

ALTER TABLE user_profiles
ADD CONSTRAINT fk_user_profiles_job
FOREIGN KEY (job) REFERENCES jobs(id);

ALTER TABLE users
ADD CONSTRAINT fk_users_profile
FOREIGN KEY (profile_id) REFERENCES user_profiles(id);

ALTER TABLE users
ADD CONSTRAINT fk_users_desired_partner
FOREIGN KEY (desired_partner_id) REFERENCES user_desired_partners(id);
  1. user_desired_partner_job_occupations 테이블 이름 변경:
RENAME TABLE user_desired_partner_job_occupations TO user_desired_partner_jobs;
  1. locations 테이블에서 user_profile 컬럼 제거하고 user_profiles 테이블에 location_id 추가:
ALTER TABLE locations
DROP COLUMN user_profile;

ALTER TABLE user_profiles
ADD COLUMN location_id BINARY(16),
ADD CONSTRAINT fk_user_profiles_location
FOREIGN KEY (location_id) REFERENCES locations(id);

이러한 변경 사항들이 애플리케이션의 요구사항과 일치하는지 확인해 주세요. 특히 locationsuser_profiles 간의 관계 변경이 비즈니스 로직에 부합하는지 검토가 필요합니다.

domain/src/main/kotlin/com/threedays/domain/user/entity/User.kt (1)

35-35: partnerBirthYearRange를 nullable로 변경한 것은 좋은 개선입니다.

이 변경으로 회원 가입 과정에서 더 많은 유연성을 제공할 수 있게 되었습니다. 하지만 몇 가지 고려해야 할 사항이 있습니다:

  1. 이 변경이 코드베이스의 다른 부분에 미치는 영향을 확인해주세요. partnerBirthYearRange를 사용하는 다른 메서드나 클래스가 이 nullable 타입을 올바르게 처리하는지 확인이 필요합니다.

  2. UserDesiredPartner 생성자에서 partnerBirthYearRange에 대한 null 체크를 추가하는 것이 좋겠습니다. 현재는 null 값을 그대로 전달하고 있어 잠재적인 NullPointerException의 위험이 있습니다.

다음 스크립트를 실행하여 partnerBirthYearRange의 사용을 확인해주세요:

infrastructure/persistence/src/main/kotlin/com/threedays/persistence/user/entity/UserDesiredPartnerJpaEntity.kt (4)

5-5: LGTM: UUIDTypeId 임포트 추가

UUIDTypeId 임포트 추가는 타입 안전성을 향상시키는 좋은 변경사항입니다. 이는 도메인 주도 설계(DDD) 원칙을 따르는 것으로 보입니다.


23-24: LGTM: 생년월일 범위를 nullable로 변경

birthYearRangeStartbirthYearRangeEnd를 nullable로 변경한 것은 좋은 결정입니다. 이를 통해 원하는 파트너의 나이 범위가 필수가 아닐 수 있는 유연성을 제공합니다.


33-46: LGTM: 프로퍼티 및 어노테이션 업데이트

birthYearRangeStartbirthYearRangeEnd 프로퍼티를 nullable로 변경하고, 해당 @Column 어노테이션에 nullable = true를 추가한 것은 적절합니다. 이는 데이터베이스 스키마가 새로운 nullable 특성과 일치하도록 보장합니다.


74-75: LGTM: toJpaEntity 함수의 null 안전성 개선

toJpaEntity 함수에서 안전 호출 연산자(?.)를 사용하여 birthYearRange 속성에 접근하도록 변경한 것은 훌륭합니다. 이는 birthYearRange가 null일 수 있는 가능성을 적절히 처리하며, 잠재적인 null 포인터 예외를 방지합니다.

build.gradle.kts (1)

61-62: 테스트 픽스처에 대한 의존성 추가가 적절해 보입니다.

fixture.monkey 라이브러리를 테스트 픽스처 구현에 추가한 것은 좋은 선택입니다. 이는 다음과 같은 이점을 제공할 수 있습니다:

  1. 테스트 데이터 생성의 용이성
  2. 테스트 코드의 재사용성 향상
  3. 테스트 유지보수의 간소화

이 변경사항은 프로젝트의 테스트 기능을 강화하고 전반적인 코드 품질을 향상시킬 것으로 보입니다.

domain/src/test/kotlin/com/threedays/domain/auth/entity/RegisterTokenTest.kt (2)

4-4: LGTM: PhoneNumber 가져오기 추가

PhoneNumber 클래스를 가져오는 import 문이 올바르게 추가되었습니다. 이는 테스트에서 PhoneNumber를 사용하기 위해 필요한 변경사항입니다.


118-123: 잘못된 시크릿 테스트 업데이트 승인

phoneNumber 매개변수가 RegisterToken.generate 메서드에 올바르게 추가되었습니다. 이 변경사항은 새로운 메서드 시그니처를 정확히 반영하며, 테스트 케이스가 적절하게 업데이트되었습니다.

이 테스트는 여전히 잘못된 시크릿이 사용될 때 InvalidRegisterTokenException을 올바르게 확인하고 있습니다. 좋은 업데이트입니다.

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

51-52: AuthCodeService 생성자 변경이 적절해 보입니다.

AuthCodeService 생성자에 issueLoginTokens를 추가한 것은 로그인 토큰 발급 로직의 분리나 새로운 기능 추가를 위한 것으로 보입니다. 이 변경은 적절해 보입니다.

다만, 이 변경이 다른 부분에 영향을 미치지 않는지 확인이 필요합니다. 다음 스크립트를 실행하여 AuthCodeService의 다른 사용 사례를 확인해 주세요:

#!/bin/bash
# AuthCodeService의 다른 인스턴스화를 찾습니다.
rg --type kotlin "AuthCodeService\\(" -A 5

46-52: 테스트 케이스 검토 제안

issueLoginTokens의 추가와 AuthCodeService 생성자의 변경으로 인해 기존 테스트 케이스들이 여전히 모든 시나리오를 적절히 커버하고 있는지 확인이 필요합니다. 특히 토큰 발급과 관련된 테스트 케이스들을 검토하고, 필요하다면 새로운 테스트 케이스를 추가하는 것이 좋겠습니다.

다음 스크립트를 실행하여 토큰 관련 테스트 케이스를 확인해 주세요:

#!/bin/bash
# 토큰 관련 테스트 케이스를 찾습니다.
rg --type kotlin "Token" "application/src/test/kotlin/com/threedays/application/auth/service/AuthCodeServiceTest.kt"

46-46: IssueLoginTokensStub에 대한 추가 정보가 필요합니다.

IssueLoginTokensStub의 추가는 로그인 토큰 발급과 관련된 새로운 기능을 나타내는 것 같습니다. 이 변경의 목적과 IssueLoginTokensStub의 역할에 대해 자세히 설명해 주시겠습니까? 이 변경이 테스트 케이스에 어떤 영향을 미치는지 이해하는 데 도움이 될 것 같습니다.

✅ Verification successful

IssueLoginTokensStub 클래스의 정의를 찾기 위해 전체 코드베이스에서 검색을 진행하겠습니다.


IssueLoginTokensStub 클래스의 내용을 확인하기 위해 해당 파일의 내용을 가져오겠습니다.


변경사항 검증 완료

IssueLoginTokensStub 클래스가 올바르게 정의되어 있으며, 테스트에서 적절하게 사용되고 있습니다. 코드에 문제가 발견되지 않았습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# IssueLoginTokensStub 클래스의 정의를 찾습니다.
rg --type kotlin "class IssueLoginTokensStub"

Length of output: 907


Script:

#!/bin/bash
# IssueLoginTokensStub 클래스의 정의를 찾기 위해 전체 코드베이스에서 검색합니다.
rg --type kotlin "class IssueLoginTokensStub"

Length of output: 174


Script:

#!/bin/bash
# IssueLoginTokensStub.kt 파일의 내용을 출력합니다.
cat application/src/testFixtures/kotlin/com/threedays/application/auth/service/IssueLoginTokensStub.kt

Length of output: 1345

application/src/main/kotlin/com/threedays/application/user/port/inbound/RegisterUser.kt (2)

40-40: partnerBirthYearRange의 null 처리 검증 필요

partnerBirthYearRange가 nullable로 변경되어 기본값이 null로 설정되었습니다. 따라서 이 변수를 사용하는 로직에서 null에 대한 처리가 필요합니다. 모든 관련 코드에서 null 체크가 이루어지고 있는지 확인해주세요.

다음 스크립트를 실행하여 partnerBirthYearRange 사용 시 null 체크 여부를 확인할 수 있습니다:

#!/bin/bash
# Description: `partnerBirthYearRange` 사용 시 null 체크가 이루어지는지 검증합니다.

# Test: `partnerBirthYearRange` 사용부 검색 및 null 체크 확인
rg --type kotlin -A 5 -B 5 'partnerBirthYearRange' | rg -C 5 'null\|?:'

16-16: invoke 메소드 반환 타입 변경에 따른 호출부 검토 필요

invoke 메소드의 반환 타입이 User에서 Result로 변경되었습니다. 이로 인해 이 메소드를 호출하는 모든 부분에서 반환 타입 변경에 따른 수정이 필요합니다. 모든 호출부가 올바르게 업데이트되었는지 확인해주세요.

다음 스크립트를 실행하여 invoke 메소드의 호출부를 확인할 수 있습니다:

bootstrap/api/src/main/kotlin/com/threedays/bootstrap/api/user/UserController.kt (1)

37-37: birthYearRange가 null인 경우 로직 확인 필요

registerUserRequest.desiredPartner.birthYearRange가 null일 경우 partnerBirthYearRange도 null이 됩니다. 이후 로직에서 이 값에 대한 처리가 올바르게 이루어지는지 확인이 필요합니다.

application/src/main/kotlin/com/threedays/application/user/service/UserService.kt (4)

3-4: 필요한 의존성이 올바르게 추가되었습니다

AuthPropertiesIssueLoginTokens를 import하여 토큰 발급 및 인증 설정을 위한 의존성이 정확하게 추가되었습니다.


23-24: 생성자에 새로운 의존성이 주입되었습니다

생성자에 issueLoginTokensauthProperties가 추가되어 서비스에서 로그인 토큰 발급 및 인증 속성을 사용할 수 있게 되었습니다.


52-56: 회원 가입 결과로 토큰 정보를 반환합니다

회원 가입 후 액세스 토큰, 리프레시 토큰 및 만료 시간을 반환하도록 구현되었습니다. 이는 사용자 경험을 향상시키는 올바른 접근입니다.


28-28: 메서드 반환 타입 변경으로 인한 영향 확인 필요

override fun invoke(command: RegisterUser.Command): User에서 override fun invoke(command: RegisterUser.Command): RegisterUser.Result로 반환 타입이 변경되었습니다. 이로 인해 이 메서드를 호출하는 모든 부분에서의 영향을 확인해야 합니다.

다음 스크립트를 실행하여 호출부의 영향을 확인할 수 있습니다:

✅ Verification successful

메서드 반환 타입 변경 확인 완료

RegisterUser.invoke 메서드의 반환 타입 변경으로 인한 호출부의 영향이 발견되지 않았습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: invoke 메서드 호출부에서 반환 타입 변경으로 인한 영향 확인

rg --type kotlin 'RegisterUser\.invoke' -A 5

Length of output: 46


Script:

#!/bin/bash
# Description: RegisterUser.invoke 메서드 호출부에서 반환 타입 변경의 영향 확인을 위한 ast-grep 사용

ast-grep --lang kotlin --pattern '
call_expression {
  function: field_identifier: "invoke"
}
' .

Length of output: 99

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

4-4: IssueLoginTokens 의 적절한 Import

IssueLoginTokens가 성공적으로 import되어 토큰 발급 로직의 모듈화에 이바지합니다.


25-26: 생성자에 issueLoginTokens 주입 추가

생성자에 issueLoginTokens가 추가되어 토큰 발급 로직이 서비스로부터 분리되고 재사용성을 높였습니다.


63-63: RegisterToken 생성 시 phoneNumber 포함

RegisterToken 생성 시 phoneNumber를 포함하여 해당 토큰이 올바른 사용자와 연관되도록 개선되었습니다.


80-81: 토큰 발급 로직의 모듈화 및 개선

issueLoginTokens.invoke를 통해 액세스 토큰과 리프레시 토큰을 발급하도록 변경되어 토큰 발급 로직이 모듈화되고 코드의 재사용성이 향상되었습니다.

domain/src/main/kotlin/com/threedays/domain/auth/entity/RegisterToken.kt (6)

4-4: 필요한 import 추가

PhoneNumber 클래스를 사용하기 위해 필요한 import 문이 추가되었습니다.


19-19: PHONE_NUMBER_CLAIM 상수 추가

JWT의 커스텀 클레임에서 사용할 PHONE_NUMBER_CLAIM 상수가 추가되었습니다.


33-35: JWT에 phoneNumber 커스텀 클레임 추가

phoneNumber를 JWT의 커스텀 클레임에 추가하여 토큰 생성 시 전화번호 정보를 포함하도록 수정되었습니다.


39-39: RegisterToken 생성 시 phoneNumber 포함

토큰 생성 과정에서 RegisterToken 인스턴스를 생성할 때 phoneNumber를 포함하도록 변경되었습니다.


60-64: verify 함수에서 phoneNumber 추출 및 검증

verify 함수에서 JWT의 커스텀 클레임에서 phoneNumber를 안전하게 추출하고 검증하는 로직이 추가되었습니다. 올바른 phoneNumber가 없을 경우 InvalidRegisterTokenException을 발생시킵니다.


11-14: RegisterToken 클래스에 phoneNumber 필드 추가

RegisterToken 데이터 클래스에 phoneNumber: PhoneNumber 필드가 추가되었습니다. 이로 인해 생성자 시그니처가 변경되었으므로, 이 클래스를 인스턴스화하는 모든 코드가 업데이트되었는지 확인해주세요.

아래 스크립트를 실행하여 RegisterToken 생성자 사용 부분을 확인할 수 있습니다:

✅ Verification successful

RegisterToken 생성자 호출부가 모두 업데이트되었습니다.

RegisterToken 클래스의 생성자에 phoneNumber 필드가 추가된 후, 모든 인스턴스화가 올바르게 업데이트되었습니다. 추가적인 수정이 필요하지 않습니다.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 설명: RegisterToken 생성자 호출부를 찾아 새로운 시그니처에 맞게 수정되었는지 확인합니다.

rg --type kt 'RegisterToken\(' -A 2

Length of output: 74


Script:

#!/bin/bash
# 설명: RegisterToken 생성자 호출부를 찾아 새로운 시그니처에 맞게 수정되었는지 확인합니다.

rg --glob "*.kt" 'RegisterToken\(' -A 2

Length of output: 919


Script:

#!/bin/bash
# 설명: RegisterToken을 사용하는 모든 Kotlin 파일을 찾아 새로운 시그니처에 맞게 수정되었는지 확인합니다.

rg --glob "*.kt" 'RegisterToken\('

Length of output: 377

@waterfogSW waterfogSW merged commit afeb0a0 into main Oct 6, 2024
3 checks passed
@waterfogSW waterfogSW deleted the feat/user-register branch October 6, 2024 05:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant