Skip to content

Commit 7e2d271

Browse files
authored
Merge pull request #27 from prgrms-web-devcourse-final-project/QUZ-82-user-update
[QUZ-82][FEATURE] 프로필 업데이트
2 parents 1dc0af6 + 7d0c05d commit 7e2d271

File tree

22 files changed

+273
-15
lines changed

22 files changed

+273
-15
lines changed

gateway-service/src/main/kotlin/com/grepp/quizy/exception/JwtErrorCode.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ enum class JwtErrorCode(
1717
TOKEN_EXPIRED(UNAUTHORIZED, "TOKEN_401", "만료된 토큰"),
1818
TOKEN_NOT_VALIDATE(UNAUTHORIZED, "TOKEN_401", "유효하지 않은 토큰"),
1919
TOKEN_BAD_SIGNATURE(UNAUTHORIZED, "TOKEN_401", "서명 불일치"),
20-
TOKEN_NOT_FOUNT(NOT_FOUND, "TOKEN_404", "토큰이 존재하지 않음"),
20+
TOKEN_NOT_FOUNT(BAD_REQUEST, "TOKEN_400", "토큰이 존재하지 않음"),
2121
UNKNOWN_EXCEPTION(INTERNAL_SERVER, "TOKEN_900", "알 수 없는 오류 발생"),
2222
LOGGED_OUT_USER(UNAUTHORIZED, "TOKEN_401", "로그아웃된 사용자"),
2323
USER_NOT_FOUND(NOT_FOUND, "TOKEN_404", "존재하지 않는 사용자"),

gateway-service/src/main/resources/application.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,17 @@ spring:
7777
springdoc:
7878
swagger-ui:
7979
urls[0]:
80+
name: Game API
81+
url: http://localhost:8080/api/game/api-docs
82+
urls[1]:
8083
name: Quiz API
8184
url: http://localhost:8080/api/quiz/api-docs
85+
urls[2]:
86+
name: Matching API
87+
url: http://localhost:8080/api/matching/api-docs
88+
urls[3]:
89+
name: User API
90+
url: http://localhost:8080/api/user/api-docs
8291

8392
jwt:
8493
secret: ${JWT_SECRET}

user-service/user-application/app-api/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ dependencies {
2121

2222
// OAuth2
2323
implementation("org.springframework.boot:spring-boot-starter-oauth2-client")
24+
2425
}
2526

2627
tasks.named<BootJar>("bootJar") {

user-service/user-application/app-api/src/main/kotlin/com/grepp/quizy/user/api/global/oauth2/CustomOAuth2UserService.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class CustomOAuth2UserService(
5555
private fun createNewUser(attributes: OAuth2Attributes) {
5656
val newUser = User(
5757
id = UserId(0),
58-
userProfile = UserProfile(
58+
_userProfile = UserProfile(
5959
name = attributes.name,
6060
email = attributes.email,
6161
profileImageUrl = attributes.profileImageUrl
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.grepp.quizy.user.api.global.util
2+
3+
import com.grepp.quizy.user.domain.user.ImageFile
4+
import org.springframework.web.multipart.MultipartFile
5+
6+
fun toImageFile(file: MultipartFile): ImageFile {
7+
val contentType = file.contentType ?: throw IllegalArgumentException("File content type is null")
8+
return ImageFile(contentType, file.bytes, file.originalFilename, file.size)
9+
}
Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,31 @@
11
package com.grepp.quizy.user.api.user
22

3-
import org.springframework.web.bind.annotation.RequestMapping
4-
import org.springframework.web.bind.annotation.RestController
3+
import com.grepp.quizy.common.api.ApiResponse
4+
import com.grepp.quizy.user.api.global.util.toImageFile
5+
import com.grepp.quizy.user.api.user.dto.UpdateProfileRequest
6+
import com.grepp.quizy.user.domain.user.UserId
7+
import com.grepp.quizy.user.domain.user.UserUpdateUseCase
8+
import org.springframework.web.bind.annotation.*
9+
import org.springframework.web.multipart.MultipartFile
510

611
@RestController
712
@RequestMapping("/api/user")
8-
class UserApi {
13+
class UserApi(
14+
private val userUpdateUseCase: UserUpdateUseCase,
15+
) {
916

17+
@PutMapping("/me")
18+
fun updateMe(
19+
@RequestPart("data", required = false) request: UpdateProfileRequest?,
20+
@RequestPart("profileImage", required = false) profileImage: MultipartFile?,
21+
@RequestHeader("X-Auth-Id") userId: String,
22+
): ApiResponse<Unit> {
23+
val image = profileImage?.let {
24+
toImageFile(it)
25+
}
26+
27+
userUpdateUseCase.updateProfile(UserId(userId.toLong()), request?.name, image)
28+
return ApiResponse.success()
29+
}
1030

1131
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.grepp.quizy.user.api.user.dto
2+
3+
import jakarta.validation.constraints.Size
4+
5+
data class UpdateProfileRequest(
6+
@field:Size(min = 2, max = 50, message = "이름은 2자 이상 50자 이하여야 합니다.")
7+
val name: String?,
8+
) {
9+
constructor() : this(null)
10+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.grepp.quizy.user.domain.user
2+
3+
class DeleteUserEvent(
4+
private val userId: Long,
5+
) : UserEvent {
6+
override fun getUserId(): Long {
7+
return userId
8+
}
9+
10+
companion object {
11+
fun from(user: User): DeleteUserEvent {
12+
return DeleteUserEvent(user.id.value)
13+
}
14+
}
15+
16+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.grepp.quizy.user.domain.user
2+
3+
data class ImageFile(
4+
val contentType: String,
5+
val bytes: ByteArray,
6+
val originalFilename: String?,
7+
val size: Long
8+
) {
9+
10+
11+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.grepp.quizy.user.domain.user
2+
3+
interface ProfileImageUploader {
4+
fun uploadFile(file: ImageFile, directory: String = "images"): String
5+
}

0 commit comments

Comments
 (0)