-
Notifications
You must be signed in to change notification settings - Fork 0
[Feat[ 마이페이지 기능 #12
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
[Feat[ 마이페이지 기능 #12
Changes from all commits
dd9851a
558b89a
9457191
cf3fd82
9e4b0ef
aaabe66
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,7 @@ | ||
| package com.WhoIsRoom.WhoIs_Server.domain.club.repository; | ||
|
|
||
| import com.WhoIsRoom.WhoIs_Server.domain.club.model.Club; | ||
| import org.springframework.data.jpa.repository.JpaRepository; | ||
|
|
||
| public interface ClubRepository extends JpaRepository<Club, Long> { | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| package com.WhoIsRoom.WhoIs_Server.domain.member.repository; | ||
|
|
||
| import com.WhoIsRoom.WhoIs_Server.domain.member.model.Member; | ||
| import org.springframework.data.jpa.repository.JpaRepository; | ||
| import org.springframework.data.jpa.repository.Modifying; | ||
| import org.springframework.data.jpa.repository.Query; | ||
| import org.springframework.data.repository.query.Param; | ||
|
|
||
| import java.util.Collection; | ||
| import java.util.List; | ||
|
|
||
| public interface MemberRepository extends JpaRepository<Member, Long> { | ||
| List<Member> findByUserId(Long userId); | ||
| // 현재 유저가 속한 clubId 목록만 빠르게 가져오기 | ||
| @Query("select m.club.id from Member m where m.user.id = :userId") | ||
| List<Long> findClubIdsByUserId(@Param("userId") Long userId); | ||
|
|
||
| @Modifying(clearAutomatically = true, flushAutomatically = true) | ||
| @Query("delete from Member m where m.user.id = :userId and m.club.id in :clubIds") | ||
| void deleteByUserIdAndClubIdIn(@Param("userId") Long userId, @Param("clubIds") Collection<Long> clubIds); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| package com.WhoIsRoom.WhoIs_Server.domain.user.dto.request; | ||
|
|
||
| import lombok.*; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| @Getter | ||
| @NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
| @Builder | ||
| @AllArgsConstructor(access = AccessLevel.PRIVATE) | ||
| public class MyPageUpdateRequest { | ||
| String nickName; | ||
| List<Long> clubList; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| package com.WhoIsRoom.WhoIs_Server.domain.user.dto.response; | ||
|
|
||
| import com.WhoIsRoom.WhoIs_Server.domain.club.model.Club; | ||
| import lombok.Builder; | ||
| import lombok.Getter; | ||
|
|
||
| @Getter | ||
| @Builder | ||
| public class ClubResponse { | ||
| private Long id; | ||
| private String name; | ||
|
|
||
| public static ClubResponse from(Club club) { | ||
| return ClubResponse.builder() | ||
| .id(club.getId()) | ||
| .name(club.getName()) | ||
| .build(); | ||
| } | ||
|
|
||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| package com.WhoIsRoom.WhoIs_Server.domain.user.dto.response; | ||
|
|
||
| import com.WhoIsRoom.WhoIs_Server.domain.member.model.Member; | ||
| import lombok.Builder; | ||
| import lombok.Getter; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| @Getter | ||
| @Builder | ||
| public class MyPageResponse { | ||
| private String nickName; | ||
| private List<ClubResponse> clubList; | ||
|
|
||
| public static MyPageResponse from(String nickname, List<Member> memberList) { | ||
|
|
||
| List<ClubResponse> clubList = memberList.stream() | ||
| .map(Member::getClub) | ||
| .distinct() | ||
| .map(ClubResponse::from) | ||
| .toList(); | ||
|
|
||
| return MyPageResponse.builder() | ||
| .nickName(nickname) | ||
| .clubList(clubList) | ||
| .build(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,5 +1,6 @@ | ||||||||||||||||||
| package com.WhoIsRoom.WhoIs_Server.global.common.resolver; | ||||||||||||||||||
|
|
||||||||||||||||||
| import com.WhoIsRoom.WhoIs_Server.domain.auth.model.UserPrincipal; | ||||||||||||||||||
| import com.WhoIsRoom.WhoIs_Server.domain.user.repository.UserRepository; | ||||||||||||||||||
| import com.WhoIsRoom.WhoIs_Server.global.common.exception.BusinessException; | ||||||||||||||||||
| import com.WhoIsRoom.WhoIs_Server.global.common.response.ErrorCode; | ||||||||||||||||||
|
|
@@ -29,9 +30,7 @@ public Object resolveArgument(MethodParameter parameter, | |||||||||||||||||
| NativeWebRequest webRequest, | ||||||||||||||||||
| WebDataBinderFactory binderFactory) throws Exception { | ||||||||||||||||||
|
|
||||||||||||||||||
| String email = (String) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); | ||||||||||||||||||
| return userRepository.findByEmail(email) | ||||||||||||||||||
| .orElseThrow(() -> new BusinessException(ErrorCode.USER_NOT_FOUND)) | ||||||||||||||||||
| .getId(); | ||||||||||||||||||
| UserPrincipal principal = (UserPrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal(); | ||||||||||||||||||
| return principal.getUserId(); | ||||||||||||||||||
|
Comment on lines
+33
to
+34
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. 인증 객체와 타입 검증이 누락되었습니다.
다음과 같이 안전하게 처리하는 것을 권장합니다: - UserPrincipal principal = (UserPrincipal) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
- return principal.getUserId();
+ var authentication = SecurityContextHolder.getContext().getAuthentication();
+ if (authentication == null || !(authentication.getPrincipal() instanceof UserPrincipal)) {
+ throw new BusinessException(ErrorCode.UNAUTHORIZED);
+ }
+ UserPrincipal principal = (UserPrincipal) authentication.getPrincipal();
+ return principal.getUserId();📝 Committable suggestion
Suggested change
|
||||||||||||||||||
| } | ||||||||||||||||||
| } | ||||||||||||||||||
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.
🛠️ Refactor suggestion | 🟠 Major
닉네임 업데이트 로직에 null 안전성 검증이 필요합니다.
Line 106에서
user.getNickName().equals(newNickName)을 호출하는데,newNickName이 null이면 정상 동작하지만user.getNickName()이 null일 경우 NPE가 발생할 수 있습니다. 엔티티 필드가 non-null이라면 괜찮지만, 명시적인 null 검증이나@NotNull밸리데이션을 추가하는 것이 안전합니다.컨트롤러나 DTO 레벨에서
@NotNull또는@NotBlank검증 추가:또는 서비스 메서드에서 명시적 null 체크:
private void updateUserNickName(User user, String newNickName) { + if (newNickName == null || newNickName.trim().isEmpty()) { + throw new BusinessException(ErrorCode.INVALID_INPUT); + } // 변경 사항이 없으면 아무것도 하지 않음 (최적화) if (user.getNickName().equals(newNickName)) { return; }