From c0686c26d82eae6ab9ac84c6dcb58a9c67ac093b Mon Sep 17 00:00:00 2001 From: seongjunnoh Date: Thu, 26 Jun 2025 17:34:02 +0900 Subject: [PATCH 01/14] =?UTF-8?q?[refactor]=20:=20User=20=EC=97=90=20email?= =?UTF-8?q?=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80=20(#28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../thip/user/adapter/out/jpa/UserJpaEntity.java | 3 +++ .../thip/user/adapter/out/mapper/UserMapper.java | 2 ++ src/main/java/konkuk/thip/user/domain/User.java | 13 +++++++++++++ 3 files changed, 18 insertions(+) diff --git a/src/main/java/konkuk/thip/user/adapter/out/jpa/UserJpaEntity.java b/src/main/java/konkuk/thip/user/adapter/out/jpa/UserJpaEntity.java index 2663aafb5..787454e8c 100644 --- a/src/main/java/konkuk/thip/user/adapter/out/jpa/UserJpaEntity.java +++ b/src/main/java/konkuk/thip/user/adapter/out/jpa/UserJpaEntity.java @@ -18,6 +18,9 @@ public class UserJpaEntity extends BaseJpaEntity { @Column(name = "user_id") private Long userId; + @Column(name = "email", length = 30, nullable = false) + private String email; + @Column(length = 60, nullable = false) private String nickname; diff --git a/src/main/java/konkuk/thip/user/adapter/out/mapper/UserMapper.java b/src/main/java/konkuk/thip/user/adapter/out/mapper/UserMapper.java index c91558dd4..38780e9ef 100644 --- a/src/main/java/konkuk/thip/user/adapter/out/mapper/UserMapper.java +++ b/src/main/java/konkuk/thip/user/adapter/out/mapper/UserMapper.java @@ -11,6 +11,7 @@ public class UserMapper { public UserJpaEntity toJpaEntity(User user, AliasJpaEntity aliasJpaEntity) { return UserJpaEntity.builder() + .email(user.getEmail()) .nickname(user.getNickname()) .imageUrl(user.getImageUrl()) .role(UserRole.from(user.getUserRole())) @@ -21,6 +22,7 @@ public UserJpaEntity toJpaEntity(User user, AliasJpaEntity aliasJpaEntity) { public User toDomainEntity(UserJpaEntity userJpaEntity) { return User.builder() .id(userJpaEntity.getUserId()) + .email(userJpaEntity.getEmail()) .nickname(userJpaEntity.getNickname()) .imageUrl(userJpaEntity.getImageUrl()) .userRole(userJpaEntity.getRole().getType()) diff --git a/src/main/java/konkuk/thip/user/domain/User.java b/src/main/java/konkuk/thip/user/domain/User.java index 889956d26..b7d1e1ebf 100644 --- a/src/main/java/konkuk/thip/user/domain/User.java +++ b/src/main/java/konkuk/thip/user/domain/User.java @@ -10,6 +10,8 @@ public class User extends BaseDomainEntity { private Long id; + private String email; + private String nickname; private String imageUrl; @@ -18,4 +20,15 @@ public class User extends BaseDomainEntity { private Long aliasId; + public static User withoutId(String email, String nickname, String imageUrl, String userRole, Long aliasId) { + return User.builder() + .id(null) + .email(email) + .nickname(nickname) + .imageUrl(imageUrl) + .userRole(userRole) + .aliasId(aliasId) + .build(); + } + } From dad6d077dc84f0b28adfc1f43a6ca104dc442d39 Mon Sep 17 00:00:00 2001 From: seongjunnoh Date: Thu, 26 Jun 2025 17:34:25 +0900 Subject: [PATCH 02/14] =?UTF-8?q?[refactor]=20:=20Alias=20=EC=97=90=20imag?= =?UTF-8?q?eUrl,=20color=20=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80=20(#28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../konkuk/thip/user/adapter/out/jpa/AliasJpaEntity.java | 7 ++++++- .../konkuk/thip/user/adapter/out/mapper/AliasMapper.java | 4 ++++ src/main/java/konkuk/thip/user/domain/Alias.java | 4 ++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/main/java/konkuk/thip/user/adapter/out/jpa/AliasJpaEntity.java b/src/main/java/konkuk/thip/user/adapter/out/jpa/AliasJpaEntity.java index 45356bee4..a5e885417 100644 --- a/src/main/java/konkuk/thip/user/adapter/out/jpa/AliasJpaEntity.java +++ b/src/main/java/konkuk/thip/user/adapter/out/jpa/AliasJpaEntity.java @@ -18,7 +18,12 @@ public class AliasJpaEntity extends BaseJpaEntity { @Column(name = "alias_id") private Long aliasId; - @Column(name = "alias_value",length = 50, nullable = false) + @Column(name = "alias_value", length = 50, nullable = false) private String value; + @Column(name = "image_url", columnDefinition = "TEXT", nullable = false) + private String imageUrl; + + @Column(name = "alias_color", length = 10, nullable = false) + private String color; } diff --git a/src/main/java/konkuk/thip/user/adapter/out/mapper/AliasMapper.java b/src/main/java/konkuk/thip/user/adapter/out/mapper/AliasMapper.java index bf53f67f7..eac3e0f45 100644 --- a/src/main/java/konkuk/thip/user/adapter/out/mapper/AliasMapper.java +++ b/src/main/java/konkuk/thip/user/adapter/out/mapper/AliasMapper.java @@ -10,6 +10,8 @@ public class AliasMapper { public AliasJpaEntity toJpaEntity(Alias alias) { return AliasJpaEntity.builder() .value(alias.getValue()) + .imageUrl(alias.getImageUrl()) + .color(alias.getColor()) .build(); } @@ -17,6 +19,8 @@ public Alias toDomainEntity(AliasJpaEntity aliasJpaEntity) { return Alias.builder() .id(aliasJpaEntity.getAliasId()) .value(aliasJpaEntity.getValue()) + .imageUrl(aliasJpaEntity.getImageUrl()) + .color(aliasJpaEntity.getColor()) .createdAt(aliasJpaEntity.getCreatedAt()) .modifiedAt(aliasJpaEntity.getModifiedAt()) .status(aliasJpaEntity.getStatus()) diff --git a/src/main/java/konkuk/thip/user/domain/Alias.java b/src/main/java/konkuk/thip/user/domain/Alias.java index 242a4c868..76e8c599d 100644 --- a/src/main/java/konkuk/thip/user/domain/Alias.java +++ b/src/main/java/konkuk/thip/user/domain/Alias.java @@ -11,4 +11,8 @@ public class Alias extends BaseDomainEntity { private Long id; private String value; + + private String imageUrl; + + private String color; } From 792b17cd08cb533406650e548d3fb8fe07310478 Mon Sep 17 00:00:00 2001 From: seongjunnoh Date: Thu, 26 Jun 2025 17:35:47 +0900 Subject: [PATCH 03/14] =?UTF-8?q?[refactor]=20:=20=EA=B8=B0=EC=A1=B4=20jpa?= =?UTF-8?q?=20entity=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20(#28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 수정된 User, Alias 도메인의 구성에 맞도록 기존 테스트 코드 수정 --- .../adapter/out/jpa/FeedJpaEntityTest.java | 11 ++++++++--- .../adapter/out/jpa/RecordJpaEntityTest.java | 19 ++++++++++++++----- .../adapter/out/jpa/RoomJpaEntityTest.java | 8 ++++---- .../adapter/out/jpa/VoteJpaEntityTest.java | 18 +++++++++++++----- .../adapter/out/jpa/UserJpaEntityTest.java | 16 ++++++++-------- 5 files changed, 47 insertions(+), 25 deletions(-) rename src/test/java/konkuk/thip/{domain => }/feed/adapter/out/jpa/FeedJpaEntityTest.java (91%) rename src/test/java/konkuk/thip/{domain => }/room/adapter/out/jpa/RecordJpaEntityTest.java (89%) rename src/test/java/konkuk/thip/{domain => }/room/adapter/out/jpa/RoomJpaEntityTest.java (94%) rename src/test/java/konkuk/thip/{domain => }/room/adapter/out/jpa/VoteJpaEntityTest.java (89%) rename src/test/java/konkuk/thip/{domain => }/user/adapter/out/jpa/UserJpaEntityTest.java (81%) diff --git a/src/test/java/konkuk/thip/domain/feed/adapter/out/jpa/FeedJpaEntityTest.java b/src/test/java/konkuk/thip/feed/adapter/out/jpa/FeedJpaEntityTest.java similarity index 91% rename from src/test/java/konkuk/thip/domain/feed/adapter/out/jpa/FeedJpaEntityTest.java rename to src/test/java/konkuk/thip/feed/adapter/out/jpa/FeedJpaEntityTest.java index 52ec6a91e..2b1d18198 100644 --- a/src/test/java/konkuk/thip/domain/feed/adapter/out/jpa/FeedJpaEntityTest.java +++ b/src/test/java/konkuk/thip/feed/adapter/out/jpa/FeedJpaEntityTest.java @@ -1,10 +1,9 @@ -package konkuk.thip.domain.feed.adapter.out.jpa; +package konkuk.thip.feed.adapter.out.jpa; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; import konkuk.thip.book.adapter.out.jpa.BookJpaEntity; import konkuk.thip.book.adapter.out.persistence.BookJpaRepository; -import konkuk.thip.feed.adapter.out.jpa.FeedJpaEntity; import konkuk.thip.feed.adapter.out.persistence.FeedJpaRepository; import konkuk.thip.user.adapter.out.jpa.AliasJpaEntity; import konkuk.thip.user.adapter.out.jpa.UserJpaEntity; @@ -39,10 +38,16 @@ class FeedJpaEntityTest { private FeedJpaRepository feedRepository; private UserJpaEntity createUser() { - AliasJpaEntity alias = AliasJpaEntity.builder().value("익명1").build(); + AliasJpaEntity alias = AliasJpaEntity.builder() + .value("칭호") + .imageUrl("test-image-url") + .color("red") + .build(); + aliasRepository.save(alias); UserJpaEntity user = UserJpaEntity.builder() + .email("test@test.com") .nickname("테스터") .imageUrl("https://test.img") .aliasForUserJpaEntity(alias) diff --git a/src/test/java/konkuk/thip/domain/room/adapter/out/jpa/RecordJpaEntityTest.java b/src/test/java/konkuk/thip/room/adapter/out/jpa/RecordJpaEntityTest.java similarity index 89% rename from src/test/java/konkuk/thip/domain/room/adapter/out/jpa/RecordJpaEntityTest.java rename to src/test/java/konkuk/thip/room/adapter/out/jpa/RecordJpaEntityTest.java index aeca4ea6d..a69653bfe 100644 --- a/src/test/java/konkuk/thip/domain/room/adapter/out/jpa/RecordJpaEntityTest.java +++ b/src/test/java/konkuk/thip/room/adapter/out/jpa/RecordJpaEntityTest.java @@ -1,12 +1,10 @@ -package konkuk.thip.domain.room.adapter.out.jpa; +package konkuk.thip.room.adapter.out.jpa; import jakarta.persistence.EntityManager; import konkuk.thip.book.adapter.out.jpa.BookJpaEntity; import konkuk.thip.book.adapter.out.persistence.BookJpaRepository; import konkuk.thip.record.adapter.out.jpa.RecordJpaEntity; import konkuk.thip.record.adapter.out.persistence.RecordJpaRepository; -import konkuk.thip.room.adapter.out.jpa.CategoryJpaEntity; -import konkuk.thip.room.adapter.out.jpa.RoomJpaEntity; import konkuk.thip.room.adapter.out.persistence.CategoryJpaRepository; import konkuk.thip.room.adapter.out.persistence.RoomJpaRepository; import konkuk.thip.user.adapter.out.jpa.AliasJpaEntity; @@ -50,10 +48,16 @@ class RecordJpaEntityTest { private CategoryJpaRepository categoryRepository; private UserJpaEntity createUser() { - AliasJpaEntity alias = AliasJpaEntity.builder().value("익명1").build(); + AliasJpaEntity alias = AliasJpaEntity.builder() + .value("칭호") + .imageUrl("test-image-url") + .color("red") + .build(); + aliasRepository.save(alias); UserJpaEntity user = UserJpaEntity.builder() + .email("test@test.com") .nickname("테스터") .imageUrl("https://test.img") .aliasForUserJpaEntity(alias) @@ -89,7 +93,12 @@ private RoomJpaEntity createRoom(BookJpaEntity book, CategoryJpaEntity category) } private CategoryJpaEntity createCategory() { - AliasJpaEntity alias = AliasJpaEntity.builder().value("익명1").build(); + AliasJpaEntity alias = AliasJpaEntity.builder() + .value("칭호") + .imageUrl("test-image-url") + .color("red") + .build(); + aliasRepository.save(alias); return categoryRepository.save(CategoryJpaEntity.builder() diff --git a/src/test/java/konkuk/thip/domain/room/adapter/out/jpa/RoomJpaEntityTest.java b/src/test/java/konkuk/thip/room/adapter/out/jpa/RoomJpaEntityTest.java similarity index 94% rename from src/test/java/konkuk/thip/domain/room/adapter/out/jpa/RoomJpaEntityTest.java rename to src/test/java/konkuk/thip/room/adapter/out/jpa/RoomJpaEntityTest.java index 54d9b3157..302a5d683 100644 --- a/src/test/java/konkuk/thip/domain/room/adapter/out/jpa/RoomJpaEntityTest.java +++ b/src/test/java/konkuk/thip/room/adapter/out/jpa/RoomJpaEntityTest.java @@ -1,12 +1,10 @@ -package konkuk.thip.domain.room.adapter.out.jpa; +package konkuk.thip.room.adapter.out.jpa; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; import konkuk.thip.book.adapter.out.jpa.BookJpaEntity; -import konkuk.thip.room.adapter.out.jpa.CategoryJpaEntity; import konkuk.thip.book.adapter.out.persistence.BookJpaRepository; import konkuk.thip.room.adapter.out.persistence.CategoryJpaRepository; -import konkuk.thip.room.adapter.out.jpa.RoomJpaEntity; import konkuk.thip.room.adapter.out.persistence.RoomJpaRepository; import konkuk.thip.user.adapter.out.jpa.AliasJpaEntity; import konkuk.thip.user.adapter.out.persistence.AliasJpaRepository; @@ -54,7 +52,9 @@ void saveAndFindRoom() { bookRepository.save(book); AliasJpaEntity alias = AliasJpaEntity.builder() - .value("칭호1") + .value("칭호") + .imageUrl("test-image-url") + .color("red") .build(); aliasRepository.save(alias); diff --git a/src/test/java/konkuk/thip/domain/room/adapter/out/jpa/VoteJpaEntityTest.java b/src/test/java/konkuk/thip/room/adapter/out/jpa/VoteJpaEntityTest.java similarity index 89% rename from src/test/java/konkuk/thip/domain/room/adapter/out/jpa/VoteJpaEntityTest.java rename to src/test/java/konkuk/thip/room/adapter/out/jpa/VoteJpaEntityTest.java index a00b4b5ea..8c626f0e3 100644 --- a/src/test/java/konkuk/thip/domain/room/adapter/out/jpa/VoteJpaEntityTest.java +++ b/src/test/java/konkuk/thip/room/adapter/out/jpa/VoteJpaEntityTest.java @@ -1,11 +1,9 @@ -package konkuk.thip.domain.room.adapter.out.jpa; +package konkuk.thip.room.adapter.out.jpa; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; import konkuk.thip.book.adapter.out.jpa.BookJpaEntity; import konkuk.thip.book.adapter.out.persistence.BookJpaRepository; -import konkuk.thip.room.adapter.out.jpa.CategoryJpaEntity; -import konkuk.thip.room.adapter.out.jpa.RoomJpaEntity; import konkuk.thip.room.adapter.out.persistence.CategoryJpaRepository; import konkuk.thip.room.adapter.out.persistence.RoomJpaRepository; import konkuk.thip.user.adapter.out.jpa.AliasJpaEntity; @@ -51,10 +49,15 @@ class VoteJpaEntityTest { private CategoryJpaRepository categoryRepository; private UserJpaEntity createUser() { - AliasJpaEntity alias = AliasJpaEntity.builder().value("익명1").build(); + AliasJpaEntity alias = AliasJpaEntity.builder() + .value("칭호") + .imageUrl("test-image-url") + .color("red") + .build(); aliasRepository.save(alias); UserJpaEntity user = UserJpaEntity.builder() + .email("test@test.com") .nickname("테스터") .imageUrl("https://test.img") .aliasForUserJpaEntity(alias) @@ -90,7 +93,12 @@ private RoomJpaEntity createRoom(BookJpaEntity book, CategoryJpaEntity category) } private CategoryJpaEntity createCategory() { - AliasJpaEntity alias = AliasJpaEntity.builder().value("익명1").build(); + AliasJpaEntity alias = AliasJpaEntity.builder() + .value("칭호") + .imageUrl("test-image-url") + .color("red") + .build(); + aliasRepository.save(alias); return categoryRepository.save(CategoryJpaEntity.builder() diff --git a/src/test/java/konkuk/thip/domain/user/adapter/out/jpa/UserJpaEntityTest.java b/src/test/java/konkuk/thip/user/adapter/out/jpa/UserJpaEntityTest.java similarity index 81% rename from src/test/java/konkuk/thip/domain/user/adapter/out/jpa/UserJpaEntityTest.java rename to src/test/java/konkuk/thip/user/adapter/out/jpa/UserJpaEntityTest.java index c6263a504..afbe8ab44 100644 --- a/src/test/java/konkuk/thip/domain/user/adapter/out/jpa/UserJpaEntityTest.java +++ b/src/test/java/konkuk/thip/user/adapter/out/jpa/UserJpaEntityTest.java @@ -1,10 +1,7 @@ -package konkuk.thip.domain.user.adapter.out.jpa; +package konkuk.thip.user.adapter.out.jpa; import jakarta.persistence.EntityManager; import jakarta.persistence.PersistenceContext; -import konkuk.thip.user.adapter.out.jpa.AliasJpaEntity; -import konkuk.thip.user.adapter.out.jpa.UserJpaEntity; -import konkuk.thip.user.adapter.out.jpa.UserRole; import konkuk.thip.user.adapter.out.persistence.AliasJpaRepository; import konkuk.thip.user.adapter.out.persistence.UserJpaRepository; import org.junit.jupiter.api.DisplayName; @@ -34,14 +31,17 @@ void saveAndFindUser() { // given AliasJpaEntity alias = AliasJpaEntity.builder() .value("칭호") + .imageUrl("test-image-url") + .color("red") .build(); aliasJpaRepository.save(alias); UserJpaEntity user = UserJpaEntity.builder() - .nickname("테스트유저") - .imageUrl("http://image.url") - .role(UserRole.USER) + .email("test@test.com") + .nickname("테스터") + .imageUrl("https://test.img") .aliasForUserJpaEntity(alias) + .role(UserRole.USER) .build(); // when @@ -52,7 +52,7 @@ void saveAndFindUser() { UserJpaEntity foundUser = userRepository.findById(user.getUserId()).orElseThrow(); // then - assertThat(foundUser.getNickname()).isEqualTo("테스트유저"); + assertThat(foundUser.getNickname()).isEqualTo("테스터"); assertThat(foundUser.getAliasForUserJpaEntity().getValue()).isEqualTo("칭호"); assertThat(foundUser.getRole()).isEqualTo(UserRole.USER); } From 4d9dfa9f6c8523303e72763886e9d08b039d5560 Mon Sep 17 00:00:00 2001 From: seongjunnoh Date: Thu, 26 Jun 2025 17:38:55 +0900 Subject: [PATCH 04/14] =?UTF-8?q?[feat]=20:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20api=20controller=20=EB=B6=80=EB=B6=84=20=EA=B0=9C?= =?UTF-8?q?=EB=B0=9C=20(#28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../adapter/in/web/UserCommandController.java | 22 +++++++++++++++++++ .../in/web/request/UserSignupRequest.java | 21 ++++++++++++++++++ .../in/web/response/DummyResponse.java | 7 ------ .../in/web/response/UserSignupResponse.java | 11 ++++++++++ 4 files changed, 54 insertions(+), 7 deletions(-) delete mode 100644 src/main/java/konkuk/thip/user/adapter/in/web/response/DummyResponse.java create mode 100644 src/main/java/konkuk/thip/user/adapter/in/web/response/UserSignupResponse.java diff --git a/src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java b/src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java index ef67414d3..d8b600ccc 100644 --- a/src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java +++ b/src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java @@ -1,10 +1,32 @@ package konkuk.thip.user.adapter.in.web; +import konkuk.thip.common.dto.BaseResponse; +import konkuk.thip.user.adapter.in.web.request.UserSignupRequest; +import konkuk.thip.user.adapter.in.web.response.UserSignupResponse; +import konkuk.thip.user.application.port.in.UserSignupUseCase; +import konkuk.thip.user.application.port.in.dto.UserSignupCommand; import lombok.RequiredArgsConstructor; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController @RequiredArgsConstructor public class UserCommandController { + private final UserSignupUseCase userSignupUseCase; + + @PostMapping("/users/signup") + public BaseResponse signup(@Validated @RequestBody UserSignupRequest request) { + UserSignupCommand command = UserSignupCommand.builder() + .aliasId(request.getAliasId()) + .nickname(request.getNickname()) + .email(request.getEmail()) + .build(); + + return BaseResponse.ok(UserSignupResponse.builder() + .userId(userSignupUseCase.signup(command)) + .build()); + } } diff --git a/src/main/java/konkuk/thip/user/adapter/in/web/request/UserSignupRequest.java b/src/main/java/konkuk/thip/user/adapter/in/web/request/UserSignupRequest.java index 1050f1c9e..5ec35b799 100644 --- a/src/main/java/konkuk/thip/user/adapter/in/web/request/UserSignupRequest.java +++ b/src/main/java/konkuk/thip/user/adapter/in/web/request/UserSignupRequest.java @@ -1,7 +1,28 @@ package konkuk.thip.user.adapter.in.web.request; +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.hibernate.validator.constraints.Length; @Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor public class UserSignupRequest { + + @NotNull(message = "aliasId는 필수입니다.") + private Long aliasId; + + @NotBlank(message = "닉네임은 공백일 수 없습니다.") + @Length(max = 10, message = "닉네임은 최대 10자 입니다.") + private String nickname; + + @NotBlank(message = "이메일은 공백일 수 없습니다.") + @Email(message = "이메일 형식이 올바르지 않습니다.") + private String email; } diff --git a/src/main/java/konkuk/thip/user/adapter/in/web/response/DummyResponse.java b/src/main/java/konkuk/thip/user/adapter/in/web/response/DummyResponse.java deleted file mode 100644 index 6b9591bdf..000000000 --- a/src/main/java/konkuk/thip/user/adapter/in/web/response/DummyResponse.java +++ /dev/null @@ -1,7 +0,0 @@ -package konkuk.thip.user.adapter.in.web.response; - -import lombok.Getter; - -@Getter -public class DummyResponse { -} diff --git a/src/main/java/konkuk/thip/user/adapter/in/web/response/UserSignupResponse.java b/src/main/java/konkuk/thip/user/adapter/in/web/response/UserSignupResponse.java new file mode 100644 index 000000000..4f8447a11 --- /dev/null +++ b/src/main/java/konkuk/thip/user/adapter/in/web/response/UserSignupResponse.java @@ -0,0 +1,11 @@ +package konkuk.thip.user.adapter.in.web.response; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class UserSignupResponse { + + private Long userId; +} From f495e3270ea13a59bf362f1ab1136c61bb2ef8bd Mon Sep 17 00:00:00 2001 From: seongjunnoh Date: Thu, 26 Jun 2025 17:39:38 +0900 Subject: [PATCH 05/14] =?UTF-8?q?[feat]=20:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20api=20use=20case=20=EB=B6=80=EB=B6=84=20=EA=B0=9C?= =?UTF-8?q?=EB=B0=9C=20(#28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/port/in/DummyUseCase.java | 5 ---- .../port/in/UserSignupUseCase.java | 8 +++++ .../port/in/dto/UserSignupCommand.java | 15 ++++++++++ .../port/out/AliasCommandPort.java | 8 +++++ .../application/port/out/UserCommandPort.java | 3 ++ .../user/application/service/UserService.java | 11 ------- .../service/UserSignupService.java | 30 +++++++++++++++++++ 7 files changed, 64 insertions(+), 16 deletions(-) delete mode 100644 src/main/java/konkuk/thip/user/application/port/in/DummyUseCase.java create mode 100644 src/main/java/konkuk/thip/user/application/port/in/UserSignupUseCase.java create mode 100644 src/main/java/konkuk/thip/user/application/port/in/dto/UserSignupCommand.java create mode 100644 src/main/java/konkuk/thip/user/application/port/out/AliasCommandPort.java delete mode 100644 src/main/java/konkuk/thip/user/application/service/UserService.java create mode 100644 src/main/java/konkuk/thip/user/application/service/UserSignupService.java diff --git a/src/main/java/konkuk/thip/user/application/port/in/DummyUseCase.java b/src/main/java/konkuk/thip/user/application/port/in/DummyUseCase.java deleted file mode 100644 index 33abe266c..000000000 --- a/src/main/java/konkuk/thip/user/application/port/in/DummyUseCase.java +++ /dev/null @@ -1,5 +0,0 @@ -package konkuk.thip.user.application.port.in; - -public interface DummyUseCase { - -} diff --git a/src/main/java/konkuk/thip/user/application/port/in/UserSignupUseCase.java b/src/main/java/konkuk/thip/user/application/port/in/UserSignupUseCase.java new file mode 100644 index 000000000..a8024b9af --- /dev/null +++ b/src/main/java/konkuk/thip/user/application/port/in/UserSignupUseCase.java @@ -0,0 +1,8 @@ +package konkuk.thip.user.application.port.in; + +import konkuk.thip.user.application.port.in.dto.UserSignupCommand; + +public interface UserSignupUseCase { + + Long signup(UserSignupCommand command); +} diff --git a/src/main/java/konkuk/thip/user/application/port/in/dto/UserSignupCommand.java b/src/main/java/konkuk/thip/user/application/port/in/dto/UserSignupCommand.java new file mode 100644 index 000000000..6e05849f5 --- /dev/null +++ b/src/main/java/konkuk/thip/user/application/port/in/dto/UserSignupCommand.java @@ -0,0 +1,15 @@ +package konkuk.thip.user.application.port.in.dto; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class UserSignupCommand { + + private Long aliasId; + + private String nickname; + + private String email; +} diff --git a/src/main/java/konkuk/thip/user/application/port/out/AliasCommandPort.java b/src/main/java/konkuk/thip/user/application/port/out/AliasCommandPort.java new file mode 100644 index 000000000..be3bbf093 --- /dev/null +++ b/src/main/java/konkuk/thip/user/application/port/out/AliasCommandPort.java @@ -0,0 +1,8 @@ +package konkuk.thip.user.application.port.out; + +import konkuk.thip.user.domain.Alias; + +public interface AliasCommandPort { + + Alias findById(Long aliasId); +} diff --git a/src/main/java/konkuk/thip/user/application/port/out/UserCommandPort.java b/src/main/java/konkuk/thip/user/application/port/out/UserCommandPort.java index f5af3b857..2a24705e7 100644 --- a/src/main/java/konkuk/thip/user/application/port/out/UserCommandPort.java +++ b/src/main/java/konkuk/thip/user/application/port/out/UserCommandPort.java @@ -1,6 +1,9 @@ package konkuk.thip.user.application.port.out; +import konkuk.thip.user.domain.User; public interface UserCommandPort { + Long save(User user); + } diff --git a/src/main/java/konkuk/thip/user/application/service/UserService.java b/src/main/java/konkuk/thip/user/application/service/UserService.java deleted file mode 100644 index 150990b52..000000000 --- a/src/main/java/konkuk/thip/user/application/service/UserService.java +++ /dev/null @@ -1,11 +0,0 @@ -package konkuk.thip.user.application.service; - -import konkuk.thip.user.application.port.in.DummyUseCase; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class UserService implements DummyUseCase { - -} diff --git a/src/main/java/konkuk/thip/user/application/service/UserSignupService.java b/src/main/java/konkuk/thip/user/application/service/UserSignupService.java new file mode 100644 index 000000000..b54d584e6 --- /dev/null +++ b/src/main/java/konkuk/thip/user/application/service/UserSignupService.java @@ -0,0 +1,30 @@ +package konkuk.thip.user.application.service; + +import konkuk.thip.user.application.port.in.UserSignupUseCase; +import konkuk.thip.user.application.port.in.dto.UserSignupCommand; +import konkuk.thip.user.application.port.out.AliasCommandPort; +import konkuk.thip.user.application.port.out.UserCommandPort; +import konkuk.thip.user.domain.Alias; +import konkuk.thip.user.domain.User; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class UserSignupService implements UserSignupUseCase { + + private static final String NORMAL_USER_ROLE = "일반유저"; + + private final UserCommandPort userCommandPort; + private final AliasCommandPort aliasCommandPort; + + @Override + public Long signup(UserSignupCommand command) { + Alias alias = aliasCommandPort.findById(command.getAliasId()); + User user = User.withoutId( + command.getEmail(), command.getNickname(), alias.getImageUrl(), NORMAL_USER_ROLE, alias.getId() + ); + + return userCommandPort.save(user); + } +} From 72d55d1c01afb7b3fcec4c5d4df24e247edca874 Mon Sep 17 00:00:00 2001 From: seongjunnoh Date: Thu, 26 Jun 2025 17:39:54 +0900 Subject: [PATCH 06/14] =?UTF-8?q?[feat]=20:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20api=20=EC=98=81=EC=86=8D=EC=84=B1=20adapter=20?= =?UTF-8?q?=EB=B6=80=EB=B6=84=20=EA=B0=9C=EB=B0=9C=20(#28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../thip/common/exception/code/ErrorCode.java | 6 +++++ .../AliasCommandPersistenceAdapter.java | 27 +++++++++++++++++++ .../UserCommandPersistenceAdapter.java | 18 ++++++++++++- 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 src/main/java/konkuk/thip/user/adapter/out/persistence/AliasCommandPersistenceAdapter.java diff --git a/src/main/java/konkuk/thip/common/exception/code/ErrorCode.java b/src/main/java/konkuk/thip/common/exception/code/ErrorCode.java index 083d64a5b..8c1a481f9 100644 --- a/src/main/java/konkuk/thip/common/exception/code/ErrorCode.java +++ b/src/main/java/konkuk/thip/common/exception/code/ErrorCode.java @@ -17,6 +17,12 @@ public enum ErrorCode implements ResponseCode { API_INVALID_TYPE(HttpStatus.BAD_REQUEST, 40003, "파라미터 타입이 잘못되었습니다."), /* 60000부터 비즈니스 예외 */ + /** + * 60000 : alias error + */ + ALIAS_NOT_FOUND(HttpStatus.NOT_FOUND, 60001, "존재하지 않는 ALIAS 입니다."); + + ; private final HttpStatus httpStatus; diff --git a/src/main/java/konkuk/thip/user/adapter/out/persistence/AliasCommandPersistenceAdapter.java b/src/main/java/konkuk/thip/user/adapter/out/persistence/AliasCommandPersistenceAdapter.java new file mode 100644 index 000000000..154feaf72 --- /dev/null +++ b/src/main/java/konkuk/thip/user/adapter/out/persistence/AliasCommandPersistenceAdapter.java @@ -0,0 +1,27 @@ +package konkuk.thip.user.adapter.out.persistence; + +import konkuk.thip.common.exception.EntityNotFoundException; +import konkuk.thip.user.adapter.out.jpa.AliasJpaEntity; +import konkuk.thip.user.adapter.out.mapper.AliasMapper; +import konkuk.thip.user.application.port.out.AliasCommandPort; +import konkuk.thip.user.domain.Alias; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +import static konkuk.thip.common.exception.code.ErrorCode.ALIAS_NOT_FOUND; + +@Repository +@RequiredArgsConstructor +public class AliasCommandPersistenceAdapter implements AliasCommandPort { + + private final AliasMapper aliasMapper; + private final AliasJpaRepository aliasJpaRepository; + + @Override + public Alias findById(Long aliasId) { + AliasJpaEntity aliasJpaEntity = aliasJpaRepository.findById(aliasId).orElseThrow( + () -> new EntityNotFoundException(ALIAS_NOT_FOUND)); + + return aliasMapper.toDomainEntity(aliasJpaEntity); + } +} diff --git a/src/main/java/konkuk/thip/user/adapter/out/persistence/UserCommandPersistenceAdapter.java b/src/main/java/konkuk/thip/user/adapter/out/persistence/UserCommandPersistenceAdapter.java index f6dac4d5c..7838356c5 100644 --- a/src/main/java/konkuk/thip/user/adapter/out/persistence/UserCommandPersistenceAdapter.java +++ b/src/main/java/konkuk/thip/user/adapter/out/persistence/UserCommandPersistenceAdapter.java @@ -1,15 +1,31 @@ package konkuk.thip.user.adapter.out.persistence; +import konkuk.thip.common.exception.EntityNotFoundException; +import konkuk.thip.user.adapter.out.jpa.AliasJpaEntity; +import konkuk.thip.user.adapter.out.jpa.UserJpaEntity; import konkuk.thip.user.adapter.out.mapper.UserMapper; import konkuk.thip.user.application.port.out.UserCommandPort; +import konkuk.thip.user.domain.User; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; +import static konkuk.thip.common.exception.code.ErrorCode.ALIAS_NOT_FOUND; + @Repository @RequiredArgsConstructor public class UserCommandPersistenceAdapter implements UserCommandPort { - private final UserJpaRepository jpaRepository; + private final UserJpaRepository userJpaRepository; + private final AliasJpaRepository aliasJpaRepository; + private final UserMapper userMapper; + @Override + public Long save(User user) { + AliasJpaEntity aliasJpaEntity = aliasJpaRepository.findById(user.getAliasId()).orElseThrow( + () -> new EntityNotFoundException(ALIAS_NOT_FOUND)); + + UserJpaEntity userJpaEntity = userMapper.toJpaEntity(user, aliasJpaEntity); + return userJpaRepository.save(userJpaEntity).getUserId(); + } } From b1f93722b7ab87e83152071e6162e6cef6b007b4 Mon Sep 17 00:00:00 2001 From: seongjunnoh Date: Thu, 26 Jun 2025 17:40:31 +0900 Subject: [PATCH 07/14] =?UTF-8?q?[test]=20:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20api=20=ED=86=B5=ED=95=A9=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=BD=94=EB=93=9C,=20controller=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EC=9E=91=EC=84=B1=20?= =?UTF-8?q?(#28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../in/web/UserCommandControllerTest.java | 174 ++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 src/test/java/konkuk/thip/user/adapter/in/web/UserCommandControllerTest.java diff --git a/src/test/java/konkuk/thip/user/adapter/in/web/UserCommandControllerTest.java b/src/test/java/konkuk/thip/user/adapter/in/web/UserCommandControllerTest.java new file mode 100644 index 000000000..9dcb308af --- /dev/null +++ b/src/test/java/konkuk/thip/user/adapter/in/web/UserCommandControllerTest.java @@ -0,0 +1,174 @@ +package konkuk.thip.user.adapter.in.web; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import konkuk.thip.user.adapter.in.web.request.UserSignupRequest; +import konkuk.thip.user.adapter.out.jpa.AliasJpaEntity; +import konkuk.thip.user.adapter.out.jpa.UserJpaEntity; +import konkuk.thip.user.adapter.out.persistence.AliasJpaRepository; +import konkuk.thip.user.adapter.out.persistence.UserJpaRepository; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@SpringBootTest +@ActiveProfiles("test") +@AutoConfigureMockMvc +class UserCommandControllerTest { + + @Autowired + private MockMvc mockMvc; + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private AliasJpaRepository aliasJpaRepository; + + @Autowired + private UserJpaRepository userJpaRepository; + + @Test + @DisplayName("[칭호id, 닉네임, 이메일] 정보를 바탕으로 회원가입을 진행한다.") + void signup_success() throws Exception { + //given : alias 생성, 회원가입 request 생성 + AliasJpaEntity aliasJpaEntity = AliasJpaEntity.builder() + .value("칭호") + .color("blue") + .imageUrl("http://image.url") + .build(); + aliasJpaRepository.save(aliasJpaEntity); + + UserSignupRequest request = new UserSignupRequest( + aliasJpaEntity.getAliasId(), + "테스트 유저", + "test@test.com" + ); + + //when : 회원가입 api 호출 + ResultActions result = mockMvc.perform(post("/users/signup") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))); + + //then + result.andExpect(status().isOk()) + .andExpect(jsonPath("$.data.userId").exists()); + + String json = result.andReturn().getResponse().getContentAsString(); + JsonNode jsonNode = objectMapper.readTree(json); + Long userId = jsonNode.path("data").path("userId").asLong(); + + UserJpaEntity userJpaEntity = userJpaRepository.findById(userId).orElse(null); + + assertThat(userJpaEntity.getAliasForUserJpaEntity().getAliasId()).isEqualTo(request.getAliasId()); + assertThat(userJpaEntity.getNickname()).isEqualTo(request.getNickname()); + assertThat(userJpaEntity.getEmail()).isEqualTo(request.getEmail()); + } + + @Test + @DisplayName("[칭호id]값이 null일 경우, 400 error가 발생한다.") + void signup_whenAliasIdNull_thenBadRequest() throws Exception { + //given: aliasId null + UserSignupRequest request = new UserSignupRequest( + null, + "테스트유저", + "test@test.com" + ); + + //when //then + mockMvc.perform(post("/users/signup") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.code").value("40002")) + .andExpect(jsonPath("$.message", containsString("aliasId는 필수입니다."))); + } + + @Test + @DisplayName("[닉네임]값이 공백일 경우, 400 error가 발생한다.") + void signup_whenNicknameBlank_thenBadRequest() throws Exception { + //given: nickname blank + UserSignupRequest request = new UserSignupRequest( + 1L, + "", + "test@test.com" + ); + + //when //then + mockMvc.perform(post("/users/signup") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.code").value("40002")) + .andExpect(jsonPath("$.message", containsString("닉네임은 공백일 수 없습니다."))); + } + + @Test + @DisplayName("[닉네임]값이 11자 이상일 경우, 400 error가 발생한다.") + void signup_whenNicknameTooLong_thenBadRequest() throws Exception { + //given: nickname blank + UserSignupRequest request = new UserSignupRequest( + 1L, + "11자_닉네임_입니다", + "test@test.com" + ); + + //when //then + mockMvc.perform(post("/users/signup") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.code").value("40002")) + .andExpect(jsonPath("$.message", containsString("닉네임은 최대 10자 입니다."))); + } + + @Test + @DisplayName("[이메일]값이 공백일 경우, 400 error가 발생한다.") + void signup_whenEmailBlank_thenBadRequest() throws Exception { + //given + UserSignupRequest request = new UserSignupRequest( + 1L, + "테스트유저", + "" + ); + + //when //then + mockMvc.perform(post("/users/signup") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.code").value("40002")) + .andExpect(jsonPath("$.message", containsString("이메일은 공백일 수 없습니다."))); + } + + @Test + @DisplayName("[이메일]값이 유효한 이메일 형식이 아닐 경우, 400 error가 발생한다.") + void signup_whenEmailInvalidFormat_thenBadRequest() throws Exception { + //given + UserSignupRequest request = new UserSignupRequest( + 1L, + "테스트유저", + "invalid-email-format" + ); + + //when //then + mockMvc.perform(post("/users/signup") + .contentType(MediaType.APPLICATION_JSON) + .content(objectMapper.writeValueAsString(request))) + .andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.code").value("40002")) + .andExpect(jsonPath("$.message", containsString("이메일 형식이 올바르지 않습니다."))); + } +} From 2d325bf8517c41ee905f3fd504811cbdd4005586 Mon Sep 17 00:00:00 2001 From: seongjunnoh Date: Thu, 26 Jun 2025 20:44:20 +0900 Subject: [PATCH 08/14] =?UTF-8?q?[refactor]=20:=20email=20DB=20length=20?= =?UTF-8?q?=EA=B0=92=20=EC=88=98=EC=A0=95=20(#28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/konkuk/thip/user/adapter/out/jpa/UserJpaEntity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/konkuk/thip/user/adapter/out/jpa/UserJpaEntity.java b/src/main/java/konkuk/thip/user/adapter/out/jpa/UserJpaEntity.java index 787454e8c..6258411ae 100644 --- a/src/main/java/konkuk/thip/user/adapter/out/jpa/UserJpaEntity.java +++ b/src/main/java/konkuk/thip/user/adapter/out/jpa/UserJpaEntity.java @@ -18,7 +18,7 @@ public class UserJpaEntity extends BaseJpaEntity { @Column(name = "user_id") private Long userId; - @Column(name = "email", length = 30, nullable = false) + @Column(name = "email", length = 100, nullable = false) private String email; @Column(length = 60, nullable = false) From a61d2a4b3362a0203088cad30e82619ad2432e11 Mon Sep 17 00:00:00 2001 From: seongjunnoh Date: Thu, 26 Jun 2025 20:45:18 +0900 Subject: [PATCH 09/14] =?UTF-8?q?[refactor]=20:=20transactional=20?= =?UTF-8?q?=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20(#28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../konkuk/thip/user/application/service/UserSignupService.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/konkuk/thip/user/application/service/UserSignupService.java b/src/main/java/konkuk/thip/user/application/service/UserSignupService.java index b54d584e6..d283bdf92 100644 --- a/src/main/java/konkuk/thip/user/application/service/UserSignupService.java +++ b/src/main/java/konkuk/thip/user/application/service/UserSignupService.java @@ -8,6 +8,7 @@ import konkuk.thip.user.domain.User; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; @Service @RequiredArgsConstructor @@ -19,6 +20,7 @@ public class UserSignupService implements UserSignupUseCase { private final AliasCommandPort aliasCommandPort; @Override + @Transactional public Long signup(UserSignupCommand command) { Alias alias = aliasCommandPort.findById(command.getAliasId()); User user = User.withoutId( From fc5d27fff1957909654848ae712f39066fc027ef Mon Sep 17 00:00:00 2001 From: seongjunnoh Date: Thu, 26 Jun 2025 20:51:29 +0900 Subject: [PATCH 10/14] =?UTF-8?q?[refactor]=20:=20request=20dto=EA=B0=80?= =?UTF-8?q?=20command=EB=A1=9C=EC=9D=98=20=EB=B3=80=ED=99=98=EC=B1=85?= =?UTF-8?q?=EC=9E=84=EC=9D=84=20=EA=B0=96=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20(#28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../thip/user/adapter/in/web/UserCommandController.java | 8 +------- .../user/adapter/in/web/request/UserSignupRequest.java | 9 +++++++++ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java b/src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java index d8b600ccc..96817bbfa 100644 --- a/src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java +++ b/src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java @@ -19,14 +19,8 @@ public class UserCommandController { @PostMapping("/users/signup") public BaseResponse signup(@Validated @RequestBody UserSignupRequest request) { - UserSignupCommand command = UserSignupCommand.builder() - .aliasId(request.getAliasId()) - .nickname(request.getNickname()) - .email(request.getEmail()) - .build(); - return BaseResponse.ok(UserSignupResponse.builder() - .userId(userSignupUseCase.signup(command)) + .userId(userSignupUseCase.signup(request.toCommand())) .build()); } } diff --git a/src/main/java/konkuk/thip/user/adapter/in/web/request/UserSignupRequest.java b/src/main/java/konkuk/thip/user/adapter/in/web/request/UserSignupRequest.java index 5ec35b799..50ad94373 100644 --- a/src/main/java/konkuk/thip/user/adapter/in/web/request/UserSignupRequest.java +++ b/src/main/java/konkuk/thip/user/adapter/in/web/request/UserSignupRequest.java @@ -3,6 +3,7 @@ import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; +import konkuk.thip.user.application.port.in.dto.UserSignupCommand; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; @@ -25,4 +26,12 @@ public class UserSignupRequest { @NotBlank(message = "이메일은 공백일 수 없습니다.") @Email(message = "이메일 형식이 올바르지 않습니다.") private String email; + + public UserSignupCommand toCommand() { + return UserSignupCommand.builder() + .aliasId(aliasId) + .nickname(nickname) + .email(email) + .build(); + } } From 4c864083404c155fff5ef2c608ab23ae34270fc7 Mon Sep 17 00:00:00 2001 From: seongjunnoh Date: Thu, 26 Jun 2025 20:55:04 +0900 Subject: [PATCH 11/14] =?UTF-8?q?[refactor]=20:=20response=20dto=20?= =?UTF-8?q?=EA=B5=AC=EC=84=B1=EC=8B=9C=20=EC=A0=95=EC=A0=81=20=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=20=EB=A9=94=EC=84=9C=EB=93=9C=20=ED=99=9C?= =?UTF-8?q?=EC=9A=A9=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95=20(#2?= =?UTF-8?q?8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../thip/user/adapter/in/web/UserCommandController.java | 6 +++--- .../user/adapter/in/web/response/UserSignupResponse.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java b/src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java index 96817bbfa..e799f0509 100644 --- a/src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java +++ b/src/main/java/konkuk/thip/user/adapter/in/web/UserCommandController.java @@ -19,8 +19,8 @@ public class UserCommandController { @PostMapping("/users/signup") public BaseResponse signup(@Validated @RequestBody UserSignupRequest request) { - return BaseResponse.ok(UserSignupResponse.builder() - .userId(userSignupUseCase.signup(request.toCommand())) - .build()); + return BaseResponse.ok(UserSignupResponse.of( + userSignupUseCase.signup(request.toCommand())) + ); } } diff --git a/src/main/java/konkuk/thip/user/adapter/in/web/response/UserSignupResponse.java b/src/main/java/konkuk/thip/user/adapter/in/web/response/UserSignupResponse.java index 4f8447a11..410e0053a 100644 --- a/src/main/java/konkuk/thip/user/adapter/in/web/response/UserSignupResponse.java +++ b/src/main/java/konkuk/thip/user/adapter/in/web/response/UserSignupResponse.java @@ -1,10 +1,10 @@ package konkuk.thip.user.adapter.in.web.response; -import lombok.Builder; +import lombok.AllArgsConstructor; import lombok.Getter; @Getter -@Builder +@AllArgsConstructor(staticName = "of") public class UserSignupResponse { private Long userId; From 41a9346bc490d95e3d67fb7eb524166846745880 Mon Sep 17 00:00:00 2001 From: seongjunnoh Date: Thu, 26 Jun 2025 20:58:30 +0900 Subject: [PATCH 12/14] =?UTF-8?q?[refactor]=20:=20=EC=98=A4=ED=83=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EB=B0=8F=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95=20(#28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 하드코딩 값 대신 ErrorCode.code 로 검증하도록 테스트 코드 수정 --- .../konkuk/thip/common/exception/code/ErrorCode.java | 2 +- .../user/adapter/in/web/UserCommandControllerTest.java | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/konkuk/thip/common/exception/code/ErrorCode.java b/src/main/java/konkuk/thip/common/exception/code/ErrorCode.java index 8c1a481f9..38fa09194 100644 --- a/src/main/java/konkuk/thip/common/exception/code/ErrorCode.java +++ b/src/main/java/konkuk/thip/common/exception/code/ErrorCode.java @@ -11,7 +11,7 @@ public enum ErrorCode implements ResponseCode { API_METHOD_NOT_ALLOWED(HttpStatus.METHOD_NOT_ALLOWED, 40500, "허용되지 않는 HTTP 메소드입니다."), API_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR, 50000, "서버 내부 오류입니다."), - API_BAD_REQUEST(HttpStatus.BAD_REQUEST, 40002, "잘못된 요청입니다."), + API_BAD_REQUEST(HttpStatus.BAD_REQUEST, 40000, "잘못된 요청입니다."), API_MISSING_PARAM(HttpStatus.BAD_REQUEST, 40001, "필수 파라미터가 없습니다."), API_INVALID_PARAM(HttpStatus.BAD_REQUEST, 40002, "파라미터 값 중 유효하지 않은 값이 있습니다."), API_INVALID_TYPE(HttpStatus.BAD_REQUEST, 40003, "파라미터 타입이 잘못되었습니다."), diff --git a/src/test/java/konkuk/thip/user/adapter/in/web/UserCommandControllerTest.java b/src/test/java/konkuk/thip/user/adapter/in/web/UserCommandControllerTest.java index 9dcb308af..2da64ce9a 100644 --- a/src/test/java/konkuk/thip/user/adapter/in/web/UserCommandControllerTest.java +++ b/src/test/java/konkuk/thip/user/adapter/in/web/UserCommandControllerTest.java @@ -17,6 +17,7 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultActions; +import static konkuk.thip.common.exception.code.ErrorCode.API_INVALID_PARAM; import static org.assertj.core.api.Assertions.assertThat; import static org.hamcrest.Matchers.containsString; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; @@ -92,7 +93,7 @@ void signup_whenAliasIdNull_thenBadRequest() throws Exception { .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.code").value("40002")) + .andExpect(jsonPath("$.code").value(API_INVALID_PARAM.getCode())) .andExpect(jsonPath("$.message", containsString("aliasId는 필수입니다."))); } @@ -111,7 +112,7 @@ void signup_whenNicknameBlank_thenBadRequest() throws Exception { .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.code").value("40002")) + .andExpect(jsonPath("$.code").value(API_INVALID_PARAM.getCode())) .andExpect(jsonPath("$.message", containsString("닉네임은 공백일 수 없습니다."))); } @@ -130,7 +131,7 @@ void signup_whenNicknameTooLong_thenBadRequest() throws Exception { .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.code").value("40002")) + .andExpect(jsonPath("$.code").value(API_INVALID_PARAM.getCode())) .andExpect(jsonPath("$.message", containsString("닉네임은 최대 10자 입니다."))); } @@ -149,7 +150,7 @@ void signup_whenEmailBlank_thenBadRequest() throws Exception { .contentType(MediaType.APPLICATION_JSON) .content(objectMapper.writeValueAsString(request))) .andExpect(status().isBadRequest()) - .andExpect(jsonPath("$.code").value("40002")) + .andExpect(jsonPath("$.code").value(API_INVALID_PARAM.getCode())) .andExpect(jsonPath("$.message", containsString("이메일은 공백일 수 없습니다."))); } From bad9a59d25e42191abdc71b019d991033ceaa9a2 Mon Sep 17 00:00:00 2001 From: seongjunnoh Date: Thu, 26 Jun 2025 21:36:35 +0900 Subject: [PATCH 13/14] =?UTF-8?q?[refactor]=20:=20setter=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20(#28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../thip/user/adapter/in/web/request/UserSignupRequest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/konkuk/thip/user/adapter/in/web/request/UserSignupRequest.java b/src/main/java/konkuk/thip/user/adapter/in/web/request/UserSignupRequest.java index 50ad94373..849843d2b 100644 --- a/src/main/java/konkuk/thip/user/adapter/in/web/request/UserSignupRequest.java +++ b/src/main/java/konkuk/thip/user/adapter/in/web/request/UserSignupRequest.java @@ -7,11 +7,9 @@ import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.Setter; import org.hibernate.validator.constraints.Length; @Getter -@Setter @NoArgsConstructor @AllArgsConstructor public class UserSignupRequest { From 05ac77ff69df6858741cafc73fe1dcbbb8efa20f Mon Sep 17 00:00:00 2001 From: seongjunnoh Date: Thu, 26 Jun 2025 22:27:07 +0900 Subject: [PATCH 14/14] =?UTF-8?q?[refactor]=20:=20dto=20->=20record=20?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20(#28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../in/web/request/UserSignupRequest.java | 27 +++++++------------ .../in/web/response/UserSignupResponse.java | 14 ++++------ .../port/in/dto/UserSignupCommand.java | 15 ++++------- .../service/UserSignupService.java | 9 ++++--- .../in/web/UserCommandControllerTest.java | 6 ++--- 5 files changed, 28 insertions(+), 43 deletions(-) diff --git a/src/main/java/konkuk/thip/user/adapter/in/web/request/UserSignupRequest.java b/src/main/java/konkuk/thip/user/adapter/in/web/request/UserSignupRequest.java index 849843d2b..96c9725a3 100644 --- a/src/main/java/konkuk/thip/user/adapter/in/web/request/UserSignupRequest.java +++ b/src/main/java/konkuk/thip/user/adapter/in/web/request/UserSignupRequest.java @@ -4,27 +4,20 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; import konkuk.thip.user.application.port.in.dto.UserSignupCommand; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; import org.hibernate.validator.constraints.Length; -@Getter -@NoArgsConstructor -@AllArgsConstructor -public class UserSignupRequest { +public record UserSignupRequest( + @NotNull(message = "aliasId는 필수입니다.") + Long aliasId, - @NotNull(message = "aliasId는 필수입니다.") - private Long aliasId; - - @NotBlank(message = "닉네임은 공백일 수 없습니다.") - @Length(max = 10, message = "닉네임은 최대 10자 입니다.") - private String nickname; - - @NotBlank(message = "이메일은 공백일 수 없습니다.") - @Email(message = "이메일 형식이 올바르지 않습니다.") - private String email; + @NotBlank(message = "닉네임은 공백일 수 없습니다.") + @Length(max = 10, message = "닉네임은 최대 10자 입니다.") + String nickname, + @NotBlank(message = "이메일은 공백일 수 없습니다.") + @Email(message = "이메일 형식이 올바르지 않습니다.") + String email +) { public UserSignupCommand toCommand() { return UserSignupCommand.builder() .aliasId(aliasId) diff --git a/src/main/java/konkuk/thip/user/adapter/in/web/response/UserSignupResponse.java b/src/main/java/konkuk/thip/user/adapter/in/web/response/UserSignupResponse.java index 410e0053a..f5a490e6e 100644 --- a/src/main/java/konkuk/thip/user/adapter/in/web/response/UserSignupResponse.java +++ b/src/main/java/konkuk/thip/user/adapter/in/web/response/UserSignupResponse.java @@ -1,11 +1,7 @@ package konkuk.thip.user.adapter.in.web.response; -import lombok.AllArgsConstructor; -import lombok.Getter; - -@Getter -@AllArgsConstructor(staticName = "of") -public class UserSignupResponse { - - private Long userId; -} +public record UserSignupResponse(Long userId) { + public static UserSignupResponse of(Long userId) { + return new UserSignupResponse(userId); + } +} \ No newline at end of file diff --git a/src/main/java/konkuk/thip/user/application/port/in/dto/UserSignupCommand.java b/src/main/java/konkuk/thip/user/application/port/in/dto/UserSignupCommand.java index 6e05849f5..38aef5a36 100644 --- a/src/main/java/konkuk/thip/user/application/port/in/dto/UserSignupCommand.java +++ b/src/main/java/konkuk/thip/user/application/port/in/dto/UserSignupCommand.java @@ -1,15 +1,10 @@ package konkuk.thip.user.application.port.in.dto; import lombok.Builder; -import lombok.Getter; -@Getter @Builder -public class UserSignupCommand { - - private Long aliasId; - - private String nickname; - - private String email; -} +public record UserSignupCommand( + Long aliasId, + String nickname, + String email +) {} diff --git a/src/main/java/konkuk/thip/user/application/service/UserSignupService.java b/src/main/java/konkuk/thip/user/application/service/UserSignupService.java index d283bdf92..b32c2028e 100644 --- a/src/main/java/konkuk/thip/user/application/service/UserSignupService.java +++ b/src/main/java/konkuk/thip/user/application/service/UserSignupService.java @@ -10,21 +10,22 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import static konkuk.thip.user.adapter.out.jpa.UserRole.USER; + + @Service @RequiredArgsConstructor public class UserSignupService implements UserSignupUseCase { - private static final String NORMAL_USER_ROLE = "일반유저"; - private final UserCommandPort userCommandPort; private final AliasCommandPort aliasCommandPort; @Override @Transactional public Long signup(UserSignupCommand command) { - Alias alias = aliasCommandPort.findById(command.getAliasId()); + Alias alias = aliasCommandPort.findById(command.aliasId()); User user = User.withoutId( - command.getEmail(), command.getNickname(), alias.getImageUrl(), NORMAL_USER_ROLE, alias.getId() + command.email(), command.nickname(), alias.getImageUrl(), USER.getType(), alias.getId() ); return userCommandPort.save(user); diff --git a/src/test/java/konkuk/thip/user/adapter/in/web/UserCommandControllerTest.java b/src/test/java/konkuk/thip/user/adapter/in/web/UserCommandControllerTest.java index 2da64ce9a..fe6ef27c2 100644 --- a/src/test/java/konkuk/thip/user/adapter/in/web/UserCommandControllerTest.java +++ b/src/test/java/konkuk/thip/user/adapter/in/web/UserCommandControllerTest.java @@ -73,9 +73,9 @@ void signup_success() throws Exception { UserJpaEntity userJpaEntity = userJpaRepository.findById(userId).orElse(null); - assertThat(userJpaEntity.getAliasForUserJpaEntity().getAliasId()).isEqualTo(request.getAliasId()); - assertThat(userJpaEntity.getNickname()).isEqualTo(request.getNickname()); - assertThat(userJpaEntity.getEmail()).isEqualTo(request.getEmail()); + assertThat(userJpaEntity.getAliasForUserJpaEntity().getAliasId()).isEqualTo(request.aliasId()); + assertThat(userJpaEntity.getNickname()).isEqualTo(request.nickname()); + assertThat(userJpaEntity.getEmail()).isEqualTo(request.email()); } @Test