Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.wayble.server.user.controller;

import com.wayble.server.common.response.CommonResponse;
import com.wayble.server.user.dto.UserPlaceRequestDto;
import com.wayble.server.user.service.UserPlaceService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/v1/users/{userId}/places")
@RequiredArgsConstructor
public class UserPlaceController {

private final UserPlaceService userPlaceService;

@PostMapping
@Operation(summary = "유저 장소 저장", description = "유저가 웨이블존을 장소로 저장합니다.")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "장소 저장 성공"),
@ApiResponse(responseCode = "400", description = "이미 저장한 장소입니다."),
@ApiResponse(responseCode = "404", description = "해당 유저 또는 웨이블존이 존재하지 않음")
})
public CommonResponse<String> saveUserPlace(
@PathVariable Long userId,
@RequestBody UserPlaceRequestDto request,

// 테스트를 위해 임시 허용 (로그인 구현되면 삭제)
@RequestHeader(value = "Authorization", required = false) String authorizationHeader
) {
userPlaceService.saveUserPlace(request);
return CommonResponse.success("장소가 저장되었습니다.");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.wayble.server.user.dto;

import jakarta.validation.constraints.NotNull;

public record UserPlaceRequestDto(
@NotNull Long userId,
@NotNull Long waybleZoneId,
@NotNull String title
) {}
3 changes: 2 additions & 1 deletion src/main/java/com/wayble/server/user/entity/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,6 @@ public class User extends BaseEntity {

// TODO 프로필 이미지 관련 작업 필요

// TODO 내가 저장한 장소 관련 작업 필요
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<UserPlace> userPlaces = new ArrayList<>();
Comment on lines +61 to +62
Copy link

@coderabbitai coderabbitai bot Jul 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

UserPlace 엔티티 import 구문이 누락되었습니다.

새로 추가된 userPlaces 필드는 UserPlace 엔티티를 참조하고 있지만, 해당 클래스의 import 구문이 없어 컴파일 오류가 발생할 것입니다.

파일 상단에 다음 import를 추가해주세요:

 import com.wayble.server.common.entity.BaseEntity;
 import com.wayble.server.review.entity.Review;
+import com.wayble.server.user.entity.UserPlace;
 import jakarta.persistence.*;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private List<UserPlace> userPlaces = new ArrayList<>();
import com.wayble.server.common.entity.BaseEntity;
import com.wayble.server.review.entity.Review;
import com.wayble.server.user.entity.UserPlace;
import jakarta.persistence.*;
🤖 Prompt for AI Agents
In src/main/java/com/wayble/server/user/entity/User.java around lines 61 to 62,
the UserPlace entity is referenced in the userPlaces field but its import
statement is missing, causing a compilation error. Add the appropriate import
statement for the UserPlace class at the top of the file to resolve this issue.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재 같은 패키지 내 클래스여서 import 없이도 사용할 수 있는거 아니야? 파일 내에서도 컴파일 오류 안나고 있어.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@seung-in-Yoo 맞습니다! 제가 실수했네요. 같은 패키지 내의 클래스들은 import 없이 사용할 수 있습니다.

User 클래스와 UserPlace 클래스가 모두 com.wayble.server.user.entity 패키지에 있기 때문에 별도의 import 구문이 필요하지 않습니다. 불필요한 지적을 해서 죄송합니다. 정정해 주셔서 감사합니다!

🐰
╭─╮
( ・ω・) 학습했어요!
╰─╯


✏️ Learnings added
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 없이 사용 가능하다.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
@RequiredArgsConstructor
public enum UserErrorCase implements ErrorCase {

USER_NOT_FOUND(400, 1001, "사용자를 찾을 수 없습니다.");
USER_NOT_FOUND(400, 1001, "사용자를 찾을 수 없습니다."),
WAYBLE_ZONE_NOT_FOUND(404, 1002, "해당 웨이블존을 찾을 수 없습니다."),
PLACE_ALREADY_SAVED(400, 1003, "이미 저장한 장소입니다.");

private final Integer httpStatusCode;
private final Integer errorCode;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.wayble.server.user.repository;

import com.wayble.server.user.entity.UserPlace;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface UserPlaceRepository extends JpaRepository<UserPlace, Long> {
Optional<UserPlace> findByUser_IdAndTitle(Long userId, String title);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.wayble.server.user.repository;

import com.wayble.server.user.entity.UserPlaceWaybleZoneMapping;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserPlaceWaybleZoneMappingRepository extends JpaRepository<UserPlaceWaybleZoneMapping, Long> {
boolean existsByUserPlace_User_IdAndWaybleZone_Id(Long userId, Long zoneId);
}
57 changes: 57 additions & 0 deletions src/main/java/com/wayble/server/user/service/UserPlaceService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.wayble.server.user.service;


import com.wayble.server.common.exception.ApplicationException;
import com.wayble.server.user.dto.UserPlaceRequestDto;
import com.wayble.server.user.entity.User;
import com.wayble.server.user.entity.UserPlace;
import com.wayble.server.user.entity.UserPlaceWaybleZoneMapping;
import com.wayble.server.user.exception.UserErrorCase;
import com.wayble.server.user.repository.UserPlaceRepository;
import com.wayble.server.user.repository.UserPlaceWaybleZoneMappingRepository;
import com.wayble.server.user.repository.UserRepository;
import com.wayble.server.wayblezone.entity.WaybleZone;
import com.wayble.server.wayblezone.repository.WaybleZoneRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class UserPlaceService {

private final UserRepository userRepository;
private final WaybleZoneRepository waybleZoneRepository;
private final UserPlaceRepository userPlaceRepository;
private final UserPlaceWaybleZoneMappingRepository mappingRepository;

public void saveUserPlace(UserPlaceRequestDto request) {
// 유저 존재 확인
User user = userRepository.findById(request.userId())
.orElseThrow(() -> new ApplicationException(UserErrorCase.USER_NOT_FOUND));

// 웨이블존 존재 확인
WaybleZone waybleZone = waybleZoneRepository.findById(request.waybleZoneId())
.orElseThrow(() -> new ApplicationException(UserErrorCase.WAYBLE_ZONE_NOT_FOUND));

// 중복 저장 확인
boolean alreadySaved = mappingRepository.existsByUserPlace_User_IdAndWaybleZone_Id(request.userId(), request.waybleZoneId());
if (alreadySaved) {
throw new ApplicationException(UserErrorCase.PLACE_ALREADY_SAVED);
}

// 저장
UserPlace userPlace = userPlaceRepository.save(
UserPlace.builder()
.title(request.title())
.user(user)
.build()
);

mappingRepository.save(
UserPlaceWaybleZoneMapping.builder()
.userPlace(userPlace)
.waybleZone(waybleZone)
.build()
);
}
}
Loading