Skip to content

Commit 3706fcc

Browse files
authored
feat: 약관동의여부 API 기능개발 (#51)
* [BOOK-162] feat: apis - 약관동의 여부상태 값 확인,상태변경로직 작성(#50) * [BOOK-162] feat: domain - 내 상태 조회 시 약관동의 컬럼 추가(#50) * [BOOK-162] feat: infra - userEntity 약관동의 컬럼추가 (#50) * [BOOK-162] fix: infra - BaseTimeEntity lateinit error 해결(#50) * [BOOK-162] refactor: �apis - dto valid 추가 (#50)
1 parent beff1d0 commit 3706fcc

File tree

14 files changed

+147
-44
lines changed

14 files changed

+147
-44
lines changed

apis/src/main/kotlin/org/yapp/apis/auth/controller/AuthController.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import org.springframework.http.ResponseEntity
55
import org.springframework.security.core.annotation.AuthenticationPrincipal
66
import org.springframework.web.bind.annotation.*
77
import org.yapp.apis.auth.dto.request.SocialLoginRequest
8+
import org.yapp.apis.auth.dto.request.TermsAgreementRequest
89
import org.yapp.apis.auth.dto.request.TokenRefreshRequest
910
import org.yapp.apis.auth.dto.response.AuthResponse
1011
import org.yapp.apis.auth.dto.response.UserProfileResponse
@@ -43,4 +44,13 @@ class AuthController(
4344
val userProfile = authUseCase.getUserProfile(userId)
4445
return ResponseEntity.ok(userProfile)
4546
}
47+
48+
@PutMapping("/terms-agreement")
49+
override fun updateTermsAgreement(
50+
@AuthenticationPrincipal userId: UUID,
51+
@Valid @RequestBody request: TermsAgreementRequest
52+
): ResponseEntity<UserProfileResponse> {
53+
val userProfile = authUseCase.updateTermsAgreement(userId, request.validTermsAgreed())
54+
return ResponseEntity.ok(userProfile)
55+
}
4656
}

apis/src/main/kotlin/org/yapp/apis/auth/controller/AuthControllerApi.kt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ import org.springframework.http.ResponseEntity
1111
import org.springframework.security.core.annotation.AuthenticationPrincipal
1212
import org.springframework.web.bind.annotation.GetMapping
1313
import org.springframework.web.bind.annotation.PostMapping
14+
import org.springframework.web.bind.annotation.PutMapping
1415
import org.springframework.web.bind.annotation.RequestBody
1516
import org.yapp.apis.auth.dto.request.SocialLoginRequest
17+
import org.yapp.apis.auth.dto.request.TermsAgreementRequest
1618
import org.yapp.apis.auth.dto.request.TokenRefreshRequest
1719
import org.yapp.apis.auth.dto.response.AuthResponse
1820
import org.yapp.apis.auth.dto.response.UserProfileResponse
@@ -105,4 +107,25 @@ interface AuthControllerApi {
105107
)
106108
@GetMapping("/me")
107109
fun getUserProfile(@AuthenticationPrincipal userId: UUID): ResponseEntity<UserProfileResponse>
110+
111+
@Operation(summary = "Update terms agreement", description = "Updates the user's terms agreement status")
112+
@ApiResponses(
113+
value = [
114+
ApiResponse(
115+
responseCode = "200",
116+
description = "Terms agreement status updated successfully",
117+
content = [Content(schema = Schema(implementation = UserProfileResponse::class))]
118+
),
119+
ApiResponse(
120+
responseCode = "404",
121+
description = "User not found",
122+
content = [Content(schema = Schema(implementation = ErrorResponse::class))]
123+
)
124+
]
125+
)
126+
@PutMapping("/terms-agreement")
127+
fun updateTermsAgreement(
128+
@AuthenticationPrincipal userId: UUID,
129+
@Valid @RequestBody request: TermsAgreementRequest
130+
): ResponseEntity<UserProfileResponse>
108131
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package org.yapp.apis.auth.dto.request
2+
3+
import io.swagger.v3.oas.annotations.media.Schema
4+
import jakarta.validation.constraints.NotNull
5+
6+
@Schema(description = "Request to update terms agreement status")
7+
data class TermsAgreementRequest private constructor(
8+
@Schema(description = "Whether the user agrees to the terms of service", example = "true", required = true)
9+
val termsAgreed: Boolean? = null
10+
11+
12+
) {
13+
fun validTermsAgreed(): Boolean = termsAgreed!!
14+
}

apis/src/main/kotlin/org/yapp/apis/auth/dto/response/UserProfileResponse.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,22 @@ data class UserProfileResponse(
3333
description = "Social login provider type",
3434
example = "KAKAO"
3535
)
36-
val provider: ProviderType
36+
val provider: ProviderType,
37+
38+
@Schema(
39+
description = "Whether the user has agreed to the terms of service",
40+
example = "false"
41+
)
42+
val termsAgreed: Boolean
3743
) {
3844
companion object {
3945
fun from(userProfileVO: UserProfileVO): UserProfileResponse {
4046
return UserProfileResponse(
4147
id = userProfileVO.id.value,
4248
email = userProfileVO.email.value,
4349
nickname = userProfileVO.nickname,
44-
provider = userProfileVO.provider
50+
provider = userProfileVO.provider,
51+
termsAgreed = userProfileVO.termsAgreed
4552
)
4653
}
4754
}

apis/src/main/kotlin/org/yapp/apis/auth/service/UserAuthService.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ class UserAuthService(
2121
return UserProfileResponse.from(userProfile)
2222
}
2323

24+
fun updateTermsAgreement(userId: UUID, termsAgreed: Boolean): UserProfileResponse {
25+
validateUserExists(userId)
26+
val updatedUserProfile = userDomainService.updateTermsAgreement(userId, termsAgreed)
27+
return UserProfileResponse.from(updatedUserProfile)
28+
}
29+
2430
fun validateUserExists(userId: UUID) {
2531
if (!userDomainService.existsActiveUserByIdAndDeletedAtIsNull(userId)) {
2632
throw AuthException(AuthErrorCode.USER_NOT_FOUND, "User not found: $userId")

apis/src/main/kotlin/org/yapp/apis/auth/usecase/AuthUseCase.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,9 @@ class AuthUseCase(
5454
fun getUserProfile(userId: UUID): UserProfileResponse {
5555
return userAuthService.findUserProfileByUserId(userId)
5656
}
57+
58+
@Transactional
59+
fun updateTermsAgreement(userId: UUID, termsAgreed: Boolean): UserProfileResponse {
60+
return userAuthService.updateTermsAgreement(userId, termsAgreed)
61+
}
5762
}

apis/src/main/kotlin/org/yapp/apis/book/dto/request/UpsertUserBookRequest.kt

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,22 @@ import java.util.UUID
77

88

99
data class UpsertUserBookRequest private constructor(
10-
val userId: UUID,
11-
val bookIsbn: String,
12-
val bookTitle: String,
13-
val bookAuthor: String,
14-
val bookPublisher: String,
15-
val bookCoverImageUrl: String,
16-
val status: BookStatus
10+
val userId: UUID? = null,
11+
val bookIsbn: String? = null,
12+
val bookTitle: String? = null,
13+
val bookAuthor: String? = null,
14+
val bookPublisher: String? = null,
15+
val bookCoverImageUrl: String? = null,
16+
val status: BookStatus? = null
1717
) {
18+
fun validUserId(): UUID = userId!!
19+
fun validBookIsbn(): String = bookIsbn!!
20+
fun validBookTitle(): String = bookTitle!!
21+
fun validBookAuthor(): String = bookAuthor!!
22+
fun validBookPublisher(): String = bookPublisher!!
23+
fun validBookCoverImageUrl(): String = bookCoverImageUrl!!
24+
fun validStatus(): BookStatus = status!!
25+
1826
companion object {
1927
fun of(
2028
userId: UUID,

apis/src/main/kotlin/org/yapp/apis/book/service/UserBookService.kt

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,18 @@ import java.util.UUID
1818
class UserBookService(
1919
private val userBookDomainService: UserBookDomainService
2020
) {
21-
fun upsertUserBook(upsertUserBookRequest: UpsertUserBookRequest): UserBookResponse =
22-
UserBookResponse.from(
23-
userBookDomainService.upsertUserBook(
24-
upsertUserBookRequest.userId,
25-
upsertUserBookRequest.bookIsbn,
26-
upsertUserBookRequest.bookTitle,
27-
upsertUserBookRequest.bookAuthor,
28-
upsertUserBookRequest.bookPublisher,
29-
upsertUserBookRequest.bookCoverImageUrl,
30-
upsertUserBookRequest.status
31-
)
21+
fun upsertUserBook(upsertUserBookRequest: UpsertUserBookRequest): UserBookResponse {
22+
val userBookInfoVO = userBookDomainService.upsertUserBook(
23+
upsertUserBookRequest.validUserId(),
24+
upsertUserBookRequest.validBookIsbn(),
25+
upsertUserBookRequest.validBookTitle(),
26+
upsertUserBookRequest.validBookAuthor(),
27+
upsertUserBookRequest.validBookPublisher(),
28+
upsertUserBookRequest.validBookCoverImageUrl(),
29+
upsertUserBookRequest.validStatus()
3230
)
31+
return UserBookResponse.from(userBookInfoVO)
32+
}
3333

3434
fun findAllUserBooks(userId: UUID): List<UserBookResponse> {
3535
val userBooks: List<UserBookInfoVO> = userBookDomainService.findAllUserBooks(userId)
@@ -39,12 +39,11 @@ class UserBookService(
3939
}
4040

4141
fun findAllByUserIdAndBookIsbnIn(userBooksByIsbnsRequest: UserBooksByIsbnsRequest): List<UserBookResponse> {
42-
return userBookDomainService
43-
.findAllByUserIdAndBookIsbnIn(
44-
userBooksByIsbnsRequest.validUserId(),
45-
userBooksByIsbnsRequest.validIsbns(),
46-
)
47-
.map { UserBookResponse.from(it) }
42+
val userBooks = userBookDomainService.findAllByUserIdAndBookIsbnIn(
43+
userBooksByIsbnsRequest.validUserId(),
44+
userBooksByIsbnsRequest.validIsbns(),
45+
)
46+
return userBooks.map { UserBookResponse.from(it) }
4847
}
4948

5049
private fun findUserBooksByDynamicCondition(
@@ -53,8 +52,8 @@ class UserBookService(
5352
sort: String?,
5453
pageable: Pageable
5554
): Page<UserBookResponse> {
56-
return userBookDomainService.findUserBooksByDynamicCondition(userId, status, sort, pageable)
57-
.map { UserBookResponse.from(it) }
55+
val page = userBookDomainService.findUserBooksByDynamicCondition(userId, status, sort, pageable)
56+
return page.map { UserBookResponse.from(it) }
5857
}
5958

6059
fun findUserBooksByDynamicConditionWithStatusCounts(

domain/src/main/kotlin/org/yapp/domain/user/User.kt

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ data class User private constructor(
2828
val providerType: ProviderType,
2929
val providerId: ProviderId,
3030
val role: Role,
31+
val termsAgreed: Boolean = false,
3132
val createdAt: LocalDateTime? = null,
3233
val updatedAt: LocalDateTime? = null,
3334
val deletedAt: LocalDateTime? = null
@@ -40,13 +41,20 @@ data class User private constructor(
4041
)
4142
}
4243

44+
fun updateTermsAgreement(termsAgreed: Boolean): User {
45+
return this.copy(
46+
termsAgreed = termsAgreed
47+
)
48+
}
49+
4350
companion object {
4451
fun create(
4552
email: String,
4653
nickname: String,
4754
profileImageUrl: String?,
4855
providerType: ProviderType,
49-
providerId: String
56+
providerId: String,
57+
termsAgreed: Boolean = false
5058
): User {
5159
return User(
5260
id = Id.newInstance(UuidGenerator.create()),
@@ -55,7 +63,8 @@ data class User private constructor(
5563
profileImageUrl = profileImageUrl,
5664
providerType = providerType,
5765
providerId = ProviderId.newInstance(providerId),
58-
role = Role.USER
66+
role = Role.USER,
67+
termsAgreed = termsAgreed
5968
)
6069
}
6170

@@ -66,7 +75,8 @@ data class User private constructor(
6675
profileImageUrl: String?,
6776
providerType: ProviderType,
6877
providerId: String,
69-
role: Role
78+
role: Role,
79+
termsAgreed: Boolean = false
7080
): User {
7181
return User(
7282
id = Id.newInstance(UuidGenerator.create()),
@@ -75,7 +85,8 @@ data class User private constructor(
7585
profileImageUrl = profileImageUrl,
7686
providerType = providerType,
7787
providerId = ProviderId.newInstance(providerId),
78-
role = role
88+
role = role,
89+
termsAgreed = termsAgreed
7990
)
8091
}
8192

@@ -87,6 +98,7 @@ data class User private constructor(
8798
providerType: ProviderType,
8899
providerId: ProviderId,
89100
role: Role,
101+
termsAgreed: Boolean = false,
90102
createdAt: LocalDateTime? = null,
91103
updatedAt: LocalDateTime? = null,
92104
deletedAt: LocalDateTime? = null
@@ -99,6 +111,7 @@ data class User private constructor(
99111
providerType = providerType,
100112
providerId = providerId,
101113
role = role,
114+
termsAgreed = termsAgreed,
102115
createdAt = createdAt,
103116
updatedAt = updatedAt,
104117
deletedAt = deletedAt

domain/src/main/kotlin/org/yapp/domain/user/UserDomainService.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,12 @@ class UserDomainService(
6969
val restoredUser = userRepository.save(deletedUser.restore())
7070
return UserIdentityVO.newInstance(restoredUser)
7171
}
72+
73+
fun updateTermsAgreement(userId: UUID, termsAgreed: Boolean): UserProfileVO {
74+
val user = userRepository.findById(userId)
75+
?: throw UserNotFoundException(UserErrorCode.USER_NOT_FOUND)
76+
77+
val updatedUser = userRepository.save(user.updateTermsAgreement(termsAgreed))
78+
return UserProfileVO.newInstance(updatedUser)
79+
}
7280
}

0 commit comments

Comments
 (0)