Skip to content

Conversation

@seung-in-Yoo
Copy link
Member

@seung-in-Yoo seung-in-Yoo commented Jul 14, 2025

작업내용

  • 자세한 작업 내용 및 테스트 결과는 동일한 제목의 close 한 pr 에 작성하였습니다.

Summary by CodeRabbit

  • 신규 기능

    • 사용자가 웨이블존에 장소를 저장할 수 있는 기능이 추가되었습니다.
    • 사용자 장소 저장 시 중복 저장 및 유효성 검증이 적용됩니다.
  • 버그 수정

    • 사용자 조회 실패 시 반환되는 HTTP 상태 코드가 400에서 404로 변경되었습니다.
  • 오류 메시지 개선

    • 웨이블존 미존재, 장소 중복 저장, 사용자 ID 불일치 등 다양한 오류 상황에 대한 상세 메시지가 추가되었습니다.

@seung-in-Yoo seung-in-Yoo self-assigned this Jul 14, 2025
@seung-in-Yoo seung-in-Yoo added the 💡 feature 기능 구현 및 개발 label Jul 14, 2025
@coderabbitai
Copy link

coderabbitai bot commented Jul 14, 2025

Walkthrough

사용자 장소 저장 기능이 새롭게 추가되었습니다. 이를 위해 컨트롤러, 서비스, DTO, 엔티티, 리포지토리, 예외 케이스가 도입 및 확장되었습니다. 리뷰 컨트롤러와 관련된 주석도 업데이트되었습니다. 전체적으로 사용자와 웨이블존 간의 장소 저장 및 중복 방지 로직이 구현되었습니다.

Changes

파일/경로 요약 변경 내용 요약
.../review/controller/ReviewController.java Authorization 헤더 관련 임시 주석을 TODO로 변경
.../user/controller/UserPlaceController.java 사용자 장소 저장을 위한 REST 컨트롤러 신설, 엔드포인트 및 검증/예외 처리 추가
.../user/dto/UserPlaceRequestDto.java 사용자 장소 요청 DTO 레코드 신설, 필수 필드에 @NotNull 적용
.../user/entity/User.java User 엔티티에 UserPlace와의 1:N 관계 및 컬렉션 필드 추가
.../user/exception/UserErrorCase.java 사용자 장소 관련 에러 케이스 3종 추가 및 기존 USER_NOT_FOUND의 상태 코드 변경
.../user/repository/UserPlaceRepository.java UserPlace 엔티티용 JPA 리포지토리 및 중복 검사용 메서드 추가
.../user/repository/UserPlaceWaybleZoneMappingRepository.java UserPlace-WaybleZone 매핑 엔티티용 JPA 리포지토리 및 존재 여부 확인 메서드 추가
.../user/service/UserPlaceService.java 사용자 장소 저장 로직을 담당하는 서비스 클래스 및 저장 메서드 추가

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: 성공 응답
Loading

Suggested labels

⚙️ chore

Suggested reviewers

  • KiSeungMin

Poem

🐇
새로운 장소 저장의 길이 열렸네,
유저와 웨이블존이 친구가 되었네.
중복 검사는 꼼꼼하게,
예외 메시지는 친절하게.
서비스와 컨트롤러,
함께 뛰는 우리 코드 러너!

🎉

✨ Finishing Touches
  • 📝 Generate Docstrings

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need 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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a 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

📥 Commits

Reviewing files that changed from the base of the PR and between 04825ca and 3380332.

📒 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: 중복 저장 확인 로직을 검토해주세요

현재 중복 확인이 userIdwaybleZoneId만으로 이루어지고 있습니다. 이는 사용자가 같은 웨이블존을 다른 제목으로 여러 번 저장하는 것을 막게 됩니다.

비즈니스 요구사항에 따라 다음 중 하나를 선택해야 합니다:

  1. 현재 로직 유지 (한 웨이블존당 하나의 저장만 허용)
  2. 제목까지 포함한 중복 확인 (같은 웨이블존을 다른 제목으로 저장 허용)

만약 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 주석을 통해 향후 로그인 구현 시 필수로 변경해야 함을 명시한 것도 좋습니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

💡 feature 기능 구현 및 개발

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants