diff --git a/application/src/main/kotlin/com/threedays/application/user/port/inbound/UpdateUserInfo.kt b/application/src/main/kotlin/com/threedays/application/user/port/inbound/UpdateUserInfo.kt new file mode 100644 index 0000000..47e6eb1 --- /dev/null +++ b/application/src/main/kotlin/com/threedays/application/user/port/inbound/UpdateUserInfo.kt @@ -0,0 +1,17 @@ +package com.threedays.application.user.port.inbound + +import com.threedays.domain.user.entity.Location +import com.threedays.domain.user.entity.User +import com.threedays.domain.user.vo.JobOccupation + +interface UpdateUserInfo { + + fun invoke(command: Command): User + + data class Command( + val userId: User.Id, + val name: User.Name? = null, + val jobOccupation: JobOccupation? = null, + val locationIds: List? = null, + ) +} diff --git a/application/src/main/kotlin/com/threedays/application/user/service/UserService.kt b/application/src/main/kotlin/com/threedays/application/user/service/UserService.kt index 50ac24d..1449753 100644 --- a/application/src/main/kotlin/com/threedays/application/user/service/UserService.kt +++ b/application/src/main/kotlin/com/threedays/application/user/service/UserService.kt @@ -5,6 +5,7 @@ import com.threedays.application.auth.port.inbound.IssueLoginTokens import com.threedays.application.user.port.inbound.DeleteProfileWidget import com.threedays.application.user.port.inbound.PutProfileWidget import com.threedays.application.user.port.inbound.RegisterUser +import com.threedays.application.user.port.inbound.UpdateUserInfo import com.threedays.domain.user.entity.Company import com.threedays.domain.user.entity.Location import com.threedays.domain.user.entity.User @@ -21,7 +22,7 @@ class UserService( private val companyQueryRepository: CompanyQueryRepository, private val issueLoginTokens: IssueLoginTokens, private val authProperties: AuthProperties, -) : RegisterUser, PutProfileWidget, DeleteProfileWidget { +) : RegisterUser, PutProfileWidget, DeleteProfileWidget, UpdateUserInfo { @Transactional override fun invoke(command: RegisterUser.Command): RegisterUser.Result { @@ -71,4 +72,17 @@ class UserService( .also { userRepository.save(it) } } + @Transactional + override fun invoke(command: UpdateUserInfo.Command): User { + return userRepository + .get(command.userId) + .updateUserInfo( + name = command.name, + jobOccupation = command.jobOccupation, + locationIds = command.locationIds, + locationQueryRepository = locationQueryRepository + ) + .also { userRepository.save(it) } + } + } diff --git a/bootstrap/api/src/main/kotlin/com/threedays/bootstrap/api/user/UserController.kt b/bootstrap/api/src/main/kotlin/com/threedays/bootstrap/api/user/UserController.kt index fd2830b..469cf1f 100644 --- a/bootstrap/api/src/main/kotlin/com/threedays/bootstrap/api/user/UserController.kt +++ b/bootstrap/api/src/main/kotlin/com/threedays/bootstrap/api/user/UserController.kt @@ -3,6 +3,7 @@ package com.threedays.bootstrap.api.user import com.threedays.application.user.port.inbound.DeleteProfileWidget import com.threedays.application.user.port.inbound.PutProfileWidget import com.threedays.application.user.port.inbound.RegisterUser +import com.threedays.application.user.port.inbound.UpdateUserInfo import com.threedays.bootstrap.api.support.security.UserAuthentication import com.threedays.bootstrap.api.support.security.withUserAuthentication import com.threedays.domain.auth.vo.PhoneNumber @@ -20,6 +21,9 @@ import com.threedays.oas.model.ProfileWidget import com.threedays.oas.model.ProfileWidgetType import com.threedays.oas.model.RegisterUserRequest import com.threedays.oas.model.TokenResponse +import com.threedays.oas.model.UpdateMyUserInfoRequest +import com.threedays.oas.model.UpdateMyUserInfoResponse +import com.threedays.oas.model.UserProfile import com.threedays.oas.model.UserProfileDisplayInfo import com.threedays.support.common.base.domain.UUIDTypeId import com.threedays.support.common.exception.NotFoundException @@ -34,6 +38,7 @@ class UserController( private val putProfileWidget: PutProfileWidget, private val userRepository: UserRepository, private val deleteProfileWidget: DeleteProfileWidget, + private val updateUserInfo: UpdateUserInfo, ) : UsersApi { override fun registerUser( @@ -144,14 +149,60 @@ class UserController( .let { ResponseEntity.ok(body) } } - override fun deleteProfileWidget(type: ProfileWidgetType): ResponseEntity = withUserAuthentication { authentication -> - val command = DeleteProfileWidget.Command( - userId = authentication.userId, - type = com.threedays.domain.user.entity.ProfileWidget.Type.valueOf(type.name) - ) + override fun deleteProfileWidget(type: ProfileWidgetType): ResponseEntity = + withUserAuthentication { authentication -> + val command = DeleteProfileWidget.Command( + userId = authentication.userId, + type = com.threedays.domain.user.entity.ProfileWidget.Type.valueOf(type.name) + ) - deleteProfileWidget.invoke(command) + deleteProfileWidget.invoke(command) - ResponseEntity.noContent().build() - } + ResponseEntity.noContent().build() + } + + override fun updateMyUserInfo(updateMyUserInfoRequest: UpdateMyUserInfoRequest): ResponseEntity = + withUserAuthentication { authentication -> + val command = UpdateUserInfo.Command( + userId = authentication.userId, + name = updateMyUserInfoRequest.name?.let { User.Name(it) }, + jobOccupation = updateMyUserInfoRequest.jobOccupation?.let { + JobOccupation.valueOf( + it.name + ) + }, + locationIds = updateMyUserInfoRequest.locationIds?.map(UUIDTypeId::from), + ) + + val user: User = updateUserInfo.invoke(command) + + UpdateMyUserInfoResponse( + id = user.id.value, + name = user.name.value, + phoneNumber = user.phoneNumber.value, + profile = UserProfile( + gender = com.threedays.oas.model.Gender.valueOf(user.profile.gender.name), + birthYear = user.profile.birthYear.value, + jobOccupation = com.threedays.oas.model.JobOccupation.valueOf(user.profile.jobOccupation.name), + locationIds = user.profile.locations.map { it.id.value }, + companyId = user.profile.company?.id?.value, + ), + desiredPartner = com.threedays.oas.model.UserDesiredPartner( + jobOccupations = user.desiredPartner.jobOccupations.map { + com.threedays.oas.model.JobOccupation.valueOf( + it.name + ) + }, + birthYearRange = user.desiredPartner.birthYearRange.let { + com.threedays.oas.model.BirthYearRange( + it.start?.value, + it.end?.value, + ) + }, + preferDistance = com.threedays.oas.model.PreferDistance.valueOf(user.desiredPartner.preferDistance.name), + ) + ).let { ResponseEntity.ok(it) } + + + } } diff --git a/domain/src/main/kotlin/com/threedays/domain/user/entity/User.kt b/domain/src/main/kotlin/com/threedays/domain/user/entity/User.kt index 0ce15b0..e2a4a75 100644 --- a/domain/src/main/kotlin/com/threedays/domain/user/entity/User.kt +++ b/domain/src/main/kotlin/com/threedays/domain/user/entity/User.kt @@ -2,6 +2,7 @@ package com.threedays.domain.user.entity import com.threedays.domain.auth.vo.PhoneNumber import com.threedays.domain.user.entity.UserDesiredPartner.PreferDistance +import com.threedays.domain.user.repository.LocationQueryRepository import com.threedays.domain.user.vo.BirthYearRange import com.threedays.domain.user.vo.Gender import com.threedays.domain.user.vo.JobOccupation @@ -94,4 +95,21 @@ data class User( return copy(profile = profile.deleteProfileWidget(type)) } + fun updateUserInfo( + name: Name?, + jobOccupation: JobOccupation?, + locationIds: List?, + locationQueryRepository: LocationQueryRepository + ): User { + val locations: List = locationIds?.map { locationQueryRepository.get(it) } ?: emptyList() + + return copy( + name = name ?: this.name, + profile = profile.copy( + jobOccupation = jobOccupation ?: profile.jobOccupation, + locations = locations.ifEmpty { profile.locations } + ) + ) + } + }