diff --git a/src/main/java/Devroup/hidaddy/controller/AuthController.java b/src/main/java/Devroup/hidaddy/controller/AuthController.java index 3c8f9f2..21a3e54 100644 --- a/src/main/java/Devroup/hidaddy/controller/AuthController.java +++ b/src/main/java/Devroup/hidaddy/controller/AuthController.java @@ -7,6 +7,7 @@ import Devroup.hidaddy.dto.auth.LogoutRequest; import Devroup.hidaddy.dto.auth.RefreshTokenRequest; import Devroup.hidaddy.repository.auth.RefreshTokenRepository; +import Devroup.hidaddy.repository.user.UserRepository; import Devroup.hidaddy.security.UserDetailsImpl; import Devroup.hidaddy.service.AuthService; import Devroup.hidaddy.service.UserService; @@ -38,6 +39,7 @@ public class AuthController { private final RefreshTokenRepository refreshTokenRepository; private final UserService userService; private final AuthService authService; + private final UserRepository userRepository; @Operation( summary = "Access Token 재발급", @@ -55,7 +57,7 @@ public ResponseEntity refreshAccessToken( return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("유효하지 않거나 만료된 리프레시 토큰"); } - User user = foundToken.getUser(); + User user = userRepository.findById(foundToken.getUser().getId()).orElseThrow(); String newAccessToken = jwtUtil.createAccessToken(user); return ResponseEntity.ok(Map.of( @@ -88,13 +90,14 @@ public ResponseEntity oauth2Callback( ? authService.getNaverEmail(accessToken) : JwtUtil.decodeClaim(idToken, "email"); - Map tokens = userService.saveOrLoginUser( + Map tokens = userService.saveOrLoginUser( null, email, null, null, provider.toUpperCase(), socialId ); return ResponseEntity.ok(Map.of( "accessToken", tokens.get("accessToken"), "refreshToken", tokens.get("refreshToken"), + "signed", !(Boolean) tokens.get("isNewUser"), // 기존 유저면 true "message", "로그인 성공" )); } catch (Exception e) { diff --git a/src/main/java/Devroup/hidaddy/controller/UserController.java b/src/main/java/Devroup/hidaddy/controller/UserController.java index 1a41fd3..b6f3071 100644 --- a/src/main/java/Devroup/hidaddy/controller/UserController.java +++ b/src/main/java/Devroup/hidaddy/controller/UserController.java @@ -1,12 +1,9 @@ package Devroup.hidaddy.controller; import Devroup.hidaddy.dto.user.*; -import Devroup.hidaddy.entity.Baby; -import Devroup.hidaddy.entity.User; import Devroup.hidaddy.security.UserDetailsImpl; import Devroup.hidaddy.service.BabyService; import Devroup.hidaddy.service.UserService; -import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.MediaType; import org.springframework.web.multipart.MultipartFile; import io.swagger.v3.oas.annotations.Operation; @@ -18,7 +15,6 @@ import org.springframework.web.bind.annotation.*; import io.swagger.v3.oas.annotations.tags.Tag; -import java.time.LocalDate; import java.util.List; @Tag( @@ -136,28 +132,23 @@ public ResponseEntity getBaby( } // 아기 수정 (이름, 날짜, 이미지) - @PatchMapping(value = "/baby/{babyId}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) - @Operation(summary = "아기 정보 수정 (JSON + 이미지 Multipart)", description = "지정된 아기의 이름, 출산 예정일, 프로필 이미지 등을 수정합니다.") + @PatchMapping("/baby/{babyId}") + @Operation(summary = "아기 정보 수정", description = "지정된 아기의 이름, 출산 예정일 등을 수정합니다.") @ApiResponses({ @ApiResponse(responseCode = "200", description = "수정 성공"), - @ApiResponse(responseCode = "400", description = "잘못된 요청") + @ApiResponse(responseCode = "400", description = "잘못된 요청"), + @ApiResponse(responseCode = "401", description = "인증되지 않은 사용자 (로그인 필요)") }) public ResponseEntity updateBaby( @PathVariable Long babyId, - @RequestParam("name") String name, - @RequestParam("dueDate") @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate dueDate, - @RequestPart(value = "image", required = false) MultipartFile image, + @RequestBody BabyUpdateRequest dto, @AuthenticationPrincipal UserDetailsImpl userDetails ) { if (userDetails == null) { return ResponseEntity.status(401).build(); } - BabyUpdateRequest dto = new BabyUpdateRequest(); - dto.setName(name); - dto.setDueDate(dueDate); - - BabyResponse response = babyService.updateBaby(userDetails.getUser(), babyId, dto, image); + BabyResponse response = babyService.updateBaby(userDetails.getUser(), babyId, dto); return ResponseEntity.ok(response); } diff --git a/src/main/java/Devroup/hidaddy/dto/user/BabyRegisterRequest.java b/src/main/java/Devroup/hidaddy/dto/user/BabyRegisterRequest.java index 7eab026..be54827 100644 --- a/src/main/java/Devroup/hidaddy/dto/user/BabyRegisterRequest.java +++ b/src/main/java/Devroup/hidaddy/dto/user/BabyRegisterRequest.java @@ -1,7 +1,6 @@ package Devroup.hidaddy.dto.user; import lombok.Getter; -import lombok.Setter; import java.time.LocalDate; import java.time.LocalDateTime; diff --git a/src/main/java/Devroup/hidaddy/dto/user/BabyResponse.java b/src/main/java/Devroup/hidaddy/dto/user/BabyResponse.java index fd5e5ba..cdeeded 100644 --- a/src/main/java/Devroup/hidaddy/dto/user/BabyResponse.java +++ b/src/main/java/Devroup/hidaddy/dto/user/BabyResponse.java @@ -14,12 +14,10 @@ public class BabyResponse { private String name; @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") // 날짜 포맷 지정 private LocalDate dueDate; - private String profileImage; public BabyResponse(Baby baby) { this.id = baby.getId(); this.name = baby.getName(); this.dueDate = baby.getDueDate().toLocalDate(); - this.profileImage = baby.getBabyImageUrl(); // 있으면 가져오기 } } diff --git a/src/main/java/Devroup/hidaddy/service/BabyService.java b/src/main/java/Devroup/hidaddy/service/BabyService.java index 9a90ee8..ec6f319 100644 --- a/src/main/java/Devroup/hidaddy/service/BabyService.java +++ b/src/main/java/Devroup/hidaddy/service/BabyService.java @@ -47,7 +47,7 @@ public BabyResponse getBaby(User user, Long babyId) { // 아기 수정 @Transactional - public BabyResponse updateBaby(User user, Long babyId, BabyUpdateRequest dto, MultipartFile image) { + public BabyResponse updateBaby(User user, Long babyId, BabyUpdateRequest dto) { Baby baby = babyRepository.findById(babyId) .orElseThrow(() -> new IllegalArgumentException("해당 아기를 찾을 수 없습니다.")); @@ -58,19 +58,6 @@ public BabyResponse updateBaby(User user, Long babyId, BabyUpdateRequest dto, Mu if (dto.getName() != null) baby.setName(dto.getName()); if (dto.getDueDate() != null) baby.setDueDate(dto.getDueDate().atStartOfDay()); - if (image != null && !image.isEmpty()) { - // 기존 이미지 삭제 - if (baby.getBabyImageUrl() != null && !baby.getBabyImageUrl().isEmpty()) { - String imageKey = baby.getBabyImageUrl().replace(cloudFrontDomain + "/", ""); - s3Uploader.delete(imageKey); - } - - // 새 이미지 업로드 - String imageUrl = s3Uploader.upload(image, "baby-profile"); - imageUrl = cloudFrontDomain + "/" + imageUrl; - baby.setBabyImageUrl(imageUrl); - } - return new BabyResponse(babyRepository.save(baby)); } @@ -85,11 +72,11 @@ public void deleteBaby(User user, Long babyId) { } @Transactional - public BabyResponse registerBabyBasic(BabyBasicRegisterRequest request, User user) { + public BabyResponse registerBabyBasic(BabyBasicRegisterRequest dto, User user) { // 아기 생성 Baby baby = Baby.builder() - .name(request.getBabyName()) - .dueDate(request.getParsedDueDate()) + .name(dto.getBabyName()) + .dueDate(dto.getParsedDueDate()) .user(user) .build(); diff --git a/src/main/java/Devroup/hidaddy/service/UserService.java b/src/main/java/Devroup/hidaddy/service/UserService.java index 80f7504..e8687f1 100644 --- a/src/main/java/Devroup/hidaddy/service/UserService.java +++ b/src/main/java/Devroup/hidaddy/service/UserService.java @@ -17,6 +17,7 @@ import java.time.LocalDateTime; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; @Service @RequiredArgsConstructor @@ -30,22 +31,19 @@ public class UserService { private String cloudFrontDomain; public void registerBaby(BabyRegisterRequest dto, User user) { - // 1. 유저 이름 업데이트 + // 유저 이름 업데이트 user.setName(dto.getUserName()); - // 2. dueDate 파싱 - LocalDateTime dueDate = dto.getParsedDueDate(); - - // 3. 아기 생성 + // 아기 생성 Baby baby = Baby.builder() .name(dto.getBabyName()) - .dueDate(dueDate) + .dueDate(dto.getParsedDueDate()) .user(user) .build(); babyRepository.save(baby); - // 4. 선택된 아기 ID 설정 + // 선택된 아기 ID 설정 user.setSelectedBabyId(baby.getId()); userRepository.save(user); } @@ -76,9 +74,11 @@ public void changeUserName(User user, String userName) { private final RefreshTokenRepository refreshTokenRepository; private final JwtUtil jwtUtil; - public Map saveOrLoginUser(String name, String email, String phone, + public Map saveOrLoginUser(String name, String email, String phone, String partnerPhone, String loginType, String socialId) { + AtomicBoolean isNewUser = new AtomicBoolean(false); + // 유저 조회 또는 생성 User user = userRepository.findBySocialIdAndLoginType(socialId, loginType) .orElseGet(() -> { @@ -89,7 +89,8 @@ public Map saveOrLoginUser(String name, String email, String pho newUser.setPartnerPhone(partnerPhone); newUser.setLoginType(loginType); newUser.setSocialId(socialId); - newUser.setProfileImageUrl(cloudFrontDomain + "/profile/default_image.svg"); // 기본 프로필 이미지 URL 설정 + newUser.setProfileImageUrl(cloudFrontDomain + "/profile/default_image.svg"); + isNewUser.set(true); return userRepository.save(newUser); }); @@ -98,7 +99,7 @@ public Map saveOrLoginUser(String name, String email, String pho String refreshTokenStr = jwtUtil.createRefreshToken(); LocalDateTime expiredAt = LocalDateTime.now().plusDays(365); - // RefreshToken DB에 저장 (기존 존재 여부에 따라 분기) + // RefreshToken DB 저장 또는 갱신 RefreshToken existing = refreshTokenRepository.findByUser(user).orElse(null); if (existing != null) { existing.updateToken(refreshTokenStr, expiredAt); @@ -108,11 +109,13 @@ public Map saveOrLoginUser(String name, String email, String pho refreshTokenRepository.save(refreshToken); } - // 응답으로 전달할 토큰들 - Map tokens = new HashMap<>(); - tokens.put("accessToken", accessToken); - tokens.put("refreshToken", refreshTokenStr); - return tokens; + // 응답 데이터 구성 + Map response = new HashMap<>(); + response.put("accessToken", accessToken); + response.put("refreshToken", refreshTokenStr); + response.put("isNewUser", isNewUser.get()); // true = 처음 가입한 유저 + + return response; } @Transactional