Skip to content

Commit

Permalink
feat: 유저 닉네임 변경 api
Browse files Browse the repository at this point in the history
  • Loading branch information
DongGeon0908 committed Sep 18, 2024
1 parent e168116 commit 3816058
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
package com.hero.alignlab.domain.user.application

import arrow.fx.coroutines.parZip
import com.hero.alignlab.common.encrypt.EncryptData
import com.hero.alignlab.common.encrypt.Encryptor
import com.hero.alignlab.common.extension.coExecute
import com.hero.alignlab.config.database.TransactionTemplates
import com.hero.alignlab.domain.auth.model.AuthUser
import com.hero.alignlab.domain.user.domain.UserInfo
import com.hero.alignlab.domain.user.domain.vo.OAuthProvider
import com.hero.alignlab.domain.user.infrastructure.UserInfoRepository
import com.hero.alignlab.domain.user.model.request.ChangeNicknameRequest
import com.hero.alignlab.domain.user.model.response.ChangeNicknameResponse
import com.hero.alignlab.domain.user.model.response.UserInfoResponse
import com.hero.alignlab.exception.ErrorCode
import com.hero.alignlab.exception.InvalidRequestException
import com.hero.alignlab.exception.NotFoundException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
Expand All @@ -18,6 +25,7 @@ import org.springframework.transaction.annotation.Transactional
class UserInfoService(
private val userInfoRepository: UserInfoRepository,
private val encryptor: Encryptor,
private val txTemplates: TransactionTemplates,
) {
suspend fun getUserByIdOrThrow(uid: Long): UserInfo {
return withContext(Dispatchers.IO) {
Expand Down Expand Up @@ -88,4 +96,37 @@ class UserInfoService(
userInfoRepository.findAllUids()
}
}

suspend fun changeNickname(
user: AuthUser,
id: Long,
request: ChangeNicknameRequest,
): ChangeNicknameResponse {
if (user.uid != id) {
throw InvalidRequestException(ErrorCode.NOT_FOUND_USER_ERROR)
}

val updatedUserInfo = parZip(
{ getUserByIdOrThrowSync(id) },
{ existsByNicknameAndIdNot(request.nickname, id) }
) { userInfo, existsNickname ->
if (existsNickname) {
throw InvalidRequestException(ErrorCode.DUPLICATE_USER_NICKNAME_ERROR)
}

txTemplates.writer.coExecute {
userInfo.apply {
this.nickname = request.nickname
}
}
}

return ChangeNicknameResponse.from(updatedUserInfo)
}

suspend fun existsByNicknameAndIdNot(nickname: String, id: Long): Boolean {
return withContext(Dispatchers.IO) {
userInfoRepository.existsByNicknameAndIdNot(nickname, id)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ class UserInfo(
val id: Long = -1,

@Column(name = "nickname")
val nickname: String,
var nickname: String,
) : BaseEntity()
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import java.time.LocalDateTime
@Repository
interface UserInfoRepository : JpaRepository<UserInfo, Long>, UserInfoQRepository {
fun countByCreatedAtBetween(startAt: LocalDateTime, endAt: LocalDateTime): Long

fun existsByNicknameAndIdNot(nickname: String, id: Long): Boolean
}

@Transactional(readOnly = true)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.hero.alignlab.domain.user.model.request

data class ChangeNicknameRequest(
val nickname: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.hero.alignlab.domain.user.model.response

import com.hero.alignlab.domain.user.domain.UserInfo

data class ChangeNicknameResponse(
val id: Long,
val nickname: String,
) {
companion object {
fun from(user: UserInfo): ChangeNicknameResponse {
return ChangeNicknameResponse(
id = user.id,
nickname = user.nickname
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.hero.alignlab.domain.user.resource

import com.hero.alignlab.common.extension.wrapOk
import com.hero.alignlab.common.model.Response
import com.hero.alignlab.domain.auth.model.AuthUser
import com.hero.alignlab.domain.user.application.UserInfoService
import com.hero.alignlab.domain.user.model.request.ChangeNicknameRequest
import com.hero.alignlab.domain.user.model.response.ChangeNicknameResponse
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.tags.Tag
import org.springframework.http.MediaType
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*

@Tag(name = "User API")
@RestController
@RequestMapping(produces = [MediaType.APPLICATION_JSON_VALUE])
class UserResource(
private val userInfoService: UserInfoService,
) {
@Operation(summary = "유저 닉네임 변경")
@PutMapping("/api/v1/users/{id}/nickname")
suspend fun changeNickname(
user: AuthUser,
@PathVariable id: Long,
@RequestBody request: ChangeNicknameRequest,
): ResponseEntity<Response<ChangeNicknameResponse>> {
return userInfoService.changeNickname(
user = user,
id = id,
request = request
).wrapOk()
}
}
1 change: 1 addition & 0 deletions src/main/kotlin/com/hero/alignlab/exception/ErrorCode.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ enum class ErrorCode(val status: HttpStatus, val description: String) {

/** User Error Code */
NOT_FOUND_USER_ERROR(HttpStatus.NOT_FOUND, "유저 정보를 찾을 수 없습니다."),
DUPLICATE_USER_NICKNAME_ERROR(HttpStatus.BAD_REQUEST, "중복된 유저 닉네임 입니다."),

/** Group Error Code */
DUPLICATE_GROUP_NAME_ERROR(HttpStatus.BAD_REQUEST, "중복된 그룹명입니다."),
Expand Down

0 comments on commit 3816058

Please sign in to comment.