Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
90271b7
[BOOK-140] chore: apis - 패키지 이동
move-hoon Jul 14, 2025
e9cb5b4
[BOOK-140] refactor: apis - vo가 아닌 dto를 반화하도록 변경
move-hoon Jul 14, 2025
29e6270
[BOOK-140] chore: apis - 개행 삭제
move-hoon Jul 14, 2025
81d9a01
[BOOK-140] chore: apis - 필요없는 명세 삭제
move-hoon Jul 14, 2025
37c54f6
[BOOK-140] feat: apis - 애플리케이션 레이어에 사용될 DTO 정의
move-hoon Jul 14, 2025
f01cab4
[BOOK-140] feat: domain - 도메인 전용 예외 클래스 구현
move-hoon Jul 14, 2025
baf7c6c
[BOOK-140] refactor: domain - 역할 부여 여부에 따라 정적 팩토리 메서드 분리
move-hoon Jul 14, 2025
7b93e32
[BOOK-140] chore: apis - 패키지 이동
move-hoon Jul 14, 2025
be67880
[BOOK-140] chore: apis - 패키지 이동
move-hoon Jul 14, 2025
8499053
[BOOK-140] refactor: apis - 정적팩토리 메서드 인자로 vo를 받도록 변경
move-hoon Jul 14, 2025
fc5114c
[BOOK-140] refactor: apis - 컨트롤러에서 usecase로 갈때 dto를 받도록 변경
move-hoon Jul 14, 2025
d7017d4
[BOOK-140] refactor: apis - valid 로직 도입
move-hoon Jul 14, 2025
5a4f5ab
[BOOK-140] refactor: domain - 인증 로직에 사용되는 vo 구현
move-hoon Jul 14, 2025
8db150f
[BOOK-140] refactor: domain, infra - 도메인 서비스에서 해당하는 vo를 리턴하도록 변경
move-hoon Jul 14, 2025
92fcf50
[BOOK-140] chore: infra - 새로운 메서드 추가
move-hoon Jul 14, 2025
d5d0046
[BOOK-140] refactor: apis - 인증 로직을 클린 아키텍처에 맞게 리팩토링
move-hoon Jul 14, 2025
becef68
[BOOK-140] chore: apis - dto 필드 검증 NotBlank로 변경
move-hoon Jul 14, 2025
c7ece94
[BOOK-140] chore: apis - 가시성을 위한 개행 추가
move-hoon Jul 14, 2025
4d4ad7b
[BOOK-140] refactor: apis, domain - 코드리뷰 반영
move-hoon Jul 15, 2025
dc25553
[BOOK-140] refactor: apis, domain, infra - 코드리뷰 반영
move-hoon Jul 15, 2025
d42517b
[BOOK-140] refactor: domain - UuidGenerator 유틸 클래스로 아이디 생성 방식 변경
move-hoon Jul 15, 2025
0313411
Merge branch 'develop' into BOOK-140-refactor/#40
move-hoon Jul 15, 2025
873ecb3
fix: sub 클레임 값을 UUID로 변환해 Authentication 객체의 principal로 설정하도록 수정 (#44)
move-hoon Jul 15, 2025
0b5f8a4
[BOOK-140] refactor: domain, infra - jpa 메서드 재정의
move-hoon Jul 15, 2025
f9c38e3
[BOOK-140] feat: domain - 리프레쉬 토큰 관련 도메인 에러 클래스 생성
move-hoon Jul 15, 2025
7c8eb79
[BOOK-140] chore: domain, apis - 메서드 네이밍 변경
move-hoon Jul 15, 2025
491594d
[BOOK-140] chore: domain - 필요 없는 중괄호 제거
move-hoon Jul 15, 2025
0e27462
[BOOK-140] feat: doamin, infra - RefreshToken 도메인에 Value Class 적용 및 생…
move-hoon Jul 15, 2025
4842ba6
[BOOK-140] feat: apis - 비즈니스 로직에 사용될 요청 및 응답 dto 구현
move-hoon Jul 15, 2025
6ae0a6e
[BOOK-140] refactor: domain - 무조건 true인 검증 제거
move-hoon Jul 15, 2025
b876e9d
[BOOK-140] refactor: requestDTO를 받도록 변경
move-hoon Jul 15, 2025
0250e3a
[BOOK-140] refactor: apis - redis 관련 인증도메인 리팩토링
move-hoon Jul 15, 2025
be84076
[BOOK-140] refactor: apis, infra - 값 기반 비교를 위해 객체들을 VO(Value Object)로…
move-hoon Jul 15, 2025
681db36
[BOOK-140] refactor: infra - this 추가
move-hoon Jul 15, 2025
563117d
[BOOK-140] refactor: apis, domain - vo 매핑으로 인한 변동사항 반영
move-hoon Jul 15, 2025
b300a52
[BOOK-140] refactor: domain, infra - 값 기반 비교를 위해 객체들을 VO(Value Object…
move-hoon Jul 15, 2025
914d72b
[BOOK-140] refactor: apis, domain - 값 객체 매핑으로 인한 변동사항 반영
move-hoon Jul 15, 2025
7c2c699
[BOOK-140] feat: domain - 책 관련 도메인 예외 클래스 생성
move-hoon Jul 15, 2025
187496f
[BOOK-140] feat: domain - 책 관련 도메인 예외 클래스 생성
move-hoon Jul 15, 2025
eeec87e
[BOOK-140] refactor: domain, infra - 생성된 도메인 예외를 이용해 로직 리팩토링
move-hoon Jul 15, 2025
0da7e95
[BOOK-140] chore: apis, domain - vo 이름 구체화
move-hoon Jul 15, 2025
0126cbf
[BOOK-140] chore: infra - 패키지 변경
move-hoon Jul 15, 2025
902106e
[BOOK-140] refactor: domain, infra - 값 기반 비교를 위해 객체들을 VO(Value Object…
move-hoon Jul 15, 2025
c8421a8
[BOOK-140] refactor: domain, apis - VO 래핑으로 인한 변동사항 반영
move-hoon Jul 15, 2025
6660280
[BOOK-140] refactor: apis, domain, infra - 코드레빗 리뷰 반영
move-hoon Jul 15, 2025
0d428b4
[BOOK-140] refactor: apis - 코드레빗 리뷰 반영
move-hoon Jul 15, 2025
332e7a1
[BOOK-140] chore: domain - 메서드 위치 변경
move-hoon Jul 15, 2025
1a2844f
[BOOK-140] chore: apis - 가독성을 위한 개행 추가
move-hoon Jul 15, 2025
ffe911e
[BOOK-140] feat: global-utils - email, isbn 전역 validator 구현
move-hoon Jul 17, 2025
75d80e8
[BOOK-140] refactor: domain - email, isbn 전역 validator 적용
move-hoon Jul 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,13 @@ class AuthController(

@PostMapping("/signin")
override fun signIn(@RequestBody @Valid request: SocialLoginRequest): ResponseEntity<AuthResponse> {
val credentials = SocialLoginRequest.toCredentials(request)
val tokenPair = authUseCase.signIn(credentials)
val tokenPair = authUseCase.signIn(request)
return ResponseEntity.ok(AuthResponse.fromTokenPair(tokenPair))
}

@PostMapping("/refresh")
override fun refreshToken(@RequestBody @Valid request: TokenRefreshRequest): ResponseEntity<AuthResponse> {
val tokenPair = authUseCase.reissueTokenPair(request.validRefreshToken())
val tokenPair = authUseCase.reissueTokenPair(request)
return ResponseEntity.ok(AuthResponse.fromTokenPair(tokenPair))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,14 @@ import org.springframework.security.core.annotation.AuthenticationPrincipal
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.yapp.apis.auth.dto.request.SocialLoginRequest
import org.yapp.apis.auth.dto.request.TokenRefreshRequest
import org.yapp.apis.auth.dto.response.AuthResponse
import org.yapp.apis.auth.dto.response.UserProfileResponse
import org.yapp.globalutils.exception.ErrorResponse
import java.util.UUID
import java.util.*
Copy link

@coderabbitai coderabbitai bot Jul 14, 2025

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

wildcard import 사용을 재고해보세요.

java.util.* wildcard import 대신 java.util.UUID를 명시적으로 import하는 것이 더 명확하고 예측 가능합니다.

다음과 같이 수정하는 것을 권장합니다:

-import java.util.*
+import java.util.UUID
🤖 Prompt for AI Agents
In apis/src/main/kotlin/org/yapp/apis/auth/controller/AuthControllerApi.kt at
line 20, replace the wildcard import 'java.util.*' with an explicit import of
'java.util.UUID' to improve code clarity and maintainability.

Copy link
Member

Choose a reason for hiding this comment

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

이부분 반영되면 좋을 것 같아요!

Copy link

Choose a reason for hiding this comment

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

@minwoo1999 네, 맞습니다! 명시적인 import가 코드 가독성과 유지보수성에 더 좋겠네요.

이전에 학습한 내용에 따르면, IntelliJ IDEA에서도 와일드카드 임포트를 방지하는 설정을 통해 이런 상황을 미연에 방지할 수 있습니다. File > Settings > Editor > Code Style > Java > Imports 탭에서 "Class count to use import with '*'" 값을 높게 설정하시면 도움이 될 것 같습니다.

해당 변경사항을 적용해드리겠습니다.

Task: Replace wildcard import with explicit import

  • Replace java.util.* with java.util.UUID in AuthControllerApi.kt

🧠 Learnings used
Learnt from: hoonyworld
PR: YAPP-Github/Reed-Server#31
File: apis/src/main/kotlin/org/yapp/apis/book/controller/BookControllerApi.kt:13-13
Timestamp: 2025-07-08T14:24:44.340Z
Learning: IntelliJ IDEA에서 와일드카드 임포트를 방지하는 설정 방법: File > Settings > Editor > Code Style > Java > Imports 탭에서 "Class count to use import with '*'" 값을 높게 설정(예: 500)하면 해당 임계값 이하에서는 와일드카드 임포트가 자동으로 사용되지 않음. 와일드카드 임포트 관련 리뷰 시 이 IDE 설정 방법도 함께 안내하면 좋음.

Learnt from: hoonyworld
PR: YAPP-Github/Reed-Server#31
File: apis/src/main/kotlin/org/yapp/apis/book/controller/BookControllerApi.kt:13-13
Timestamp: 2025-07-08T14:24:44.340Z
Learning: hoonyworld가 와일드카드 임포트 관련하여 IDE 설정을 통한 자동 최적화 방법을 추천했습니다. 향후 임포트 관련 리뷰 시 IDE 설정 방법도 함께 안내하는 것이 좋겠습니다.

⏳ Preparing changes...

Copy link

Choose a reason for hiding this comment

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

A summary of the changes CodeRabbit can apply:

  • Update the AuthControllerApi.kt file by replacing the wildcard import of java.util.* with an explicit import of java.util.UUID to improve code clarity and maintainability.
  • ✅ Create PR with these edits
  • 📌 Create commit in current branch
  • 📋 Get copyable edits


@Tag(name = "Authentication", description = "Authentication API")
@RequestMapping("/api/v1/auth")
interface AuthControllerApi {

@Operation(
Expand Down
35 changes: 0 additions & 35 deletions apis/src/main/kotlin/org/yapp/apis/auth/dto/UserCreateInfo.kt

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package org.yapp.apis.auth.dto.request

import io.swagger.v3.oas.annotations.media.Schema
import jakarta.validation.constraints.NotBlank
import org.yapp.apis.auth.dto.response.RefreshTokenResponse

@Schema(
name = "DeleteTokenRequest",
description = "Request DTO for deleting a refresh token"
)
data class DeleteTokenRequest(
@field:NotBlank(message = "Refresh token must not be blank.")
@Schema(description = "Refresh token to be deleted", example = "eyJhbGciOiJIUz...")
val refreshToken: String? = null
) {
fun validRefreshToken() = refreshToken!!
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

강제 언래핑으로 인한 잠재적 런타임 예외 위험이 있습니다.

validRefreshToken() 메서드에서 !! 연산자를 사용하는 것은 검증이 실패할 경우 KotlinNullPointerException을 발생시킬 위험이 있습니다. 더 안전한 접근 방식을 고려해보세요.

다음과 같이 안전한 방식으로 개선할 수 있습니다:

-    fun validRefreshToken() = refreshToken!!
+    fun validRefreshToken(): String {
+        return refreshToken ?: throw IllegalStateException("Refresh token must not be null after validation")
+    }

또는 검증된 상태에서만 호출되는 것이 보장된다면 주석으로 명시하는 것도 좋은 방법입니다.

🤖 Prompt for AI Agents
In apis/src/main/kotlin/org/yapp/apis/auth/dto/request/DeleteTokenRequest.kt at
line 16, the use of the !! operator in validRefreshToken() risks a runtime
exception if refreshToken is null. To fix this, replace the forced unwrap with a
safe access pattern such as returning a nullable type or throwing a custom
exception with a clear message. Alternatively, if the method is only called when
refreshToken is guaranteed non-null, add a comment to document this assumption
clearly.


companion object {
fun from(refreshTokenResponse: RefreshTokenResponse): DeleteTokenRequest {
return DeleteTokenRequest(refreshToken = refreshTokenResponse.refreshToken)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package org.yapp.apis.auth.dto.request

import io.swagger.v3.oas.annotations.media.Schema
import jakarta.validation.constraints.NotBlank
import org.yapp.apis.auth.dto.response.UserCreateInfoResponse
import org.yapp.apis.util.NicknameGenerator
import org.yapp.domain.user.ProviderType

@Schema(
name = "FindOrCreateUserRequest",
description = "Request DTO for finding an existing user or creating a new one during social login"
)
data class FindOrCreateUserRequest private constructor(
@Schema(
description = "사용자 이메일",
example = "[email protected]", nullable = true)
val email: String? = null,

@Schema(
description = "사용자 닉네임",
example = "코딩하는곰",
nullable = true
)
val nickname: String? = null,

@Schema(
description = "사용자 프로필 이미지 URL",
example = "https://example.com/image.jpg",
nullable = true
)
val profileImageUrl: String? = null,

@Schema(
description = "소셜 로그인 제공자",
example = "KAKAO"
)
@field:NotBlank(message = "providerType은 필수입니다.")
val providerType: ProviderType? = null,

@Schema(
description = "소셜 제공자에서 발급한 식별자",
example = "12345678901234567890"
)
@field:NotBlank(message = "providerId는 필수입니다.")
val providerId: String? = null
) {
fun getOrDefaultEmail(): String {
return email?.takeIf { it.isNotBlank() } ?: "${validProviderId()}@${validProviderType().name.lowercase()}.local"
}

fun getOrDefaultNickname(): String {
return nickname?.takeIf { it.isNotBlank() } ?: NicknameGenerator.generate()
}

fun validProviderType(): ProviderType = providerType!!
fun validProviderId(): String = providerId!!

companion object {
fun from(
userCreateInfoResponse: UserCreateInfoResponse
): FindOrCreateUserRequest {
return FindOrCreateUserRequest(
email = userCreateInfoResponse.email,
nickname = userCreateInfoResponse.nickname,
profileImageUrl = userCreateInfoResponse.profileImageUrl,
providerType = userCreateInfoResponse.providerType,
providerId = userCreateInfoResponse.providerId
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.yapp.apis.auth.dto.request

import io.swagger.v3.oas.annotations.media.Schema
import jakarta.validation.constraints.NotNull
import org.yapp.apis.auth.dto.response.UserIdResponse
import java.util.*
Copy link
Member

Choose a reason for hiding this comment

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

여기 수정 부탁드릴게요!


@Schema(
name = "FindUserIdentityRequest",
description = "Request DTO to retrieve user identity information using userId"
)
data class FindUserIdentityRequest(
@Schema(
description = "User ID (UUID format)",
example = "a1b2c3d4-e5f6-7890-1234-56789abcdef0"
)
@field:NotNull(message = "userId must not be null")
val userId: UUID? = null
) {
fun validUserId(): UUID = userId!!
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

!! 연산자 사용 시 NPE 위험이 있습니다.

validUserId() 메서드에서 !! 연산자를 사용하면 예상치 못한 NPE가 발생할 수 있습니다. 더 안전한 방법을 고려해보세요.

다음과 같이 개선할 수 있습니다:

-    fun validUserId(): UUID = userId!!
+    fun validUserId(): UUID = userId ?: throw IllegalArgumentException("userId must not be null")

또는 validation이 이미 적용되어 있다면 requireNotNull을 사용하는 것도 좋습니다:

-    fun validUserId(): UUID = userId!!
+    fun validUserId(): UUID = requireNotNull(userId) { "userId must not be null" }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fun validUserId(): UUID = userId!!
fun validUserId(): UUID = userId ?: throw IllegalArgumentException("userId must not be null")
Suggested change
fun validUserId(): UUID = userId!!
fun validUserId(): UUID = requireNotNull(userId) { "userId must not be null" }
🤖 Prompt for AI Agents
In
apis/src/main/kotlin/org/yapp/apis/auth/dto/request/FindUserIdentityRequest.kt
at line 20, the use of the !! operator in validUserId() risks throwing a
NullPointerException. To fix this, replace the !! operator with a safer null
check by using requireNotNull(userId) to explicitly validate that userId is not
null before returning it, ensuring safer code and clearer error messages.


companion object {
fun from(userIdResponse: UserIdResponse): FindUserIdentityRequest {
return FindUserIdentityRequest(userIdResponse.userId)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.yapp.apis.auth.dto.request

import io.swagger.v3.oas.annotations.media.Schema
import jakarta.validation.constraints.NotBlank
import org.yapp.apis.auth.dto.response.CreateUserResponse
import org.yapp.apis.auth.dto.response.UserAuthInfoResponse
import org.yapp.globalutils.auth.Role
import java.util.UUID

@Schema(
name = "GenerateTokenPairRequest",
description = "Request DTO to generate a new pair of access and refresh tokens"
)
data class GenerateTokenPairRequest private constructor(
@Schema(
description = "User ID",
example = "a1b2c3d4-e5f6-7890-1234-56789abcdef0"
)
@field:NotBlank(message = "userId must not be null")
val userId: UUID? = null,

@Schema(
description = "User role",
example = "USER"
)
@field:NotBlank(message = "role must not be null")
val role: Role? = null
) {

fun validUserId(): UUID = userId!!
fun validRole(): Role = role!!

Comment on lines +30 to +32
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

!! 연산자 사용으로 인한 런타임 예외 위험

nullable 필드를 non-null로 강제 변환하는 !! 연산자는 런타임 KotlinNullPointerException을 발생시킬 수 있습니다.

위의 필드를 non-null로 변경하면 이 메소드들도 불필요해집니다:

- fun validUserId(): UUID = userId!!
- fun validRole(): Role = role!!
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fun validUserId(): UUID = userId!!
fun validRole(): Role = role!!
🤖 Prompt for AI Agents
In
apis/src/main/kotlin/org/yapp/apis/auth/dto/request/GenerateTokenPairRequest.kt
around lines 30 to 32, the functions validUserId() and validRole() use the !!
operator to force unwrap nullable fields, which risks runtime
KotlinNullPointerException. To fix this, change the userId and role fields to be
non-nullable types so that these functions become unnecessary and can be removed
safely.

companion object {
fun from(response: CreateUserResponse): GenerateTokenPairRequest {
return GenerateTokenPairRequest(
userId = response.id,
role = response.role
)
}

fun from(response: UserAuthInfoResponse): GenerateTokenPairRequest {
return GenerateTokenPairRequest(
userId = response.id,
role = response.role
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package org.yapp.apis.auth.dto.request

import io.swagger.v3.oas.annotations.media.Schema
import jakarta.validation.constraints.NotBlank
import org.yapp.apis.auth.dto.AppleAuthCredentials
import org.yapp.apis.auth.dto.AuthCredentials
import org.yapp.apis.auth.dto.KakaoAuthCredentials
import org.yapp.apis.auth.strategy.AppleAuthCredentials
import org.yapp.apis.auth.strategy.AuthCredentials
import org.yapp.apis.auth.strategy.KakaoAuthCredentials
import org.yapp.apis.auth.exception.AuthErrorCode
import org.yapp.apis.auth.exception.AuthException
import org.yapp.domain.user.ProviderType
Expand All @@ -14,11 +14,19 @@ import org.yapp.domain.user.ProviderType
description = "DTO for social login requests"
)
data class SocialLoginRequest private constructor(
@Schema(description = "Type of social login provider", example = "KAKAO", required = true)
@Schema(
description = "Type of social login provider",
example = "KAKAO",
required = true
)
@field:NotBlank(message = "Provider type is required")
val providerType: String? = null,

@Schema(description = "OAuth token issued by the social provider", example = "eyJ...", required = true)
@Schema(
description = "OAuth token issued by the social provider",
example = "eyJ...",
required = true
)
@field:NotBlank(message = "OAuth token is required")
val oauthToken: String? = null
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.yapp.apis.auth.dto.request

import io.swagger.v3.oas.annotations.media.Schema
import jakarta.validation.constraints.NotBlank
import jakarta.validation.constraints.NotNull
import java.util.*
Copy link
Member

Choose a reason for hiding this comment

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

여기 수정 부탁드릴게요!


@Schema(
name = "TokenGenerateRequest",
description = "DTO containing information required to save the generated refresh token"
)
data class TokenGenerateRequest(
@field:NotNull(message = "userId must not be null")
@Schema(description = "User ID", example = "f6b7d490-1b1a-4b9f-8e8e-27f8e3a5dafa")
val userId: UUID? = null,

@field:NotBlank(message = "refreshToken must not be blank")
@Schema(description = "Generated refresh token", example = "eyJhbGciOiJIUzI1NiIsInR...")
val refreshToken: String? = null,

@field:NotNull(message = "expiration must not be null")
@Schema(description = "Refresh token expiration time (in seconds)", example = "2592000")
val expiration: Long? = null
) {
fun validUserId() = userId!!
fun validRefreshToken() = refreshToken!!
fun validExpiration() = expiration!!
Comment on lines +25 to +27
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

!! 연산자 사용으로 인한 NPE 위험이 있습니다.

validUserId(), validRefreshToken(), validExpiration() 메서드에서 !! 연산자를 사용하면 예상치 못한 NPE가 발생할 수 있습니다.

다음과 같이 개선할 수 있습니다:

-    fun validUserId() = userId!!
-    fun validRefreshToken() = refreshToken!!
-    fun validExpiration() = expiration!!
+    fun validUserId() = requireNotNull(userId) { "userId must not be null" }
+    fun validRefreshToken() = requireNotNull(refreshToken) { "refreshToken must not be blank" }
+    fun validExpiration() = requireNotNull(expiration) { "expiration must not be null" }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fun validUserId() = userId!!
fun validRefreshToken() = refreshToken!!
fun validExpiration() = expiration!!
fun validUserId() = requireNotNull(userId) { "userId must not be null" }
fun validRefreshToken() = requireNotNull(refreshToken) { "refreshToken must not be blank" }
fun validExpiration() = requireNotNull(expiration) { "expiration must not be null" }
🤖 Prompt for AI Agents
In apis/src/main/kotlin/org/yapp/apis/auth/dto/request/TokenGenerateRequest.kt
lines 25 to 27, the use of the !! operator in validUserId(),
validRefreshToken(), and validExpiration() methods can cause unexpected
NullPointerExceptions. To fix this, replace the !! operator with safe null
checks or return types that handle nullability properly, such as using Kotlin's
requireNotNull() function to throw a clear exception if the value is null, or
refactor the methods to return nullable types and handle null cases gracefully.


companion object {
fun of(userId: UUID, refreshToken: String, expiration: Long): TokenGenerateRequest {
require(refreshToken.isNotBlank()) { "Refresh token must not be blank." }
require(expiration > 0) { "Expiration must be greater than 0." }

return TokenGenerateRequest(
userId = userId,
refreshToken = refreshToken,
expiration = expiration
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,12 @@ import jakarta.validation.constraints.NotBlank
description = "DTO for requesting an access token using a refresh token"
)
data class TokenRefreshRequest private constructor(

@field:NotBlank(message = "Refresh token is required")
@Schema(
description = "Valid refresh token issued during previous authentication",
example = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
required = true
)
@field:NotBlank(message = "Refresh token is required")
val refreshToken: String? = null
Comment on lines +16 to 17
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

@NotBlank 와 nullable 타입이 상충됩니다.

@NotBlank 는 값이 null 이면 즉시 제약 위반이 발생하도록 설계되었습니다. 그런데 현재 refreshToken 타입이 String?(nullable) 이고 기본값까지 null 로 지정되어 있어, DTO 인스턴스가 생성되는 순간부터 제약 위반 상태가 됩니다. 또한 이후 !! 연산자 사용을 강제하게 되어 NPE 위험이 존재합니다.

-    @field:NotBlank(message = "Refresh token is required")
-    val refreshToken: String? = null
+    @field:NotBlank(message = "Refresh token is required")
+    val refreshToken: String

이렇게 변경하면

  1. 컴파일 단계에서 null 전달을 차단하여 불필요한 런타임 검증을 줄이고,
  2. 하단 validRefreshToken()!! 도 제거할 수 있습니다.
    DTO 생성 방식(예: @Builder, 정적 팩토리 등)이 있다면 해당 부분 역시 non-null 서명으로 맞춰주세요.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@field:NotBlank(message = "Refresh token is required")
val refreshToken: String? = null
@field:NotBlank(message = "Refresh token is required")
val refreshToken: String
🤖 Prompt for AI Agents
In apis/src/main/kotlin/org/yapp/apis/auth/dto/request/TokenRefreshRequest.kt at
lines 16-17, the refreshToken property is marked as nullable String? with a
default null value but annotated with @NotBlank, which conflicts because
@NotBlank expects a non-null value. Change the type of refreshToken to a
non-nullable String without a default value to enforce non-null at compile time,
remove the default null, and update any related builder or factory methods to
match this non-null signature. This will eliminate the need for !! operators and
reduce runtime validation.

) {
fun validRefreshToken(): String = refreshToken!!
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

불필요한 !! 제거로 NPE 위험 해소

위 필드가 non-null 로 변경되면 아래 메서드는 단순 반환으로 충분합니다.

-fun validRefreshToken(): String = refreshToken!!
+fun validRefreshToken(): String = refreshToken

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In apis/src/main/kotlin/org/yapp/apis/auth/dto/request/TokenRefreshRequest.kt at
line 19, the method validRefreshToken() uses the not-null assertion operator
(!!) on refreshToken, which can cause a NullPointerException. Since the
refreshToken field should be non-null, remove the !! operator and simply return
refreshToken directly to eliminate the unnecessary null check and avoid
potential NPE.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ data class AuthResponse private constructor(
val refreshToken: String
) {
companion object {
fun fromTokenPair(
tokenPairResponse: TokenPairResponse)
fun fromTokenPair(tokenPairResponse: TokenPairResponse)
: AuthResponse {
return AuthResponse(
accessToken = tokenPairResponse.accessToken,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.yapp.apis.auth.dto.response

import io.swagger.v3.oas.annotations.media.Schema
import org.yapp.domain.user.vo.UserIdentityVO
import org.yapp.globalutils.auth.Role
import java.util.UUID

@Schema(
name = "CreateUserResponse",
description = "Response DTO returned after successful user registration"
)
data class CreateUserResponse private constructor(
@Schema(
description = "사용자 ID",
example = "a1b2c3d4-e5f6-7890-1234-56789abcdef0"
)
val id: UUID,

@Schema(
description = "사용자 역할",
example = "USER"
)
val role: Role
Comment on lines +14 to +23
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick (assertive)

Schema description의 언어 일관성을 맞춰주세요.

Swagger 어노테이션의 description에서 한국어와 영어가 혼재되어 있습니다. API 문서의 일관성을 위해 영어로 통일하는 것을 권장합니다.

     @Schema(
-        description = "사용자 ID",
+        description = "User ID",
         example = "a1b2c3d4-e5f6-7890-1234-56789abcdef0"
     )
     val id: UUID,

     @Schema(
-        description = "사용자 역할",
+        description = "User role",
         example = "USER"
     )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
description = "사용자 ID",
example = "a1b2c3d4-e5f6-7890-1234-56789abcdef0"
)
val id: UUID,
@Schema(
description = "사용자 역할",
example = "USER"
)
val role: Role
@Schema(
description = "User ID",
example = "a1b2c3d4-e5f6-7890-1234-56789abcdef0"
)
val id: UUID,
@Schema(
description = "User role",
example = "USER"
)
val role: Role
🤖 Prompt for AI Agents
In apis/src/main/kotlin/org/yapp/apis/auth/dto/response/CreateUserResponse.kt
between lines 14 and 23, the Swagger @Schema descriptions mix Korean and English
languages. To maintain consistency in the API documentation, change all
description texts to English, ensuring uniform language usage throughout the
annotations.

) {
companion object {
fun from(identity: UserIdentityVO): CreateUserResponse {
return CreateUserResponse(
id = identity.id.value,
role = identity.role
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.yapp.apis.auth.dto.response

import io.swagger.v3.oas.annotations.media.Schema
import org.yapp.domain.token.RefreshToken.Token

@Schema(
name = "RefreshTokenResponse",
description = "Response DTO containing the issued refresh token"
)
data class RefreshTokenResponse(
@Schema(description = "The refresh token string", example = "eyJhbGciOiJIUz...")
val refreshToken: String
) {
companion object {
fun from(token: Token): RefreshTokenResponse {
return RefreshTokenResponse(refreshToken = token.value)
}
}
}
Loading