diff --git a/core/src/main/java/org/haedal/zzansuni/core/api/ApiResponse.java b/core/src/main/java/org/haedal/zzansuni/core/api/ApiResponse.java index af5a9db..3f164cb 100644 --- a/core/src/main/java/org/haedal/zzansuni/core/api/ApiResponse.java +++ b/core/src/main/java/org/haedal/zzansuni/core/api/ApiResponse.java @@ -18,6 +18,14 @@ public static ApiResponse success(T data) { .build(); } + public static ApiResponse success(T data, String message) { + return ApiResponse.builder() + .result(Result.SUCCESS) + .data(data) + .message(message) + .build(); + } + public static ApiResponse fail(String errorCode, String message) { return ApiResponse.builder() .result(Result.FAIL) diff --git a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/controller/user/UserController.java b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/controller/user/UserController.java index 4a384d7..234f015 100644 --- a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/controller/user/UserController.java +++ b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/controller/user/UserController.java @@ -3,8 +3,10 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.haedal.zzansuni.core.api.ApiResponse; +import org.haedal.zzansuni.domain.user.UserService; import org.haedal.zzansuni.global.jwt.JwtUser; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; @@ -17,6 +19,7 @@ @RequiredArgsConstructor @RestController public class UserController { + private final UserService userService; @Operation(summary = "내 정보 조회", description = "내 정보를 조회한다.") @GetMapping("/api/user") @@ -32,8 +35,13 @@ public ApiResponse getUserInfo( @Operation(summary = "내 정보 수정", description = "내 정보를 수정한다.") @PatchMapping("/api/user") - public ApiResponse updateUser(@RequestBody UserReq.UserUpdateRequest request) { - return ApiResponse.success(null); + public ApiResponse updateUser( + @Valid @RequestBody UserReq.UserUpdateRequest request, + @AuthenticationPrincipal JwtUser jwtUser + ) { + var command = request.toCommand(); + userService.updateUser(jwtUser.getId(), command); + return ApiResponse.success(null, "수정에 성공하였습니다."); } @Operation(summary = "스트릭 조회", description = "스트릭을 조회한다.") diff --git a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/controller/user/UserReq.java b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/controller/user/UserReq.java index 26d3fab..f210d97 100644 --- a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/controller/user/UserReq.java +++ b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/controller/user/UserReq.java @@ -1,5 +1,16 @@ package org.haedal.zzansuni.controller.user; +import jakarta.validation.constraints.NotBlank; +import org.haedal.zzansuni.domain.user.UserCommand; + public class UserReq { - public record UserUpdateRequest(String nickname){} + public record UserUpdateRequest( + @NotBlank(message = "nickname은 필수입니다.") String nickname + ) { + public UserCommand.Update toCommand() { + return UserCommand.Update.builder() + .nickname(nickname) + .build(); + } + } } diff --git a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/user/User.java b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/user/User.java index 15e3a52..f03c8f7 100644 --- a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/user/User.java +++ b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/user/User.java @@ -1,4 +1,39 @@ package org.haedal.zzansuni.domain.user; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.haedal.zzansuni.global.security.Role; + +@Getter +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table(name = "users") public class User { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private String nickname; + + @Enumerated(EnumType.STRING) + @Column(nullable = false) + private Role role; + + private String email; + + private String password; + + @Column(nullable = false) + private Integer exp; + + private String authToken; + + private String profileImageUrl; + + public void update(UserCommand.Update userUpdate) { + this.nickname = userUpdate.getNickname(); + } } diff --git a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/user/UserCommand.java b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/user/UserCommand.java new file mode 100644 index 0000000..51d46dc --- /dev/null +++ b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/user/UserCommand.java @@ -0,0 +1,21 @@ +package org.haedal.zzansuni.domain.user; + +import jakarta.validation.constraints.NotBlank; +import lombok.Builder; +import lombok.Getter; +import org.haedal.zzansuni.core.utils.SelfValidating; + +public class UserCommand { + + @Getter + @Builder + public static class Update extends SelfValidating { + @NotBlank(message = "닉네임은 필수입니다.") + private String nickname; + + public Update(String nickname) { + this.nickname = nickname; + this.validateSelf(); + } + } +} diff --git a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/user/UserModel.java b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/user/UserModel.java index 22312fb..9652ba7 100644 --- a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/user/UserModel.java +++ b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/user/UserModel.java @@ -2,7 +2,7 @@ public class UserModel { - public static UserModel from(User user){ + public static UserModel from(User user) { throw new UnsupportedOperationException("Not supported yet."); } } diff --git a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/user/UserReader.java b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/user/UserReader.java new file mode 100644 index 0000000..f2cd935 --- /dev/null +++ b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/user/UserReader.java @@ -0,0 +1,9 @@ +package org.haedal.zzansuni.domain.user; + +import java.util.Optional; + +public interface UserReader { + User getById(Long id); + + Optional findByAuthToken(String authToken); +} diff --git a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/user/UserService.java b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/user/UserService.java index eab4e59..ec33aad 100644 --- a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/user/UserService.java +++ b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/user/UserService.java @@ -1,4 +1,21 @@ package org.haedal.zzansuni.domain.user; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@RequiredArgsConstructor +@Service public class UserService { + private final UserReader userReader; + private final UserStore userStore; + + /** + * 수정해야할 정보를 받고 해당 값으로 모두 업데이트 + */ + @Transactional + public void updateUser(Long id, UserCommand.Update userUpdate) { + User user = userReader.getById(id); + user.update(userUpdate); + } } diff --git a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/user/UserStore.java b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/user/UserStore.java new file mode 100644 index 0000000..ddcd726 --- /dev/null +++ b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/user/UserStore.java @@ -0,0 +1,5 @@ +package org.haedal.zzansuni.domain.user; + +public interface UserStore { + User store(User user); +} diff --git a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/infrastructure/user/UserReaderImpl.java b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/infrastructure/user/UserReaderImpl.java new file mode 100644 index 0000000..97d5360 --- /dev/null +++ b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/infrastructure/user/UserReaderImpl.java @@ -0,0 +1,25 @@ +package org.haedal.zzansuni.infrastructure.user; + +import jakarta.persistence.EntityNotFoundException; +import lombok.RequiredArgsConstructor; +import org.haedal.zzansuni.domain.user.User; +import org.haedal.zzansuni.domain.user.UserReader; +import org.springframework.stereotype.Component; + +import java.util.Optional; + +@Component +@RequiredArgsConstructor +public class UserReaderImpl implements UserReader { + private final UserRepository userRepository; + + @Override + public User getById(Long id) { + return userRepository.findById(id).orElseThrow(EntityNotFoundException::new); + } + + @Override + public Optional findByAuthToken(String authToken) { + return userRepository.findByAuthToken(authToken); + } +} diff --git a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/infrastructure/user/UserRepository.java b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/infrastructure/user/UserRepository.java new file mode 100644 index 0000000..ad3604e --- /dev/null +++ b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/infrastructure/user/UserRepository.java @@ -0,0 +1,10 @@ +package org.haedal.zzansuni.infrastructure.user; + +import org.haedal.zzansuni.domain.user.User; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +public interface UserRepository extends JpaRepository { + Optional findByAuthToken(String authToken); +} diff --git a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/infrastructure/user/UserStoreImpl.java b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/infrastructure/user/UserStoreImpl.java new file mode 100644 index 0000000..05fe0ee --- /dev/null +++ b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/infrastructure/user/UserStoreImpl.java @@ -0,0 +1,17 @@ +package org.haedal.zzansuni.infrastructure.user; + +import lombok.RequiredArgsConstructor; +import org.haedal.zzansuni.domain.user.User; +import org.haedal.zzansuni.domain.user.UserStore; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class UserStoreImpl implements UserStore { + private final UserRepository userRepository; + + @Override + public User store(User user) { + return userRepository.save(user); + } +}