-
Notifications
You must be signed in to change notification settings - Fork 0
feat: user #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: user #2
Changes from 19 commits
b8ad1fa
e3be647
2cd815d
6575451
bd2b2dc
00a94e2
c889057
046464c
01dffdd
8847a0d
2d516e2
73c5f25
5cf6355
4e54a5d
542ddd9
117cd82
196f2c0
e71cef8
ae0a7e0
54ab978
5b057bf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| package uoslife.springaccount.app.user.controller | ||
|
|
||
| import org.springframework.http.ResponseEntity | ||
| import org.springframework.security.core.annotation.AuthenticationPrincipal | ||
| import org.springframework.security.core.userdetails.UserDetails | ||
| import org.springframework.web.bind.annotation.GetMapping | ||
| import org.springframework.web.bind.annotation.PathVariable | ||
| import org.springframework.web.bind.annotation.RequestMapping | ||
| import org.springframework.web.bind.annotation.RestController | ||
| import uoslife.springaccount.app.user.dto.response.UserProfileDto | ||
| import uoslife.springaccount.app.user.service.UserService | ||
|
|
||
| @RestController | ||
| @RequestMapping("/v2/user") | ||
| class UserController(private val userService: UserService) { | ||
|
|
||
| @GetMapping("/me") | ||
| fun getMyProfile( | ||
| @AuthenticationPrincipal userDetails: UserDetails | ||
|
||
| ): ResponseEntity<UserProfileDto.UserProfileResponse> { | ||
| val userId = userDetails.username.toLong() | ||
| return ResponseEntity.ok(userService.getProfile(userId)) | ||
| } | ||
|
|
||
| @GetMapping("/{userId}") | ||
| fun getProfile( | ||
| @PathVariable userId: Long, | ||
| ): ResponseEntity<UserProfileDto.UserProfileResponse> { | ||
| return ResponseEntity.ok(userService.getProfile(userId)) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| package uoslife.springaccount.app.user.dto.param | ||
|
|
||
| data class CreateUserDto(val nickname: String, val phoneNumber: String) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| package uoslife.springaccount.app.user.dto.param | ||
|
|
||
| data class UpdateUserDto(val nickname: String?) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package uoslife.springaccount.app.user.dto.param | ||
|
|
||
| import uoslife.springaccount.app.identity.domain.entity.Identity | ||
| import uoslife.springaccount.app.moderator.domain.entity.Moderators | ||
| import uoslife.springaccount.app.verification.domain.entity.PortalAccounts | ||
| import uoslife.springaccount.app.verification.domain.entity.Verifications | ||
|
|
||
| data class UserWithInfoDto( | ||
| val identities: List<Identity>, | ||
| val portalAccounts: List<PortalAccounts>, | ||
| val verifications: List<Verifications>, | ||
| val moderator: Moderators?, | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| package uoslife.springaccount.app.user.dto.response | ||
|
|
||
| import uoslife.springaccount.app.user.domain.entity.User | ||
| import uoslife.springaccount.app.verification.domain.entity.VerificationMethod | ||
| import uoslife.springaccount.common.error.ErrorCode | ||
| import uoslife.springaccount.common.error.baseexception.BusinessException | ||
|
|
||
| class UserProfileDto { | ||
|
|
||
| data class UserRealm( | ||
| val code: String, | ||
| val name: String, | ||
| ) | ||
|
|
||
| data class UserProfileIdentity( | ||
| val id: String, | ||
| val type: String, | ||
| val status: String, | ||
| val idNumber: String, | ||
| val university: String?, | ||
| val department: String?, | ||
| val major: String?, | ||
| ) | ||
|
|
||
| data class UserProfileModerator( | ||
| val generation: String, | ||
| val chapter: String, | ||
| val role: String, | ||
| ) | ||
|
|
||
| data class UserProfileResponse( | ||
| val id: Long, | ||
| val nickname: String, | ||
| val phone: String, | ||
| val name: String?, | ||
| val email: String?, | ||
| // val realm: UserRealm?, | ||
| val identity: UserProfileIdentity?, | ||
| val moderator: UserProfileModerator?, | ||
| val isLinkedPortal: Boolean, | ||
| val isVerified: Boolean, | ||
| val verificationMethod: VerificationMethod?, | ||
| ) | ||
|
|
||
| companion object { | ||
| fun toUserProfileResponse(user: User): UserProfileResponse { | ||
| return UserProfileResponse( | ||
| id = user.id ?: throw BusinessException(ErrorCode.USER_ID_NULL), | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BusinessException์ ErrorCode๋ฅผ ๋ฃ๋ ๊ฒ๋ณด๋ค BusinessException ๊ฐ์ฒด๋ฅผ ์์ํ UserNullException ๊ฐ์ ๊ฑธ ๋ง๋ค์ด ์ฐ๋ ๊ฒ ๊ฐ์ต๋๋ค |
||
| nickname = user.nickname ?: "No Nickname", | ||
| phone = user.phoneNumber, | ||
| name = user.name, | ||
| email = user.email, | ||
| identity = | ||
| user.identities.firstOrNull()?.let { identity -> | ||
| UserProfileIdentity( | ||
| id = identity.id, | ||
| type = identity.type, | ||
| status = identity.status, | ||
| idNumber = identity.idNumber, | ||
| university = identity.university, | ||
| department = identity.department, | ||
| major = identity.major | ||
| ) | ||
| }, | ||
| moderator = | ||
| user.moderators.firstOrNull()?.let { | ||
| UserProfileModerator( | ||
| generation = it.generation, | ||
| chapter = it.chapter, | ||
| role = it.role | ||
| ) | ||
| }, | ||
| isLinkedPortal = user.portalAccounts.isNotEmpty(), | ||
| isVerified = user.verifications.isNotEmpty(), | ||
| verificationMethod = user.verifications.firstOrNull()?.method | ||
| ) | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| package uoslife.springaccount.app.user.service | ||
|
|
||
| import java.util.concurrent.TimeUnit | ||
| import org.redisson.api.RBucket | ||
| import org.redisson.api.RedissonClient | ||
| import org.springframework.stereotype.Service | ||
| import uoslife.springaccount.app.user.domain.repository.jpa.UserRepository | ||
| import uoslife.springaccount.app.user.dto.response.UserProfileDto | ||
| import uoslife.springaccount.app.user.util.UserConfig | ||
| import uoslife.springaccount.common.error.user.UserNotFoundException | ||
|
|
||
| @Service | ||
| class UserService( | ||
| private val userRepository: UserRepository, | ||
| private val redisClient: RedissonClient, | ||
| ) { | ||
|
|
||
| fun getProfile(userId: Long): UserProfileDto.UserProfileResponse { | ||
| val cacheKey = getProfileCacheKey(userId) | ||
|
|
||
| // ์บ์๋ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ | ||
| val bucket: RBucket<UserProfileDto.UserProfileResponse> = redisClient.getBucket(cacheKey) | ||
| val cachedData = bucket.get() | ||
| if (cachedData != null) { | ||
| return cachedData | ||
| } | ||
|
|
||
| // DB์์ ์ ์ ์กฐํ | ||
| val user = | ||
| userRepository.findByIdAndDeletedAtIsNull(userId) ?: throw UserNotFoundException() | ||
|
|
||
| // User ์ํฐํฐ๋ฅผ DTO๋ก ๋ณํ | ||
| val userProfileResponse = UserProfileDto.toUserProfileResponse(user) | ||
|
|
||
| // ์บ์ ์ ์ฅ | ||
| bucket.set(userProfileResponse, UserConfig.USER_PROFILE_CACHE_TTL, TimeUnit.SECONDS) | ||
|
|
||
| return userProfileResponse | ||
| } | ||
|
|
||
| private fun getProfileCacheKey(userId: Long): String { | ||
| return "uoslife:user:profile:$userId" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package uoslife.springaccount.app.user.util | ||
|
|
||
| class UserConfig { | ||
| companion object { | ||
| const val USER_PROFILE_CACHE_TTL: Long = 60 * 60 // ์ ์ ์ ๋ณด ์ ์ฅ ์๊ฐ. 1์๊ฐ | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| package uoslife.springaccount.common.error.user | ||
|
|
||
| import uoslife.springaccount.common.error.ErrorCode | ||
| import uoslife.springaccount.common.error.baseexception.EntityNotFoundException | ||
|
|
||
| class UserNotFoundException : EntityNotFoundException(ErrorCode.USER_NOT_FOUND) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JVM ์บ์ฑ ์ฌ์ฉํ์ง ์์ผ๋ฉด ์ ๊ฑฐํด์ผ ํ ๊ฒ ๊ฐ์ต๋๋ค.