-
Notifications
You must be signed in to change notification settings - Fork 1
[feat] 유저 장소 저장 api 구현 (충돌 해결용) #39
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
Conversation
…ring into feature/seungin
Walkthrough사용자 장소 저장 기능이 새롭게 추가되었습니다. 이를 위해 컨트롤러, 서비스, DTO, 엔티티, 리포지토리, 예외 케이스가 도입 및 확장되었습니다. 리뷰 컨트롤러와 관련된 주석도 업데이트되었습니다. 전체적으로 사용자와 웨이블존 간의 장소 저장 및 중복 방지 로직이 구현되었습니다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant UserPlaceController
participant UserPlaceService
participant UserRepository
participant WaybleZoneRepository
participant UserPlaceRepository
participant UserPlaceWaybleZoneMappingRepository
Client->>UserPlaceController: POST /api/v1/users/{userId}/places
UserPlaceController->>UserPlaceService: saveUserPlace(request)
UserPlaceService->>UserRepository: findById(userId)
UserPlaceService->>WaybleZoneRepository: findById(waybleZoneId)
UserPlaceService->>UserPlaceWaybleZoneMappingRepository: existsByUserPlace_User_IdAndWaybleZone_Id(userId, zoneId)
alt not exists
UserPlaceService->>UserPlaceRepository: save(new UserPlace)
UserPlaceService->>UserPlaceWaybleZoneMappingRepository: save(mapping)
else exists
UserPlaceService-->>UserPlaceController: throw PLACE_ALREADY_SAVED
end
UserPlaceService-->>UserPlaceController: 완료
UserPlaceController-->>Client: 성공 응답
Suggested labels
Suggested reviewers
Poem
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
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.
Actionable comments posted: 0
🧹 Nitpick comments (2)
src/main/java/com/wayble/server/user/repository/UserPlaceWaybleZoneMappingRepository.java (1)
6-8: 중첩 프로퍼티 네비게이션을 활용한 효율적인 중복 체크 메서드입니다.
existsByUserPlace_User_IdAndWaybleZone_Id는 Spring Data JPA 컨벤션을 올바르게 따르고 있으며, boolean 반환으로 성능상 효율적입니다.메서드명이 다소 길어 가독성을 위해 다음과 같은 대안을 고려해볼 수 있습니다:
- boolean existsByUserPlace_User_IdAndWaybleZone_Id(Long userId, Long zoneId); + boolean existsByUserIdAndWaybleZoneId(Long userId, Long zoneId);이를 위해서는
@Query어노테이션을 사용하여 명시적인 JPQL을 작성해야 합니다.src/main/java/com/wayble/server/user/dto/UserPlaceRequestDto.java (1)
5-9: Record 클래스를 활용한 깔끔한 DTO 구현입니다.모든 필드에
@NotNull검증이 적용되어 있어 좋습니다.title 필드에 대해 추가적인 검증을 고려해보세요:
public record UserPlaceRequestDto( @NotNull Long userId, @NotNull Long waybleZoneId, - @NotNull String title + @NotNull @NotBlank String title ) {}이렇게 하면 빈 문자열이나 공백만 있는 제목을 방지할 수 있습니다.
@NotBlank사용을 위해 import가 필요합니다:import jakarta.validation.constraints.NotBlank;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
src/main/java/com/wayble/server/review/controller/ReviewController.java(1 hunks)src/main/java/com/wayble/server/user/controller/UserPlaceController.java(1 hunks)src/main/java/com/wayble/server/user/dto/UserPlaceRequestDto.java(1 hunks)src/main/java/com/wayble/server/user/entity/User.java(1 hunks)src/main/java/com/wayble/server/user/exception/UserErrorCase.java(1 hunks)src/main/java/com/wayble/server/user/repository/UserPlaceRepository.java(1 hunks)src/main/java/com/wayble/server/user/repository/UserPlaceWaybleZoneMappingRepository.java(1 hunks)src/main/java/com/wayble/server/user/service/UserPlaceService.java(1 hunks)
🧰 Additional context used
🧠 Learnings (3)
src/main/java/com/wayble/server/user/entity/User.java (1)
Learnt from: seung-in-Yoo
PR: Wayble-Project/wayble-spring#37
File: src/main/java/com/wayble/server/user/entity/User.java:61-62
Timestamp: 2025-07-13T15:08:59.288Z
Learning: Java에서 같은 패키지 내의 클래스들은 import 구문 없이 서로를 참조할 수 있다. com.wayble.server.user.entity 패키지 내의 클래스들은 명시적인 import 없이 사용 가능하다.
src/main/java/com/wayble/server/user/repository/UserPlaceWaybleZoneMappingRepository.java (1)
Learnt from: seung-in-Yoo
PR: Wayble-Project/wayble-spring#37
File: src/main/java/com/wayble/server/user/entity/User.java:61-62
Timestamp: 2025-07-13T15:08:59.288Z
Learning: Java에서 같은 패키지 내의 클래스들은 import 구문 없이 서로를 참조할 수 있다. com.wayble.server.user.entity 패키지 내의 클래스들은 명시적인 import 없이 사용 가능하다.
src/main/java/com/wayble/server/user/service/UserPlaceService.java (1)
Learnt from: seung-in-Yoo
PR: Wayble-Project/wayble-spring#37
File: src/main/java/com/wayble/server/user/entity/User.java:61-62
Timestamp: 2025-07-13T15:08:59.288Z
Learning: Java에서 같은 패키지 내의 클래스들은 import 구문 없이 서로를 참조할 수 있다. com.wayble.server.user.entity 패키지 내의 클래스들은 명시적인 import 없이 사용 가능하다.
🧬 Code Graph Analysis (1)
src/main/java/com/wayble/server/user/controller/UserPlaceController.java (1)
src/main/java/com/wayble/server/review/controller/ReviewController.java (1)
RestController(20-61)
🔇 Additional comments (11)
src/main/java/com/wayble/server/review/controller/ReviewController.java (1)
42-43: 일관된 주석 표준화가 잘 적용되었습니다.다른 컨트롤러들과 동일한 TODO 형식으로 주석을 통일한 것이 좋습니다. 향후 로그인 구현 시 쉽게 찾아서 수정할 수 있도록 명확하게 표시되어 있습니다.
src/main/java/com/wayble/server/user/entity/User.java (1)
61-62: 검증 완료: UserPlace 엔티티 존재 및 관계 매핑 확인UserPlace.java 파일이
src/main/java/com/wayble/server/user/entity경로에 존재함을 확인했습니다.
따라서@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)설정이 올바르게 적용되었으며, 추가 조치가 필요 없습니다.src/main/java/com/wayble/server/user/repository/UserPlaceRepository.java (1)
8-10: Spring Data JPA 컨벤션을 올바르게 따른 깔끔한 구현입니다.
findByUser_IdAndTitle메서드명이 명확하고, Optional 반환 타입으로 null 안전성을 보장하고 있습니다. 사용자별 장소 제목 중복 체크에 효과적으로 사용될 것 같습니다.src/main/java/com/wayble/server/user/exception/UserErrorCase.java (1)
11-14: 에러 케이스 정의가 적절합니다
USER_NOT_FOUND의 HTTP 상태 코드를 400에서 404로 변경한 것이 REST 표준에 맞습니다- 새로 추가된 에러 케이스들이 사용자 장소 저장 기능의 비즈니스 시나리오를 잘 커버하고 있습니다
- 에러 코드가 순차적으로 잘 정의되었습니다
src/main/java/com/wayble/server/user/service/UserPlaceService.java (3)
19-27: 클래스 구조가 잘 설계되었습니다의존성 주입과 어노테이션 사용이 적절하며, 필요한 리포지토리들을 모두 주입받고 있습니다.
28-42: 중복 저장 확인 로직을 검토해주세요현재 중복 확인이
userId와waybleZoneId만으로 이루어지고 있습니다. 이는 사용자가 같은 웨이블존을 다른 제목으로 여러 번 저장하는 것을 막게 됩니다.비즈니스 요구사항에 따라 다음 중 하나를 선택해야 합니다:
- 현재 로직 유지 (한 웨이블존당 하나의 저장만 허용)
- 제목까지 포함한 중복 확인 (같은 웨이블존을 다른 제목으로 저장 허용)
만약 2번이 요구사항이라면 다음과 같이 수정이 필요합니다:
- boolean alreadySaved = mappingRepository.existsByUserPlace_User_IdAndWaybleZone_Id(request.userId(), request.waybleZoneId()); + Optional<UserPlace> existingPlace = userPlaceRepository.findByUserIdAndTitle(request.userId(), request.title()); + if (existingPlace.isPresent()) { + boolean alreadySaved = mappingRepository.existsByUserPlaceAndWaybleZone_Id(existingPlace.get(), request.waybleZoneId()); + if (alreadySaved) { + throw new ApplicationException(UserErrorCase.PLACE_ALREADY_SAVED); + } + }
44-58: 엔티티 생성 및 저장 로직이 적절합니다UserPlace를 먼저 저장한 후 매핑 엔티티를 생성하는 순서가 올바르며, @transactional로 데이터 일관성이 보장됩니다.
src/main/java/com/wayble/server/user/controller/UserPlaceController.java (4)
15-21: 컨트롤러 구조가 일관성 있게 설계되었습니다ReviewController와 동일한 패턴을 따르고 있어 코드베이스의 일관성이 유지됩니다.
22-28: API 문서화가 잘 되어있습니다OpenAPI 어노테이션을 통해 엔드포인트의 목적과 가능한 응답 코드들이 명확하게 문서화되었습니다.
36-39: 경로 변수와 요청 바디의 userId 일치성 검증이 훌륭합니다보안과 데이터 무결성을 위한 방어적 프로그래밍 접근 방식입니다. 이러한 검증 로직이 잠재적인 버그를 방지합니다.
33-34: Authorization 헤더 처리가 일관성 있습니다
src/main/java/com/wayble/server/review/controller/ReviewController.java의 패턴과 동일하게 구현되어 코드베이스의 일관성이 유지됩니다. TODO 주석을 통해 향후 로그인 구현 시 필수로 변경해야 함을 명시한 것도 좋습니다.
작업내용
Summary by CodeRabbit
신규 기능
버그 수정
오류 메시지 개선