From 6ee84ae9ead8b5271829acfc68b44e8b23469bb3 Mon Sep 17 00:00:00 2001 From: qhdudedi Date: Thu, 27 Feb 2025 23:51:05 +0900 Subject: [PATCH 1/5] =?UTF-8?q?Fix:=20JWT=20=EC=83=9D=EC=84=B1=20=EB=B0=8F?= =?UTF-8?q?=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20Id=20=EA=B0=92=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 사용자 정보 조회 시, 원활함을 위해 Id값을 추가 --- .../com/bamboo/log/domain/user/jwt/service/JWTFilter.java | 6 +++--- .../com/bamboo/log/domain/user/jwt/service/JWTUtil.java | 7 ++++++- .../bamboo/log/domain/user/oauth/dto/CustomOAuth2User.java | 2 ++ .../java/com/bamboo/log/domain/user/oauth/dto/UserDTO.java | 1 + .../domain/user/oauth/service/CustomOAuth2UserService.java | 2 ++ .../domain/user/oauth/service/CustomSuccessHandler.java | 5 +++-- .../user/refresh/service/ProcessTokenReissueImpl.java | 6 +++--- 7 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/bamboo/log/domain/user/jwt/service/JWTFilter.java b/src/main/java/com/bamboo/log/domain/user/jwt/service/JWTFilter.java index 1698608..9f7e2c9 100644 --- a/src/main/java/com/bamboo/log/domain/user/jwt/service/JWTFilter.java +++ b/src/main/java/com/bamboo/log/domain/user/jwt/service/JWTFilter.java @@ -5,7 +5,6 @@ import io.jsonwebtoken.ExpiredJwtException; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; -import jakarta.servlet.http.Cookie; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.RequiredArgsConstructor; @@ -58,12 +57,13 @@ protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); return; } - - + Long userId = jwtUtil.getId(accessToken); String username = jwtUtil.getUsername(accessToken); String role = jwtUtil.getRole(accessToken); String name=jwtUtil.getName(accessToken); + UserDTO userDTO = UserDTO.builder() + .id(userId) .name(name) .username(username) .role(role) diff --git a/src/main/java/com/bamboo/log/domain/user/jwt/service/JWTUtil.java b/src/main/java/com/bamboo/log/domain/user/jwt/service/JWTUtil.java index 88ee472..c2dd261 100644 --- a/src/main/java/com/bamboo/log/domain/user/jwt/service/JWTUtil.java +++ b/src/main/java/com/bamboo/log/domain/user/jwt/service/JWTUtil.java @@ -43,8 +43,13 @@ public String getCategory(String token) { public String getName(String token){ return Jwts.parser().verifyWith(secretKey).build().parseSignedClaims(token).getPayload().get("name", String.class); } - public String createJwt(String category,String name,String username, String role, Long expiredMs) { + public Long getId(String token){ + return Jwts.parser().verifyWith(secretKey).build().parseSignedClaims(token).getPayload().get("id", Long.class); + } + + public String createJwt(Long id, String category,String name,String username, String role, Long expiredMs) { return Jwts.builder() + .claim("id", id) .claim("category",category) .claim("username", username) .claim("name",name) diff --git a/src/main/java/com/bamboo/log/domain/user/oauth/dto/CustomOAuth2User.java b/src/main/java/com/bamboo/log/domain/user/oauth/dto/CustomOAuth2User.java index bb7502a..29e2adb 100644 --- a/src/main/java/com/bamboo/log/domain/user/oauth/dto/CustomOAuth2User.java +++ b/src/main/java/com/bamboo/log/domain/user/oauth/dto/CustomOAuth2User.java @@ -46,4 +46,6 @@ public String getUsername() { return userDTO.getUsername(); } + public Long getId() { return userDTO.getId(); } + } \ No newline at end of file diff --git a/src/main/java/com/bamboo/log/domain/user/oauth/dto/UserDTO.java b/src/main/java/com/bamboo/log/domain/user/oauth/dto/UserDTO.java index efda413..54f3499 100644 --- a/src/main/java/com/bamboo/log/domain/user/oauth/dto/UserDTO.java +++ b/src/main/java/com/bamboo/log/domain/user/oauth/dto/UserDTO.java @@ -8,6 +8,7 @@ @Builder @Getter public class UserDTO { + private Long id; private String name; private String username; private String role; diff --git a/src/main/java/com/bamboo/log/domain/user/oauth/service/CustomOAuth2UserService.java b/src/main/java/com/bamboo/log/domain/user/oauth/service/CustomOAuth2UserService.java index b7f7c02..93fcb76 100644 --- a/src/main/java/com/bamboo/log/domain/user/oauth/service/CustomOAuth2UserService.java +++ b/src/main/java/com/bamboo/log/domain/user/oauth/service/CustomOAuth2UserService.java @@ -49,6 +49,7 @@ public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2Authentic userRepository.save(userEntity); UserDTO userDTO = UserDTO.builder() + .id(userEntity.getId()) .username(username) .name(oAuth2Response.getName()) .role("ROLE_USER") @@ -57,6 +58,7 @@ public OAuth2User loadUser(OAuth2UserRequest userRequest) throws OAuth2Authentic return new CustomOAuth2User(userDTO); } else { UserDTO userDTO = UserDTO.builder() + .id(existData.getId()) .username(existData.getUsername()) .name(existData.getName()) .role(existData.getRole()) diff --git a/src/main/java/com/bamboo/log/domain/user/oauth/service/CustomSuccessHandler.java b/src/main/java/com/bamboo/log/domain/user/oauth/service/CustomSuccessHandler.java index f82af92..c91ce65 100644 --- a/src/main/java/com/bamboo/log/domain/user/oauth/service/CustomSuccessHandler.java +++ b/src/main/java/com/bamboo/log/domain/user/oauth/service/CustomSuccessHandler.java @@ -30,6 +30,7 @@ public class CustomSuccessHandler extends SimpleUrlAuthenticationSuccessHandler @Override public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { CustomOAuth2User customUserDetails = (CustomOAuth2User) authentication.getPrincipal(); + Long userId = customUserDetails.getId(); String name=customUserDetails.getName(); String username = customUserDetails.getUsername(); Collection authorities = authentication.getAuthorities(); @@ -37,8 +38,8 @@ public void onAuthenticationSuccess(HttpServletRequest request, HttpServletRespo GrantedAuthority auth = iterator.next(); String role = auth.getAuthority(); - String refreshToken = jwtUtil.createJwt("refresh",name,username, role, 1800000L); - String accessToken = jwtUtil.createJwt("access",name,username, role, 1209600000L); + String refreshToken = jwtUtil.createJwt(userId,"refresh", name, username, role, 1800000L); + String accessToken = jwtUtil.createJwt(userId,"access", name, username, role, 1209600000L); addRefreshEntity(name, username, refreshToken, 1209600000L); response.addCookie(createCookie("refresh", refreshToken)); response.addCookie(UnScretCreateCookie("access", accessToken)); diff --git a/src/main/java/com/bamboo/log/domain/user/refresh/service/ProcessTokenReissueImpl.java b/src/main/java/com/bamboo/log/domain/user/refresh/service/ProcessTokenReissueImpl.java index 0e123ae..477002c 100644 --- a/src/main/java/com/bamboo/log/domain/user/refresh/service/ProcessTokenReissueImpl.java +++ b/src/main/java/com/bamboo/log/domain/user/refresh/service/ProcessTokenReissueImpl.java @@ -57,13 +57,13 @@ public ResponseEntity reissue(HttpServletRequest request, HttpServletResponse log.error("리프레시 토큰이 존재하지 않습니다. token: {}", refresh); return new ResponseEntity<>("invalid refresh token", HttpStatus.BAD_REQUEST); } - + Long userId = jwtUtil.getId(refresh); String name = jwtUtil.getName(refresh); String username = jwtUtil.getUsername(refresh); String role = jwtUtil.getRole(refresh); - String newAccess = jwtUtil.createJwt("access", name, username , role, 1800000L); - String newRefresh = jwtUtil.createJwt("refresh", name, username, role, 1209600000L); + String newAccess = jwtUtil.createJwt(userId,"access", name, username , role, 1800000L); + String newRefresh = jwtUtil.createJwt(userId,"refresh", name, username, role, 1209600000L); refreshRepository.deleteByToken(refresh); addRefreshEntity(name,username,role,1209600000L); From 751e2e5426ad7031b25f0ae422f9176b92b330c0 Mon Sep 17 00:00:00 2001 From: qhdudedi Date: Thu, 27 Feb 2025 23:52:58 +0900 Subject: [PATCH 2/5] =?UTF-8?q?Feat:=20=EC=A3=BD=EC=88=9C=EC=9D=B4=20?= =?UTF-8?q?=EC=97=94=ED=8B=B0=ED=8B=B0=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 유저<->죽순이 1:1 연관관계 매핑 --- .../domain/user/oauth/entity/UserEntity.java | 4 +++ .../bamboo/log/juksoon/domain/Juksoon.java | 25 +++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 src/main/java/com/bamboo/log/juksoon/domain/Juksoon.java diff --git a/src/main/java/com/bamboo/log/domain/user/oauth/entity/UserEntity.java b/src/main/java/com/bamboo/log/domain/user/oauth/entity/UserEntity.java index 2a3be77..03b88bc 100644 --- a/src/main/java/com/bamboo/log/domain/user/oauth/entity/UserEntity.java +++ b/src/main/java/com/bamboo/log/domain/user/oauth/entity/UserEntity.java @@ -1,5 +1,6 @@ package com.bamboo.log.domain.user.oauth.entity; +import com.bamboo.log.juksoon.domain.Juksoon; import jakarta.persistence.*; import lombok.Builder; import lombok.Getter; @@ -24,6 +25,9 @@ public class UserEntity { private String role; private String profile_img_url; + @OneToOne(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true) + private Juksoon juksooni; + @Builder public UserEntity(String username, String name, String email, String role,String profile_img_url) { this.username = username; diff --git a/src/main/java/com/bamboo/log/juksoon/domain/Juksoon.java b/src/main/java/com/bamboo/log/juksoon/domain/Juksoon.java new file mode 100644 index 0000000..267b79e --- /dev/null +++ b/src/main/java/com/bamboo/log/juksoon/domain/Juksoon.java @@ -0,0 +1,25 @@ +package com.bamboo.log.juksoon.domain; + +import com.bamboo.log.domain.user.oauth.entity.UserEntity; +import jakarta.persistence.*; +import lombok.*; + +@Getter +@Entity +@NoArgsConstructor +@AllArgsConstructor +@Table(name = "juksooni") +@Builder +public class Juksoon { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @OneToOne + @JoinColumn(name = "user_id", nullable = false, unique = true) + private UserEntity user; + + public static Juksoon create(UserEntity user) { + return Juksoon.builder().user(user).build(); + } +} From caa13947831a684c16b31d90f867eeec325e084b Mon Sep 17 00:00:00 2001 From: qhdudedi Date: Thu, 27 Feb 2025 23:53:48 +0900 Subject: [PATCH 3/5] =?UTF-8?q?Feat:=20=EC=A3=BD=EC=88=9C=EC=9D=B4=20?= =?UTF-8?q?=EC=97=AC=EB=B6=80=20=EC=A1=B0=ED=9A=8C=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../juksoon/controller/JuksoonController.java | 30 +++++++++++++++++++ .../log/juksoon/dto/JuksooniResponse.java | 8 +++++ .../juksoon/repository/JuksoonRepository.java | 9 ++++++ .../log/juksoon/service/JuksoonService.java | 7 +++++ .../juksoon/service/JuksoonServiceImpl.java | 22 ++++++++++++++ 5 files changed, 76 insertions(+) create mode 100644 src/main/java/com/bamboo/log/juksoon/controller/JuksoonController.java create mode 100644 src/main/java/com/bamboo/log/juksoon/dto/JuksooniResponse.java create mode 100644 src/main/java/com/bamboo/log/juksoon/repository/JuksoonRepository.java create mode 100644 src/main/java/com/bamboo/log/juksoon/service/JuksoonService.java create mode 100644 src/main/java/com/bamboo/log/juksoon/service/JuksoonServiceImpl.java diff --git a/src/main/java/com/bamboo/log/juksoon/controller/JuksoonController.java b/src/main/java/com/bamboo/log/juksoon/controller/JuksoonController.java new file mode 100644 index 0000000..78c6b6f --- /dev/null +++ b/src/main/java/com/bamboo/log/juksoon/controller/JuksoonController.java @@ -0,0 +1,30 @@ +package com.bamboo.log.juksoon.controller; + +import com.bamboo.log.domain.user.oauth.dto.CustomOAuth2User; +import com.bamboo.log.juksoon.dto.JuksooniResponse; +import com.bamboo.log.juksoon.service.JuksoonService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + + +@RestController +@RequestMapping("/api/juksooni") +@RequiredArgsConstructor +public class JuksoonController { + private final JuksoonService juksoonService; + + @GetMapping("/status") + public ResponseEntity checkJuksooniStatus( + @AuthenticationPrincipal CustomOAuth2User customOAuth2User) { + + Long userId = customOAuth2User.getId(); + JuksooniResponse response = juksoonService.checkJuksooniStatus(userId); + + return ResponseEntity.status(HttpStatus.OK).body(response); + } +} \ No newline at end of file diff --git a/src/main/java/com/bamboo/log/juksoon/dto/JuksooniResponse.java b/src/main/java/com/bamboo/log/juksoon/dto/JuksooniResponse.java new file mode 100644 index 0000000..cd4fe9b --- /dev/null +++ b/src/main/java/com/bamboo/log/juksoon/dto/JuksooniResponse.java @@ -0,0 +1,8 @@ +package com.bamboo.log.juksoon.dto; + +import org.springframework.http.HttpStatus; + +public record JuksooniResponse( + HttpStatus status, + boolean hasJuksooni +) { } diff --git a/src/main/java/com/bamboo/log/juksoon/repository/JuksoonRepository.java b/src/main/java/com/bamboo/log/juksoon/repository/JuksoonRepository.java new file mode 100644 index 0000000..8bf6a64 --- /dev/null +++ b/src/main/java/com/bamboo/log/juksoon/repository/JuksoonRepository.java @@ -0,0 +1,9 @@ +package com.bamboo.log.juksoon.repository; + +import com.bamboo.log.juksoon.domain.Juksoon; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface JuksoonRepository extends JpaRepository { + boolean existsByUserId(Long userId); + +} diff --git a/src/main/java/com/bamboo/log/juksoon/service/JuksoonService.java b/src/main/java/com/bamboo/log/juksoon/service/JuksoonService.java new file mode 100644 index 0000000..a391cf9 --- /dev/null +++ b/src/main/java/com/bamboo/log/juksoon/service/JuksoonService.java @@ -0,0 +1,7 @@ +package com.bamboo.log.juksoon.service; + +import com.bamboo.log.juksoon.dto.JuksooniResponse; + +public interface JuksoonService { + JuksooniResponse checkJuksooniStatus(Long userId); +} diff --git a/src/main/java/com/bamboo/log/juksoon/service/JuksoonServiceImpl.java b/src/main/java/com/bamboo/log/juksoon/service/JuksoonServiceImpl.java new file mode 100644 index 0000000..dacf9db --- /dev/null +++ b/src/main/java/com/bamboo/log/juksoon/service/JuksoonServiceImpl.java @@ -0,0 +1,22 @@ +package com.bamboo.log.juksoon.service; + +import com.bamboo.log.juksoon.dto.JuksooniResponse; +import com.bamboo.log.juksoon.repository.JuksoonRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class JuksoonServiceImpl implements JuksoonService{ + + private final JuksoonRepository juksoonRepository; + + @Override + public JuksooniResponse checkJuksooniStatus(Long userId) { + boolean hasJuksooni = juksoonRepository.existsByUserId(userId); + return new JuksooniResponse(HttpStatus.OK, hasJuksooni); + } +} From f1956086114da9ec9be1a95512f825cc5714e89b Mon Sep 17 00:00:00 2001 From: qhdudedi Date: Fri, 28 Feb 2025 01:58:46 +0900 Subject: [PATCH 4/5] =?UTF-8?q?Refactor:=20=EB=AF=B8=EC=82=AC=EC=9A=A9=20?= =?UTF-8?q?=EB=A9=94=EC=84=9C=EB=93=9C=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/bamboo/log/juksoon/domain/Juksoon.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/com/bamboo/log/juksoon/domain/Juksoon.java b/src/main/java/com/bamboo/log/juksoon/domain/Juksoon.java index 267b79e..bd8dfcc 100644 --- a/src/main/java/com/bamboo/log/juksoon/domain/Juksoon.java +++ b/src/main/java/com/bamboo/log/juksoon/domain/Juksoon.java @@ -19,7 +19,4 @@ public class Juksoon { @JoinColumn(name = "user_id", nullable = false, unique = true) private UserEntity user; - public static Juksoon create(UserEntity user) { - return Juksoon.builder().user(user).build(); - } } From 28ec3637436159633c89f469c4ba321fc23c5e6a Mon Sep 17 00:00:00 2001 From: qhdudedi Date: Fri, 28 Feb 2025 01:59:28 +0900 Subject: [PATCH 5/5] =?UTF-8?q?Feat:=20=EC=A3=BD=EC=88=9C=EC=9D=B4=20?= =?UTF-8?q?=EB=B6=84=EC=96=91=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../juksoon/controller/JuksoonController.java | 18 +++++++++- .../log/juksoon/service/JuksoonService.java | 1 + .../juksoon/service/JuksoonServiceImpl.java | 34 +++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/bamboo/log/juksoon/controller/JuksoonController.java b/src/main/java/com/bamboo/log/juksoon/controller/JuksoonController.java index 78c6b6f..b96dd38 100644 --- a/src/main/java/com/bamboo/log/juksoon/controller/JuksoonController.java +++ b/src/main/java/com/bamboo/log/juksoon/controller/JuksoonController.java @@ -3,11 +3,14 @@ import com.bamboo.log.domain.user.oauth.dto.CustomOAuth2User; import com.bamboo.log.juksoon.dto.JuksooniResponse; import com.bamboo.log.juksoon.service.JuksoonService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -15,16 +18,29 @@ @RestController @RequestMapping("/api/juksooni") @RequiredArgsConstructor +@Tag(name = "Juksooni", description = "죽순이 분양 관련 API") public class JuksoonController { private final JuksoonService juksoonService; + @PostMapping("/adopt") + @Operation(summary = "죽순이 분양", description = "JWT 토큰이 필요합니다.") + public ResponseEntity adoptJuksooni( + @AuthenticationPrincipal CustomOAuth2User customOAuth2User) { + + Long userId = customOAuth2User.getId(); + JuksooniResponse response = juksoonService.adoptJuksooni(userId); + return ResponseEntity.status(HttpStatus.CREATED).body(response); + } + @GetMapping("/status") + @Operation(summary = "죽순이 분양 여부 조회", description = "JWT 토큰이 필요합니다.") public ResponseEntity checkJuksooniStatus( @AuthenticationPrincipal CustomOAuth2User customOAuth2User) { Long userId = customOAuth2User.getId(); JuksooniResponse response = juksoonService.checkJuksooniStatus(userId); - return ResponseEntity.status(HttpStatus.OK).body(response); + return ResponseEntity.ok(response); + } } \ No newline at end of file diff --git a/src/main/java/com/bamboo/log/juksoon/service/JuksoonService.java b/src/main/java/com/bamboo/log/juksoon/service/JuksoonService.java index a391cf9..daf9999 100644 --- a/src/main/java/com/bamboo/log/juksoon/service/JuksoonService.java +++ b/src/main/java/com/bamboo/log/juksoon/service/JuksoonService.java @@ -3,5 +3,6 @@ import com.bamboo.log.juksoon.dto.JuksooniResponse; public interface JuksoonService { + JuksooniResponse adoptJuksooni(Long userId); JuksooniResponse checkJuksooniStatus(Long userId); } diff --git a/src/main/java/com/bamboo/log/juksoon/service/JuksoonServiceImpl.java b/src/main/java/com/bamboo/log/juksoon/service/JuksoonServiceImpl.java index dacf9db..f866361 100644 --- a/src/main/java/com/bamboo/log/juksoon/service/JuksoonServiceImpl.java +++ b/src/main/java/com/bamboo/log/juksoon/service/JuksoonServiceImpl.java @@ -1,11 +1,15 @@ package com.bamboo.log.juksoon.service; +import com.bamboo.log.domain.user.oauth.entity.UserEntity; +import com.bamboo.log.domain.user.oauth.repository.UserRepository; +import com.bamboo.log.juksoon.domain.Juksoon; import com.bamboo.log.juksoon.dto.JuksooniResponse; import com.bamboo.log.juksoon.repository.JuksoonRepository; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Slf4j @Service @@ -13,10 +17,40 @@ public class JuksoonServiceImpl implements JuksoonService{ private final JuksoonRepository juksoonRepository; + private final UserRepository userRepository; + // 죽순이 분양 로직 @Override + @Transactional + public JuksooniResponse adoptJuksooni(Long userId) { + if (userId == null) { + throw new IllegalArgumentException("유저 ID가 null입니다."); + } + + // 이미 죽순이를 분양받았는지 확인 + if (juksoonRepository.existsByUserId(userId)) { + return new JuksooniResponse(HttpStatus.CONFLICT, false); + } + + // 유저 조회 + UserEntity user = userRepository.findById(userId) + .orElseThrow(() -> new RuntimeException("해당 유저를 찾을 수 없습니다.")); + + // 죽순이 생성 및 저장 + Juksoon juksoon = Juksoon.builder() + .user(user) + .build(); + juksoonRepository.save(juksoon); + + return new JuksooniResponse(HttpStatus.CREATED, true); + } + + // 죽순이 분양 여부 조회 로직 + @Override + @Transactional(readOnly = true) public JuksooniResponse checkJuksooniStatus(Long userId) { boolean hasJuksooni = juksoonRepository.existsByUserId(userId); + return new JuksooniResponse(HttpStatus.OK, hasJuksooni); } }