From 6605e11129c063271f48e9a5cf5099bb891e3e8a Mon Sep 17 00:00:00 2001 From: junhokim Date: Sun, 16 Feb 2025 18:53:24 +0900 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20Crew=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 1 + .../crew/application/in/CrewService.java | 9 ++- .../in/request/CrewCreateRequest.java | 11 +++- .../in/response/CrewCreateResponse.java | 16 ++++-- .../com/retrip/crew/domain/entity/Crew.java | 40 +++++++++---- .../retrip/crew/domain/entity/CrewMember.java | 44 ++++++++++++++ .../retrip/crew/domain/entity/FreeBoard.java | 31 ++++++++++ .../crew/domain/entity/NotificationBoard.java | 30 ++++++++++ .../com/retrip/crew/domain/entity/Role.java | 8 +++ .../domain/entity/SelfIntroduceBoard.java | 31 ++++++++++ .../retrip/crew/domain/vo/CrewContent.java | 38 +++++++++++++ .../crew/domain/vo/FreeBoardContent.java | 38 +++++++++++++ .../domain/vo/NotificationBoardContent.java | 38 +++++++++++++ .../domain/vo/SelfIntroduceBoardContent.java | 38 +++++++++++++ .../out/gateway/rest/member/MemberClient.java | 14 +++++ .../gateway/rest/member/MockMemberClient.java | 20 +++++++ .../rest/member/response/MemberResponse.java | 16 ++++++ src/main/resources/application.yml | 4 ++ .../com/retrip/crew/CrewApplicationTests.java | 9 ++- .../crew/application/in/CrewServiceTest.java | 57 +++++++++++++++++++ .../retrip/crew/domain/entity/CrewTest.java | 15 ++++- .../crew/domain/vo/CrewContentTest.java | 31 ++++++++++ 22 files changed, 516 insertions(+), 23 deletions(-) create mode 100644 src/main/java/com/retrip/crew/domain/entity/CrewMember.java create mode 100644 src/main/java/com/retrip/crew/domain/entity/FreeBoard.java create mode 100644 src/main/java/com/retrip/crew/domain/entity/NotificationBoard.java create mode 100644 src/main/java/com/retrip/crew/domain/entity/Role.java create mode 100644 src/main/java/com/retrip/crew/domain/entity/SelfIntroduceBoard.java create mode 100644 src/main/java/com/retrip/crew/domain/vo/CrewContent.java create mode 100644 src/main/java/com/retrip/crew/domain/vo/FreeBoardContent.java create mode 100644 src/main/java/com/retrip/crew/domain/vo/NotificationBoardContent.java create mode 100644 src/main/java/com/retrip/crew/domain/vo/SelfIntroduceBoardContent.java create mode 100644 src/main/java/com/retrip/crew/infra/adapter/out/gateway/rest/member/MemberClient.java create mode 100644 src/main/java/com/retrip/crew/infra/adapter/out/gateway/rest/member/MockMemberClient.java create mode 100644 src/main/java/com/retrip/crew/infra/adapter/out/gateway/rest/member/response/MemberResponse.java create mode 100644 src/test/java/com/retrip/crew/application/in/CrewServiceTest.java create mode 100644 src/test/java/com/retrip/crew/domain/vo/CrewContentTest.java diff --git a/build.gradle b/build.gradle index ea4402d..80325ee 100644 --- a/build.gradle +++ b/build.gradle @@ -27,6 +27,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-webflux' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' diff --git a/src/main/java/com/retrip/crew/application/in/CrewService.java b/src/main/java/com/retrip/crew/application/in/CrewService.java index 4cddfcf..8e5e2c0 100644 --- a/src/main/java/com/retrip/crew/application/in/CrewService.java +++ b/src/main/java/com/retrip/crew/application/in/CrewService.java @@ -5,6 +5,8 @@ import com.retrip.crew.application.in.usecase.CreateCrewUseCase; import com.retrip.crew.application.out.repository.CrewRepository; import com.retrip.crew.domain.entity.Crew; +import com.retrip.crew.infra.adapter.out.gateway.rest.member.MemberClient; +import com.retrip.crew.infra.adapter.out.gateway.rest.member.response.MemberResponse; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -14,9 +16,14 @@ @RequiredArgsConstructor public class CrewService implements CreateCrewUseCase { private final CrewRepository crewRepository; + private final MemberClient memberClient; + @Override public CrewCreateResponse createCrew(CrewCreateRequest request) { - Crew crew = crewRepository.save(request.to()); + MemberResponse leader = memberClient.getMember(request.leader()); + Crew entity = request.to(leader.id()); + Crew crew = crewRepository.save(entity); + return CrewCreateResponse.of(crew); } } diff --git a/src/main/java/com/retrip/crew/application/in/request/CrewCreateRequest.java b/src/main/java/com/retrip/crew/application/in/request/CrewCreateRequest.java index d840e89..4121836 100644 --- a/src/main/java/com/retrip/crew/application/in/request/CrewCreateRequest.java +++ b/src/main/java/com/retrip/crew/application/in/request/CrewCreateRequest.java @@ -3,12 +3,17 @@ import com.retrip.crew.domain.entity.Crew; import jakarta.validation.constraints.Size; +import java.util.UUID; + public record CrewCreateRequest( + UUID leader, @Size(min = 1, max = 30) - String title + String name, + @Size(min = 1, max = 500) + String description ){ - public Crew to() { - return Crew.create(this.title); + public Crew to(UUID leader) { + return Crew.create(this.name, this.description, leader); } } diff --git a/src/main/java/com/retrip/crew/application/in/response/CrewCreateResponse.java b/src/main/java/com/retrip/crew/application/in/response/CrewCreateResponse.java index b062770..5ea6adc 100644 --- a/src/main/java/com/retrip/crew/application/in/response/CrewCreateResponse.java +++ b/src/main/java/com/retrip/crew/application/in/response/CrewCreateResponse.java @@ -4,12 +4,18 @@ import java.util.UUID; -public record CrewCreateResponse ( - UUID id -){ - public static CrewCreateResponse of(Crew crew){ +public record CrewCreateResponse( + UUID id, + String name, + String description, + UUID leaderId +) { + public static CrewCreateResponse of(Crew crew) { return new CrewCreateResponse( - crew.getId() + crew.getId(), + crew.getCrewContent().getName(), + crew.getCrewContent().getDescription(), + crew.getLeader().getFirst().getId() ); } } diff --git a/src/main/java/com/retrip/crew/domain/entity/Crew.java b/src/main/java/com/retrip/crew/domain/entity/Crew.java index feb000c..f42f8ba 100644 --- a/src/main/java/com/retrip/crew/domain/entity/Crew.java +++ b/src/main/java/com/retrip/crew/domain/entity/Crew.java @@ -1,13 +1,13 @@ package com.retrip.crew.domain.entity; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import jakarta.persistence.Version; +import com.retrip.crew.domain.vo.CrewContent; +import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; @Entity @@ -18,18 +18,38 @@ public class Crew extends BaseEntity { @Column(columnDefinition = "varbinary(16)") private UUID id; - @Column - private String title; + @Embedded + private CrewContent crewContent; + + @OneToMany(mappedBy = "crew", cascade = CascadeType.ALL, orphanRemoval = true) + private List leader = new ArrayList<>(); + + @OneToMany(mappedBy = "crew", cascade = CascadeType.ALL, orphanRemoval = true) + private List members = new ArrayList<>(); + + @OneToMany(mappedBy = "crew", cascade = CascadeType.ALL, orphanRemoval = true) + private List freeBoards = new ArrayList<>(); + + @OneToMany(mappedBy = "crew", cascade = CascadeType.ALL, orphanRemoval = true) + private List notificationBoards = new ArrayList<>(); + + @OneToMany(mappedBy = "crew", cascade = CascadeType.ALL, orphanRemoval = true) + private List selfIntroduceBoards = new ArrayList<>(); @Version private long version; - private Crew(String title) { + private Crew(String name, String description, UUID leader) { this.id = UUID.randomUUID(); - this.title = title; + this.crewContent = new CrewContent(name, description); + this.leader = CrewMember.createLeader(this, leader, Role.LEADER); + this.members = new ArrayList<>(); + this.freeBoards = new ArrayList<>(); + this.notificationBoards = new ArrayList<>(); + this.selfIntroduceBoards = new ArrayList<>(); } - public static Crew create(String title) { - return new Crew(title); + public static Crew create(String name, String description, UUID leader) { + return new Crew(name, description, leader); } } diff --git a/src/main/java/com/retrip/crew/domain/entity/CrewMember.java b/src/main/java/com/retrip/crew/domain/entity/CrewMember.java new file mode 100644 index 0000000..8572957 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/entity/CrewMember.java @@ -0,0 +1,44 @@ +package com.retrip.crew.domain.entity; + +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; +import java.util.UUID; + +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED, force = true) +@Getter +public class CrewMember extends BaseEntity { + @Id + @Column(columnDefinition = "varbinary(16)") + private UUID id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn( + name = "crew_id", + nullable = false, + columnDefinition = "varbinary(16)", + foreignKey = @ForeignKey(name = "fk_crew_member_to_crew") + ) + private Crew crew; + + @Enumerated + private Role role; + + @Column(nullable = false) + private UUID memberId; + + private CrewMember(Crew crew, UUID memberId, Role role) { + this.id = UUID.randomUUID(); + this.crew = crew; + this.memberId = memberId; + this.role = Role.valueOf(role.name()); + } + + public static List createLeader(Crew crew, UUID memberId, Role role) { + return List.of(new CrewMember(crew, memberId, role)); + } +} diff --git a/src/main/java/com/retrip/crew/domain/entity/FreeBoard.java b/src/main/java/com/retrip/crew/domain/entity/FreeBoard.java new file mode 100644 index 0000000..9771531 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/entity/FreeBoard.java @@ -0,0 +1,31 @@ +package com.retrip.crew.domain.entity; + +import com.retrip.crew.domain.vo.FreeBoardContent; +import com.retrip.crew.domain.vo.NotificationBoardContent; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.UUID; + +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +public class FreeBoard extends BaseEntity { + @Id + @Column(columnDefinition = "varbinary(16)") + private UUID id; + + @Embedded + private FreeBoardContent content; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn( + name = "crew_id", + nullable = false, + columnDefinition = "varbinary(16)", + foreignKey = @ForeignKey(name = "fk_free_board_to_crew") + ) + private Crew crew; +} diff --git a/src/main/java/com/retrip/crew/domain/entity/NotificationBoard.java b/src/main/java/com/retrip/crew/domain/entity/NotificationBoard.java new file mode 100644 index 0000000..c7f6d72 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/entity/NotificationBoard.java @@ -0,0 +1,30 @@ +package com.retrip.crew.domain.entity; + +import com.retrip.crew.domain.vo.NotificationBoardContent; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.UUID; + +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +public class NotificationBoard extends BaseEntity { + @Id + @Column(columnDefinition = "varbinary(16)") + private UUID id; + + @Embedded + private NotificationBoardContent content; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn( + name = "crew_id", + nullable = false, + columnDefinition = "varbinary(16)", + foreignKey = @ForeignKey(name = "fk_notification_board_to_crew") + ) + private Crew crew; +} diff --git a/src/main/java/com/retrip/crew/domain/entity/Role.java b/src/main/java/com/retrip/crew/domain/entity/Role.java new file mode 100644 index 0000000..cabcfd3 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/entity/Role.java @@ -0,0 +1,8 @@ +package com.retrip.crew.domain.entity; + +import jakarta.persistence.Embedded; + +public enum Role { + LEADER, GENERAL +} + diff --git a/src/main/java/com/retrip/crew/domain/entity/SelfIntroduceBoard.java b/src/main/java/com/retrip/crew/domain/entity/SelfIntroduceBoard.java new file mode 100644 index 0000000..2c100d8 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/entity/SelfIntroduceBoard.java @@ -0,0 +1,31 @@ +package com.retrip.crew.domain.entity; + +import com.retrip.crew.domain.vo.NotificationBoardContent; +import com.retrip.crew.domain.vo.SelfIntroduceBoardContent; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.UUID; + +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Getter +public class SelfIntroduceBoard extends BaseEntity { + @Id + @Column(columnDefinition = "varbinary(16)") + private UUID id; + + @Embedded + private SelfIntroduceBoardContent content; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn( + name = "crew_id", + nullable = false, + columnDefinition = "varbinary(16)", + foreignKey = @ForeignKey(name = "fk_self_introduce_board_to_crew") + ) + private Crew crew; +} diff --git a/src/main/java/com/retrip/crew/domain/vo/CrewContent.java b/src/main/java/com/retrip/crew/domain/vo/CrewContent.java new file mode 100644 index 0000000..ff68731 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/vo/CrewContent.java @@ -0,0 +1,38 @@ +package com.retrip.crew.domain.vo; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Embeddable +@EqualsAndHashCode +@NoArgsConstructor(access = AccessLevel.PROTECTED, force = true) +public class CrewContent { + private static final int NAME_LENGTH_LIMIT = 30; + private static final int DESCRIPTION_LENGTH_LIMIT = 100; + + @Column(name = "name", nullable = false, length = NAME_LENGTH_LIMIT) + private final String name; + + @Column(name = "description", nullable = false, length = DESCRIPTION_LENGTH_LIMIT) + private final String description; + + public CrewContent(String name, String description) { + validate(name, description); + this.name = name; + this.description = description; + } + + private void validate(String name, String description) { + if (name.length() > NAME_LENGTH_LIMIT) { + throw new IllegalArgumentException("크루 제목은 " + NAME_LENGTH_LIMIT + "자를 넘을 수 없습니다."); + } + if (description.length() > DESCRIPTION_LENGTH_LIMIT) { + throw new IllegalArgumentException("크루 설명은 " + DESCRIPTION_LENGTH_LIMIT + "자를 넘을 수 없습니다."); + } + } +} diff --git a/src/main/java/com/retrip/crew/domain/vo/FreeBoardContent.java b/src/main/java/com/retrip/crew/domain/vo/FreeBoardContent.java new file mode 100644 index 0000000..c69b63f --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/vo/FreeBoardContent.java @@ -0,0 +1,38 @@ +package com.retrip.crew.domain.vo; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Embeddable +@EqualsAndHashCode +@NoArgsConstructor(access = AccessLevel.PROTECTED, force = true) +public class FreeBoardContent { + private static final int TITLE_LENGTH_LIMIT = 30; + private static final int CONTENT_LENGTH_LIMIT = 100; + + @Column(name = "title", nullable = false, length = TITLE_LENGTH_LIMIT) + private final String title; + + @Column(name = "content", nullable = false, length = CONTENT_LENGTH_LIMIT) + private final String content; + + public FreeBoardContent(String title, String content) { + validate(title, content); + this.title = title; + this.content = content; + } + + private void validate(String title, String content) { + if (title.length() > TITLE_LENGTH_LIMIT) { + throw new IllegalArgumentException("자유 게시글 제목은 " + TITLE_LENGTH_LIMIT + "자를 넘을 수 없습니다."); + } + if (content.length() > CONTENT_LENGTH_LIMIT) { + throw new IllegalArgumentException("자유 게시글 내용은 " + CONTENT_LENGTH_LIMIT + "자를 넘을 수 없습니다."); + } + } +} diff --git a/src/main/java/com/retrip/crew/domain/vo/NotificationBoardContent.java b/src/main/java/com/retrip/crew/domain/vo/NotificationBoardContent.java new file mode 100644 index 0000000..eeb7017 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/vo/NotificationBoardContent.java @@ -0,0 +1,38 @@ +package com.retrip.crew.domain.vo; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Embeddable +@EqualsAndHashCode +@NoArgsConstructor(access = AccessLevel.PROTECTED, force = true) +public class NotificationBoardContent { + private static final int TITLE_LENGTH_LIMIT = 30; + private static final int CONTENT_LENGTH_LIMIT = 100; + + @Column(name = "title", nullable = false, length = TITLE_LENGTH_LIMIT) + private final String title; + + @Column(name = "content", nullable = false, length = CONTENT_LENGTH_LIMIT) + private final String content; + + public NotificationBoardContent(String title, String content) { + validate(title, content); + this.title = title; + this.content = content; + } + + private void validate(String title, String content) { + if (title.length() > TITLE_LENGTH_LIMIT) { + throw new IllegalArgumentException("공지 게시글 제목은 " + TITLE_LENGTH_LIMIT + "자를 넘을 수 없습니다."); + } + if (content.length() > CONTENT_LENGTH_LIMIT) { + throw new IllegalArgumentException("공지 게시글 내용은 " + CONTENT_LENGTH_LIMIT + "자를 넘을 수 없습니다."); + } + } +} diff --git a/src/main/java/com/retrip/crew/domain/vo/SelfIntroduceBoardContent.java b/src/main/java/com/retrip/crew/domain/vo/SelfIntroduceBoardContent.java new file mode 100644 index 0000000..1c7b9eb --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/vo/SelfIntroduceBoardContent.java @@ -0,0 +1,38 @@ +package com.retrip.crew.domain.vo; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Embeddable +@EqualsAndHashCode +@NoArgsConstructor(access = AccessLevel.PROTECTED, force = true) +public class SelfIntroduceBoardContent { + private static final int TITLE_LENGTH_LIMIT = 30; + private static final int CONTENT_LENGTH_LIMIT = 100; + + @Column(name = "title", nullable = false, length = TITLE_LENGTH_LIMIT) + private final String title; + + @Column(name = "content", nullable = false, length = CONTENT_LENGTH_LIMIT) + private final String content; + + public SelfIntroduceBoardContent(String title, String content) { + validate(title, content); + this.title = title; + this.content = content; + } + + private void validate(String title, String content) { + if (title.length() > TITLE_LENGTH_LIMIT) { + throw new IllegalArgumentException("자기 소개 게시글 제목은 " + TITLE_LENGTH_LIMIT + "자를 넘을 수 없습니다."); + } + if (content.length() > CONTENT_LENGTH_LIMIT) { + throw new IllegalArgumentException("자기 소개 게시글 내용은 " + CONTENT_LENGTH_LIMIT + "자를 넘을 수 없습니다."); + } + } +} diff --git a/src/main/java/com/retrip/crew/infra/adapter/out/gateway/rest/member/MemberClient.java b/src/main/java/com/retrip/crew/infra/adapter/out/gateway/rest/member/MemberClient.java new file mode 100644 index 0000000..c050888 --- /dev/null +++ b/src/main/java/com/retrip/crew/infra/adapter/out/gateway/rest/member/MemberClient.java @@ -0,0 +1,14 @@ +package com.retrip.crew.infra.adapter.out.gateway.rest.member; + +import com.retrip.crew.infra.adapter.out.gateway.rest.member.response.MemberResponse; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.service.annotation.GetExchange; +import org.springframework.web.service.annotation.HttpExchange; + +import java.util.UUID; + +//@HttpExchange(url = "${apis.urls.member}") +public interface MemberClient { + //@GetExchange("/{memberId}") + MemberResponse getMember(@PathVariable("memberId") UUID memberId); +} diff --git a/src/main/java/com/retrip/crew/infra/adapter/out/gateway/rest/member/MockMemberClient.java b/src/main/java/com/retrip/crew/infra/adapter/out/gateway/rest/member/MockMemberClient.java new file mode 100644 index 0000000..61393d2 --- /dev/null +++ b/src/main/java/com/retrip/crew/infra/adapter/out/gateway/rest/member/MockMemberClient.java @@ -0,0 +1,20 @@ +package com.retrip.crew.infra.adapter.out.gateway.rest.member; + +import com.retrip.crew.infra.adapter.out.gateway.rest.member.response.MemberResponse; +import org.springframework.stereotype.Component; + +import java.util.UUID; + +@Component +public class MockMemberClient implements MemberClient { + + @Override + public MemberResponse getMember(UUID memberId) { + return new MemberResponse( + UUID.randomUUID(), + "김준호", + 30, + MemberResponse.GenderResponse.MALE + ); + } +} diff --git a/src/main/java/com/retrip/crew/infra/adapter/out/gateway/rest/member/response/MemberResponse.java b/src/main/java/com/retrip/crew/infra/adapter/out/gateway/rest/member/response/MemberResponse.java new file mode 100644 index 0000000..dfbc9b1 --- /dev/null +++ b/src/main/java/com/retrip/crew/infra/adapter/out/gateway/rest/member/response/MemberResponse.java @@ -0,0 +1,16 @@ +package com.retrip.crew.infra.adapter.out.gateway.rest.member.response; + + + +import java.util.UUID; + +public record MemberResponse ( + UUID id, + String name, + int age, + GenderResponse gender +){ + public enum GenderResponse{ + MALE, FEMALE + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index aafba9a..ca9300c 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -19,3 +19,7 @@ logging: level: org.hibernate.type.descriptor.sql: trace org.springframework.web.client.RestTemplate: DEBUG + +apis: + url: + member: "http://www.naver.com" diff --git a/src/test/java/com/retrip/crew/CrewApplicationTests.java b/src/test/java/com/retrip/crew/CrewApplicationTests.java index 76c2982..405f037 100644 --- a/src/test/java/com/retrip/crew/CrewApplicationTests.java +++ b/src/test/java/com/retrip/crew/CrewApplicationTests.java @@ -3,9 +3,8 @@ import com.retrip.crew.domain.entity.Crew; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; -import java.time.LocalDate; +import java.util.UUID; import static org.assertj.core.api.Assertions.assertThatCode; @@ -13,7 +12,11 @@ class CrewApplicationTests { @DisplayName("제목을 입력해 크루를 생성할 수 있다.") @Test void create() { - assertThatCode(() -> Crew.create("속초 크루 모집")).doesNotThrowAnyException(); + assertThatCode(() -> Crew.create( + "인천 크루 모집", + "인천 크루원을 모집합니다.\n 가입나이: 20~29살 \n 금지 사항\n - 연애 금지\n - 만남 당일 취소 금지\n - 사적 연락 금지", + UUID.randomUUID() + )).doesNotThrowAnyException(); } } diff --git a/src/test/java/com/retrip/crew/application/in/CrewServiceTest.java b/src/test/java/com/retrip/crew/application/in/CrewServiceTest.java new file mode 100644 index 0000000..2b5490e --- /dev/null +++ b/src/test/java/com/retrip/crew/application/in/CrewServiceTest.java @@ -0,0 +1,57 @@ +package com.retrip.crew.application.in; + +import com.retrip.crew.application.in.request.CrewCreateRequest; +import com.retrip.crew.application.in.response.CrewCreateResponse; +import com.retrip.crew.application.out.repository.CrewRepository; +import com.retrip.crew.infra.adapter.out.gateway.rest.member.MemberClient; +import com.retrip.crew.infra.adapter.out.gateway.rest.member.response.MemberResponse; +import org.junit.jupiter.api.BeforeEach; +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.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; + +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@DataJpaTest +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +class CrewServiceTest { + @Autowired + CrewRepository crewRepository; + + MemberClient memberClient = mock(MemberClient.class); + + CrewService crewService; + UUID memberId = UUID.randomUUID(); + + @BeforeEach + void setUp() { + crewService = new CrewService(crewRepository, memberClient); + } + + @DisplayName("크루를 생성 한다.") + @Test + void createCrew() { + when(memberClient.getMember(memberId)).thenReturn(new MemberResponse( + memberId, + "김준호", + 30, + MemberResponse.GenderResponse.MALE + )); + + + CrewCreateRequest request = new CrewCreateRequest( + memberId, + "속초 크루원 구함", + "속초 친구 구합니다! 나이는 20~40.. 많은 가입 부탁드립니다." + ); + CrewCreateResponse response = crewService.createCrew(request); + + assertThat(response.id()).isNotNull(); + } +} diff --git a/src/test/java/com/retrip/crew/domain/entity/CrewTest.java b/src/test/java/com/retrip/crew/domain/entity/CrewTest.java index eb2edcf..2c89485 100644 --- a/src/test/java/com/retrip/crew/domain/entity/CrewTest.java +++ b/src/test/java/com/retrip/crew/domain/entity/CrewTest.java @@ -1,7 +1,20 @@ package com.retrip.crew.domain.entity; -import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.util.UUID; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; class CrewTest { + @DisplayName("크루 생성 테스트") + @Test + public void create() { + assertThatCode(() -> Crew.create( + "속초 크루원 구함", + "속초 친구 구합니다! 나이는 20~40.. 많은 가입 부탁드립니다.", + UUID.randomUUID())).doesNotThrowAnyException(); + } } diff --git a/src/test/java/com/retrip/crew/domain/vo/CrewContentTest.java b/src/test/java/com/retrip/crew/domain/vo/CrewContentTest.java new file mode 100644 index 0000000..3b737b3 --- /dev/null +++ b/src/test/java/com/retrip/crew/domain/vo/CrewContentTest.java @@ -0,0 +1,31 @@ +package com.retrip.crew.domain.vo; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; + +class CrewContentTest { + + @Test + @DisplayName("크루 이름은 30자 미만으로 설정해야한다.") + public void validateName() { + assertThatThrownBy(() -> new CrewContent( + "통천, 회양, 평강, 이천, 김화, 철원, 양구, 인제, 고성, 강릉, 속초 등 크루 인원 모집합니다. 다들 오세요", + "강원도 크루 모집합니다.") + ) + .isExactlyInstanceOf(IllegalArgumentException.class); + } + + @Test + @DisplayName("크루 설명은 100자 미만으로 설정해야한다.") + public void validateDescription() { + assertThatThrownBy(() -> new CrewContent( + "춘천 크루 모집 92년생~76년생", + "춘천에서 좋은분들과 식사하고 차도 마시며 살아가는 이야기를 나누는 모임입니다. 등산,낚시,골프,당구,배드민턴, 영화등 다양한 취미활동도 같이 하면서 친분을 쌓고 인맥을 넓히며 춘천에 대한 다양한 정보도 공유하고 진솔한 삶의 의미를 찾을수 있도록 인연을 무엇보다 소중하게 생각하는 모임입니다.\n" + + "\n" + + "지속적으로 모임방이 유지되는 이유는 배려심과 생각이 깊은 많은회원분들이 있기에 춘천의 대표 모임방으로 인정받은게 아닌가 싶습니다. 많은 분들이 오셔서 춘천에서 살아가는 이야기를 나눠 보자구요~\n") + ) + .isExactlyInstanceOf(IllegalArgumentException.class); + } +} From a11296f321af8a65a876e6b203eb62bf04ff9321 Mon Sep 17 00:00:00 2001 From: junhokim Date: Fri, 21 Feb 2025 18:20:20 +0900 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20Code=20=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=EB=B0=98=EC=98=81,=20Exception=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../crew/application/in/CrewService.java | 7 +-- .../in/request/CrewCreateRequest.java | 4 +- .../in/response/CrewCreateResponse.java | 8 +-- .../converter/CrewMemberRoleConverter.java | 24 ++++++++ ...tificationBoard.java => Announcement.java} | 2 +- .../crew/domain/entity/Announcements.java | 26 +++++++++ .../com/retrip/crew/domain/entity/Crew.java | 55 +++++++++++-------- .../retrip/crew/domain/entity/CrewMember.java | 12 ++-- .../crew/domain/entity/CrewMemberRole.java | 25 +++++++++ .../crew/domain/entity/CrewMembers.java | 32 +++++++++++ ...fIntroduceBoard.java => Introduction.java} | 11 ++-- .../crew/domain/entity/Introductions.java | 24 ++++++++ .../entity/{FreeBoard.java => Post.java} | 11 ++-- .../com/retrip/crew/domain/entity/Posts.java | 26 +++++++++ .../com/retrip/crew/domain/entity/Role.java | 8 --- .../AnnouncementContentException.java | 8 +++ .../exception/AnnouncementTitleException.java | 8 +++ .../exception/CrewDescriptionException.java | 8 +++ .../crew/domain/exception/CrewErrorCode.java | 17 ++++++ .../crew/domain/exception/CrewException.java | 10 ++++ .../domain/exception/CrewTitleException.java | 7 +++ .../IntroductionContentException.java | 9 +++ .../exception/IntroductionTitleException.java | 9 +++ .../exception/PostContentException.java | 8 +++ .../domain/exception/PostTitleException.java | 8 +++ .../crew/domain/vo/AnnouncementContent.java | 31 +++++++++++ .../crew/domain/vo/AnnouncementTitle.java | 31 +++++++++++ .../retrip/crew/domain/vo/CrewContent.java | 38 ------------- .../crew/domain/vo/CrewDescription.java | 31 +++++++++++ .../com/retrip/crew/domain/vo/CrewTitle.java | 31 +++++++++++ .../crew/domain/vo/FreeBoardContent.java | 38 ------------- .../crew/domain/vo/IntroductionContent.java | 31 +++++++++++ .../crew/domain/vo/IntroductionTitle.java | 32 +++++++++++ .../retrip/crew/domain/vo/PostContent.java | 31 +++++++++++ .../com/retrip/crew/domain/vo/PostTitle.java | 31 +++++++++++ .../domain/vo/SelfIntroduceBoardContent.java | 38 ------------- .../out/gateway/rest/member/MemberClient.java | 14 ----- .../gateway/rest/member/MockMemberClient.java | 20 ------- .../rest/member/response/MemberResponse.java | 16 ------ .../crew/application/in/CrewServiceTest.java | 17 +----- .../crew/domain/vo/CrewContentTest.java | 31 ----------- .../domain/vo/CrewIntroductionTitleTest.java | 16 ++++++ 42 files changed, 574 insertions(+), 270 deletions(-) create mode 100644 src/main/java/com/retrip/crew/domain/converter/CrewMemberRoleConverter.java rename src/main/java/com/retrip/crew/domain/entity/{NotificationBoard.java => Announcement.java} (93%) create mode 100644 src/main/java/com/retrip/crew/domain/entity/Announcements.java create mode 100644 src/main/java/com/retrip/crew/domain/entity/CrewMemberRole.java create mode 100644 src/main/java/com/retrip/crew/domain/entity/CrewMembers.java rename src/main/java/com/retrip/crew/domain/entity/{SelfIntroduceBoard.java => Introduction.java} (71%) create mode 100644 src/main/java/com/retrip/crew/domain/entity/Introductions.java rename src/main/java/com/retrip/crew/domain/entity/{FreeBoard.java => Post.java} (74%) create mode 100644 src/main/java/com/retrip/crew/domain/entity/Posts.java delete mode 100644 src/main/java/com/retrip/crew/domain/entity/Role.java create mode 100644 src/main/java/com/retrip/crew/domain/exception/AnnouncementContentException.java create mode 100644 src/main/java/com/retrip/crew/domain/exception/AnnouncementTitleException.java create mode 100644 src/main/java/com/retrip/crew/domain/exception/CrewDescriptionException.java create mode 100644 src/main/java/com/retrip/crew/domain/exception/CrewErrorCode.java create mode 100644 src/main/java/com/retrip/crew/domain/exception/CrewException.java create mode 100644 src/main/java/com/retrip/crew/domain/exception/CrewTitleException.java create mode 100644 src/main/java/com/retrip/crew/domain/exception/IntroductionContentException.java create mode 100644 src/main/java/com/retrip/crew/domain/exception/IntroductionTitleException.java create mode 100644 src/main/java/com/retrip/crew/domain/exception/PostContentException.java create mode 100644 src/main/java/com/retrip/crew/domain/exception/PostTitleException.java create mode 100644 src/main/java/com/retrip/crew/domain/vo/AnnouncementContent.java create mode 100644 src/main/java/com/retrip/crew/domain/vo/AnnouncementTitle.java delete mode 100644 src/main/java/com/retrip/crew/domain/vo/CrewContent.java create mode 100644 src/main/java/com/retrip/crew/domain/vo/CrewDescription.java create mode 100644 src/main/java/com/retrip/crew/domain/vo/CrewTitle.java delete mode 100644 src/main/java/com/retrip/crew/domain/vo/FreeBoardContent.java create mode 100644 src/main/java/com/retrip/crew/domain/vo/IntroductionContent.java create mode 100644 src/main/java/com/retrip/crew/domain/vo/IntroductionTitle.java create mode 100644 src/main/java/com/retrip/crew/domain/vo/PostContent.java create mode 100644 src/main/java/com/retrip/crew/domain/vo/PostTitle.java delete mode 100644 src/main/java/com/retrip/crew/domain/vo/SelfIntroduceBoardContent.java delete mode 100644 src/main/java/com/retrip/crew/infra/adapter/out/gateway/rest/member/MemberClient.java delete mode 100644 src/main/java/com/retrip/crew/infra/adapter/out/gateway/rest/member/MockMemberClient.java delete mode 100644 src/main/java/com/retrip/crew/infra/adapter/out/gateway/rest/member/response/MemberResponse.java delete mode 100644 src/test/java/com/retrip/crew/domain/vo/CrewContentTest.java create mode 100644 src/test/java/com/retrip/crew/domain/vo/CrewIntroductionTitleTest.java diff --git a/src/main/java/com/retrip/crew/application/in/CrewService.java b/src/main/java/com/retrip/crew/application/in/CrewService.java index 8e5e2c0..661c355 100644 --- a/src/main/java/com/retrip/crew/application/in/CrewService.java +++ b/src/main/java/com/retrip/crew/application/in/CrewService.java @@ -5,8 +5,6 @@ import com.retrip.crew.application.in.usecase.CreateCrewUseCase; import com.retrip.crew.application.out.repository.CrewRepository; import com.retrip.crew.domain.entity.Crew; -import com.retrip.crew.infra.adapter.out.gateway.rest.member.MemberClient; -import com.retrip.crew.infra.adapter.out.gateway.rest.member.response.MemberResponse; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -16,13 +14,10 @@ @RequiredArgsConstructor public class CrewService implements CreateCrewUseCase { private final CrewRepository crewRepository; - private final MemberClient memberClient; @Override public CrewCreateResponse createCrew(CrewCreateRequest request) { - MemberResponse leader = memberClient.getMember(request.leader()); - Crew entity = request.to(leader.id()); - Crew crew = crewRepository.save(entity); + Crew crew = crewRepository.save(request.to(request.leader())); return CrewCreateResponse.of(crew); } diff --git a/src/main/java/com/retrip/crew/application/in/request/CrewCreateRequest.java b/src/main/java/com/retrip/crew/application/in/request/CrewCreateRequest.java index 4121836..c987d3d 100644 --- a/src/main/java/com/retrip/crew/application/in/request/CrewCreateRequest.java +++ b/src/main/java/com/retrip/crew/application/in/request/CrewCreateRequest.java @@ -8,12 +8,12 @@ public record CrewCreateRequest( UUID leader, @Size(min = 1, max = 30) - String name, + String title, @Size(min = 1, max = 500) String description ){ public Crew to(UUID leader) { - return Crew.create(this.name, this.description, leader); + return Crew.create(this.title, this.description, leader); } } diff --git a/src/main/java/com/retrip/crew/application/in/response/CrewCreateResponse.java b/src/main/java/com/retrip/crew/application/in/response/CrewCreateResponse.java index 5ea6adc..b710eba 100644 --- a/src/main/java/com/retrip/crew/application/in/response/CrewCreateResponse.java +++ b/src/main/java/com/retrip/crew/application/in/response/CrewCreateResponse.java @@ -6,16 +6,16 @@ public record CrewCreateResponse( UUID id, - String name, + String title, String description, UUID leaderId ) { public static CrewCreateResponse of(Crew crew) { return new CrewCreateResponse( crew.getId(), - crew.getCrewContent().getName(), - crew.getCrewContent().getDescription(), - crew.getLeader().getFirst().getId() + crew.getTitle().getValue(), + crew.getDescription().getValue(), + crew.getLeader().getId() ); } } diff --git a/src/main/java/com/retrip/crew/domain/converter/CrewMemberRoleConverter.java b/src/main/java/com/retrip/crew/domain/converter/CrewMemberRoleConverter.java new file mode 100644 index 0000000..fd4ea2c --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/converter/CrewMemberRoleConverter.java @@ -0,0 +1,24 @@ +package com.retrip.crew.domain.converter; + +import com.retrip.crew.domain.entity.CrewMemberRole; +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; + +@Converter(autoApply = true) +public class CrewMemberRoleConverter implements AttributeConverter { + @Override + public String convertToDatabaseColumn(CrewMemberRole crewMemberRole) { + if(crewMemberRole == null){ + throw new NullPointerException("crewMemberRole을 DB 칼럼으로 변경하는 과정에서 null이 포함되었습니다."); + } + return crewMemberRole.getCode(); + } + + @Override + public CrewMemberRole convertToEntityAttribute(String dbData) { + if(dbData == null){ + throw new NullPointerException("CrewMember 테이블의 role 값이 null입니다."); + } + return CrewMemberRole.codeOf(dbData); + } +} diff --git a/src/main/java/com/retrip/crew/domain/entity/NotificationBoard.java b/src/main/java/com/retrip/crew/domain/entity/Announcement.java similarity index 93% rename from src/main/java/com/retrip/crew/domain/entity/NotificationBoard.java rename to src/main/java/com/retrip/crew/domain/entity/Announcement.java index c7f6d72..681825d 100644 --- a/src/main/java/com/retrip/crew/domain/entity/NotificationBoard.java +++ b/src/main/java/com/retrip/crew/domain/entity/Announcement.java @@ -11,7 +11,7 @@ @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter -public class NotificationBoard extends BaseEntity { +public class Announcement extends BaseEntity { @Id @Column(columnDefinition = "varbinary(16)") private UUID id; diff --git a/src/main/java/com/retrip/crew/domain/entity/Announcements.java b/src/main/java/com/retrip/crew/domain/entity/Announcements.java new file mode 100644 index 0000000..652989d --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/entity/Announcements.java @@ -0,0 +1,26 @@ +package com.retrip.crew.domain.entity; + +import jakarta.persistence.CascadeType; +import jakarta.persistence.Embeddable; +import jakarta.persistence.OneToMany; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; + +@Getter +@Embeddable +public class Announcements { + @OneToMany(mappedBy = "crew", cascade = CascadeType.ALL, orphanRemoval = true) + private List values = new ArrayList<>(); + + public Announcements() { //리더 생성 + this.values = createEmptyValues(); + } + + private List createEmptyValues() { + return new ArrayList<>(); + } +} diff --git a/src/main/java/com/retrip/crew/domain/entity/Crew.java b/src/main/java/com/retrip/crew/domain/entity/Crew.java index f42f8ba..d2c9f28 100644 --- a/src/main/java/com/retrip/crew/domain/entity/Crew.java +++ b/src/main/java/com/retrip/crew/domain/entity/Crew.java @@ -1,55 +1,64 @@ package com.retrip.crew.domain.entity; -import com.retrip.crew.domain.vo.CrewContent; +import com.retrip.crew.domain.vo.CrewDescription; +import com.retrip.crew.domain.vo.CrewTitle; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; -import java.util.ArrayList; -import java.util.List; import java.util.UUID; @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) -@Getter public class Crew extends BaseEntity { @Id @Column(columnDefinition = "varbinary(16)") + @Getter private UUID id; + @Getter @Embedded - private CrewContent crewContent; + private CrewTitle title; + + @Embedded + @Getter + private CrewDescription description; - @OneToMany(mappedBy = "crew", cascade = CascadeType.ALL, orphanRemoval = true) - private List leader = new ArrayList<>(); - @OneToMany(mappedBy = "crew", cascade = CascadeType.ALL, orphanRemoval = true) - private List members = new ArrayList<>(); + @Embedded + private CrewMembers crewMembers; - @OneToMany(mappedBy = "crew", cascade = CascadeType.ALL, orphanRemoval = true) - private List freeBoards = new ArrayList<>(); - @OneToMany(mappedBy = "crew", cascade = CascadeType.ALL, orphanRemoval = true) - private List notificationBoards = new ArrayList<>(); + @Embedded + private Posts posts; + + @Embedded + private Announcements announcements; + + @Embedded + private Introductions introductions; - @OneToMany(mappedBy = "crew", cascade = CascadeType.ALL, orphanRemoval = true) - private List selfIntroduceBoards = new ArrayList<>(); @Version private long version; private Crew(String name, String description, UUID leader) { this.id = UUID.randomUUID(); - this.crewContent = new CrewContent(name, description); - this.leader = CrewMember.createLeader(this, leader, Role.LEADER); - this.members = new ArrayList<>(); - this.freeBoards = new ArrayList<>(); - this.notificationBoards = new ArrayList<>(); - this.selfIntroduceBoards = new ArrayList<>(); + this.title = new CrewTitle(name); + this.description = new CrewDescription(description); + this.crewMembers = new CrewMembers(this, leader); + this.posts = new Posts(); + this.announcements = new Announcements(); + this.introductions = new Introductions(); } - public static Crew create(String name, String description, UUID leader) { - return new Crew(name, description, leader); + public static Crew create(String title, String description, UUID leader) { + return new Crew(title, description, leader); } + + public CrewMember getLeader() { + return crewMembers.getLeader(); + } + } diff --git a/src/main/java/com/retrip/crew/domain/entity/CrewMember.java b/src/main/java/com/retrip/crew/domain/entity/CrewMember.java index 8572957..7a2c6f1 100644 --- a/src/main/java/com/retrip/crew/domain/entity/CrewMember.java +++ b/src/main/java/com/retrip/crew/domain/entity/CrewMember.java @@ -25,20 +25,16 @@ public class CrewMember extends BaseEntity { ) private Crew crew; - @Enumerated - private Role role; + @Column(name = "role", length = 50, nullable = false) + private CrewMemberRole crewMemberRole; @Column(nullable = false) private UUID memberId; - private CrewMember(Crew crew, UUID memberId, Role role) { + public CrewMember(Crew crew, UUID memberId, CrewMemberRole crewMemberRole) { this.id = UUID.randomUUID(); this.crew = crew; this.memberId = memberId; - this.role = Role.valueOf(role.name()); - } - - public static List createLeader(Crew crew, UUID memberId, Role role) { - return List.of(new CrewMember(crew, memberId, role)); + this.crewMemberRole = CrewMemberRole.valueOf(crewMemberRole.name()); } } diff --git a/src/main/java/com/retrip/crew/domain/entity/CrewMemberRole.java b/src/main/java/com/retrip/crew/domain/entity/CrewMemberRole.java new file mode 100644 index 0000000..86072f2 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/entity/CrewMemberRole.java @@ -0,0 +1,25 @@ +package com.retrip.crew.domain.entity; + + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Arrays; + +@Getter +@AllArgsConstructor +public enum CrewMemberRole { + LEADER("LEADER", "리더"), + PARTICIPANT("PARTICIPANT", "참가자"); + + private final String code; + private final String viewName; + + public static CrewMemberRole codeOf(String code) { + return Arrays.stream(CrewMemberRole.values()) + .filter(crewMemberRole -> crewMemberRole.getCode().equals(code)) + .findAny() + .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 코드입니다.")); + } +} + diff --git a/src/main/java/com/retrip/crew/domain/entity/CrewMembers.java b/src/main/java/com/retrip/crew/domain/entity/CrewMembers.java new file mode 100644 index 0000000..cabf553 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/entity/CrewMembers.java @@ -0,0 +1,32 @@ +package com.retrip.crew.domain.entity; + +import jakarta.persistence.CascadeType; +import jakarta.persistence.Embeddable; +import jakarta.persistence.OneToMany; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED, force = true) +@Embeddable +public class CrewMembers { + @OneToMany(mappedBy = "crew", cascade = CascadeType.ALL, orphanRemoval = true) + private List values = new ArrayList<>(); + + public CrewMembers(Crew crew, UUID member) { //리더 생성 + this.values = createLeader(crew, member); + } + + private List createLeader(Crew crew, UUID memberId) { + return List.of(new CrewMember(crew, memberId, CrewMemberRole.LEADER)); + } + + public CrewMember getLeader() { + return this.values.stream().filter(it -> it.getCrewMemberRole() == CrewMemberRole.LEADER).findFirst().orElse(null); + } +} diff --git a/src/main/java/com/retrip/crew/domain/entity/SelfIntroduceBoard.java b/src/main/java/com/retrip/crew/domain/entity/Introduction.java similarity index 71% rename from src/main/java/com/retrip/crew/domain/entity/SelfIntroduceBoard.java rename to src/main/java/com/retrip/crew/domain/entity/Introduction.java index 2c100d8..1753df1 100644 --- a/src/main/java/com/retrip/crew/domain/entity/SelfIntroduceBoard.java +++ b/src/main/java/com/retrip/crew/domain/entity/Introduction.java @@ -1,7 +1,7 @@ package com.retrip.crew.domain.entity; -import com.retrip.crew.domain.vo.NotificationBoardContent; -import com.retrip.crew.domain.vo.SelfIntroduceBoardContent; +import com.retrip.crew.domain.vo.IntroductionContent; +import com.retrip.crew.domain.vo.IntroductionTitle; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Getter; @@ -12,13 +12,16 @@ @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter -public class SelfIntroduceBoard extends BaseEntity { +public class Introduction extends BaseEntity { @Id @Column(columnDefinition = "varbinary(16)") private UUID id; @Embedded - private SelfIntroduceBoardContent content; + private IntroductionTitle title; + + @Embedded + private IntroductionContent content; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn( diff --git a/src/main/java/com/retrip/crew/domain/entity/Introductions.java b/src/main/java/com/retrip/crew/domain/entity/Introductions.java new file mode 100644 index 0000000..b5d8470 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/entity/Introductions.java @@ -0,0 +1,24 @@ +package com.retrip.crew.domain.entity; + +import jakarta.persistence.CascadeType; +import jakarta.persistence.Embeddable; +import jakarta.persistence.OneToMany; +import lombok.Getter; + +import java.util.ArrayList; +import java.util.List; + +@Getter +@Embeddable +public class Introductions { + @OneToMany(mappedBy = "crew", cascade = CascadeType.ALL, orphanRemoval = true) + private List values = new ArrayList<>(); + + public Introductions() { //리더 생성 + this.values = createEmptyValues(); + } + + private List createEmptyValues() { + return new ArrayList<>(); + } +} diff --git a/src/main/java/com/retrip/crew/domain/entity/FreeBoard.java b/src/main/java/com/retrip/crew/domain/entity/Post.java similarity index 74% rename from src/main/java/com/retrip/crew/domain/entity/FreeBoard.java rename to src/main/java/com/retrip/crew/domain/entity/Post.java index 9771531..8bcf102 100644 --- a/src/main/java/com/retrip/crew/domain/entity/FreeBoard.java +++ b/src/main/java/com/retrip/crew/domain/entity/Post.java @@ -1,7 +1,7 @@ package com.retrip.crew.domain.entity; -import com.retrip.crew.domain.vo.FreeBoardContent; -import com.retrip.crew.domain.vo.NotificationBoardContent; +import com.retrip.crew.domain.vo.PostContent; +import com.retrip.crew.domain.vo.PostTitle; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Getter; @@ -12,13 +12,16 @@ @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter -public class FreeBoard extends BaseEntity { +public class Post extends BaseEntity { @Id @Column(columnDefinition = "varbinary(16)") private UUID id; @Embedded - private FreeBoardContent content; + private PostTitle title; + + @Embedded + private PostContent content; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn( diff --git a/src/main/java/com/retrip/crew/domain/entity/Posts.java b/src/main/java/com/retrip/crew/domain/entity/Posts.java new file mode 100644 index 0000000..1159c46 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/entity/Posts.java @@ -0,0 +1,26 @@ +package com.retrip.crew.domain.entity; + +import jakarta.persistence.CascadeType; +import jakarta.persistence.Embeddable; +import jakarta.persistence.OneToMany; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; + +@Getter +@Embeddable +public class Posts { + @OneToMany(mappedBy = "crew", cascade = CascadeType.ALL, orphanRemoval = true) + private List values = new ArrayList<>(); + + public Posts() { //리더 생성 + this.values = createEmptyValues(); + } + + private List createEmptyValues() { + return new ArrayList<>(); + } +} diff --git a/src/main/java/com/retrip/crew/domain/entity/Role.java b/src/main/java/com/retrip/crew/domain/entity/Role.java deleted file mode 100644 index cabcfd3..0000000 --- a/src/main/java/com/retrip/crew/domain/entity/Role.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.retrip.crew.domain.entity; - -import jakarta.persistence.Embedded; - -public enum Role { - LEADER, GENERAL -} - diff --git a/src/main/java/com/retrip/crew/domain/exception/AnnouncementContentException.java b/src/main/java/com/retrip/crew/domain/exception/AnnouncementContentException.java new file mode 100644 index 0000000..554d584 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/exception/AnnouncementContentException.java @@ -0,0 +1,8 @@ +package com.retrip.crew.domain.exception; + +public class AnnouncementContentException extends CrewException { + + public AnnouncementContentException(String message) { + super(CrewErrorCode.ANNOUNCEMENT_CONTENT_ERROR, message); + } +} diff --git a/src/main/java/com/retrip/crew/domain/exception/AnnouncementTitleException.java b/src/main/java/com/retrip/crew/domain/exception/AnnouncementTitleException.java new file mode 100644 index 0000000..571ae90 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/exception/AnnouncementTitleException.java @@ -0,0 +1,8 @@ +package com.retrip.crew.domain.exception; + +public class AnnouncementTitleException extends CrewException { + + public AnnouncementTitleException(String message) { + super(CrewErrorCode.ANNOUNCEMENT_TITLE_ERROR, message); + } +} diff --git a/src/main/java/com/retrip/crew/domain/exception/CrewDescriptionException.java b/src/main/java/com/retrip/crew/domain/exception/CrewDescriptionException.java new file mode 100644 index 0000000..04db44e --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/exception/CrewDescriptionException.java @@ -0,0 +1,8 @@ +package com.retrip.crew.domain.exception; + +public class CrewDescriptionException extends CrewException { + + public CrewDescriptionException(String message) { + super(CrewErrorCode.CREW_DESCRIPTION_ERROR, message); + } +} diff --git a/src/main/java/com/retrip/crew/domain/exception/CrewErrorCode.java b/src/main/java/com/retrip/crew/domain/exception/CrewErrorCode.java new file mode 100644 index 0000000..d494b90 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/exception/CrewErrorCode.java @@ -0,0 +1,17 @@ +package com.retrip.crew.domain.exception; + +public enum CrewErrorCode { + CREW_TITLE_ERROR(1001), + CREW_DESCRIPTION_ERROR(1002), + POST_TITLE_ERROR(1003), + POST_CONTENT_ERROR(1004), + ANNOUNCEMENT_TITLE_ERROR(1005), + ANNOUNCEMENT_CONTENT_ERROR(1006), + INTRODUCTION_TITLE_ERROR(1007), + INTRODUCTION_CONTENT_ERROR(1008); + + private final int code; + CrewErrorCode(int code) { + this.code = code; + } +} diff --git a/src/main/java/com/retrip/crew/domain/exception/CrewException.java b/src/main/java/com/retrip/crew/domain/exception/CrewException.java new file mode 100644 index 0000000..6b851e9 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/exception/CrewException.java @@ -0,0 +1,10 @@ +package com.retrip.crew.domain.exception; + +public abstract class CrewException extends RuntimeException { + private final CrewErrorCode errorCode; + + public CrewException(CrewErrorCode errorCode, String message) { + super(message); + this.errorCode = errorCode; + } +} diff --git a/src/main/java/com/retrip/crew/domain/exception/CrewTitleException.java b/src/main/java/com/retrip/crew/domain/exception/CrewTitleException.java new file mode 100644 index 0000000..ae1c0c1 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/exception/CrewTitleException.java @@ -0,0 +1,7 @@ +package com.retrip.crew.domain.exception; + +public class CrewTitleException extends CrewException { + public CrewTitleException(String message) { + super(CrewErrorCode.CREW_TITLE_ERROR, message); + } +} diff --git a/src/main/java/com/retrip/crew/domain/exception/IntroductionContentException.java b/src/main/java/com/retrip/crew/domain/exception/IntroductionContentException.java new file mode 100644 index 0000000..ab07f4b --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/exception/IntroductionContentException.java @@ -0,0 +1,9 @@ +package com.retrip.crew.domain.exception; + +public class IntroductionContentException extends CrewException { + private static final int ERROR_CODE = 1003; + + public IntroductionContentException(String message) { + super(CrewErrorCode.INTRODUCTION_CONTENT_ERROR, message); + } +} diff --git a/src/main/java/com/retrip/crew/domain/exception/IntroductionTitleException.java b/src/main/java/com/retrip/crew/domain/exception/IntroductionTitleException.java new file mode 100644 index 0000000..6d7af3e --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/exception/IntroductionTitleException.java @@ -0,0 +1,9 @@ +package com.retrip.crew.domain.exception; + +public class IntroductionTitleException extends CrewException { + private static final int ERROR_CODE = 1003; + + public IntroductionTitleException(String message) { + super(CrewErrorCode.INTRODUCTION_TITLE_ERROR, message); + } +} diff --git a/src/main/java/com/retrip/crew/domain/exception/PostContentException.java b/src/main/java/com/retrip/crew/domain/exception/PostContentException.java new file mode 100644 index 0000000..997f665 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/exception/PostContentException.java @@ -0,0 +1,8 @@ +package com.retrip.crew.domain.exception; + +public class PostContentException extends CrewException { + + public PostContentException(String message) { + super(CrewErrorCode.POST_CONTENT_ERROR, message); + } +} diff --git a/src/main/java/com/retrip/crew/domain/exception/PostTitleException.java b/src/main/java/com/retrip/crew/domain/exception/PostTitleException.java new file mode 100644 index 0000000..64afe6c --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/exception/PostTitleException.java @@ -0,0 +1,8 @@ +package com.retrip.crew.domain.exception; + +public class PostTitleException extends CrewException { + + public PostTitleException(String message) { + super(CrewErrorCode.POST_TITLE_ERROR, message); + } +} diff --git a/src/main/java/com/retrip/crew/domain/vo/AnnouncementContent.java b/src/main/java/com/retrip/crew/domain/vo/AnnouncementContent.java new file mode 100644 index 0000000..e213e0d --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/vo/AnnouncementContent.java @@ -0,0 +1,31 @@ +package com.retrip.crew.domain.vo; + +import com.retrip.crew.domain.exception.CrewDescriptionException; +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Embeddable +@EqualsAndHashCode +@NoArgsConstructor(access = AccessLevel.PROTECTED, force = true) +public class AnnouncementContent { + private static final int CONTENT_LENGTH_LIMIT = 300; + + @Column(name = "content", nullable = false, length = CONTENT_LENGTH_LIMIT) + private final String value; + + public AnnouncementContent(String value) { + validate(value); + this.value = value; + } + + private void validate(String value) { + if (value.length() > CONTENT_LENGTH_LIMIT) { + throw new CrewDescriptionException("공지 게시글 내용은 " + CONTENT_LENGTH_LIMIT + "자를 넘을 수 없습니다."); + } + } +} diff --git a/src/main/java/com/retrip/crew/domain/vo/AnnouncementTitle.java b/src/main/java/com/retrip/crew/domain/vo/AnnouncementTitle.java new file mode 100644 index 0000000..7aabaf1 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/vo/AnnouncementTitle.java @@ -0,0 +1,31 @@ +package com.retrip.crew.domain.vo; + +import com.retrip.crew.domain.exception.IntroductionTitleException; +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Embeddable +@EqualsAndHashCode +@NoArgsConstructor(access = AccessLevel.PROTECTED, force = true) +public class AnnouncementTitle { + private static final int TITLE_LENGTH_LIMIT = 20; + + @Column(name = "title", nullable = false, length = TITLE_LENGTH_LIMIT) + private final String value; + + public AnnouncementTitle(String value) { + validate(value); + this.value = value; + } + + private void validate(String value) { + if (value.length() > TITLE_LENGTH_LIMIT) { + throw new IntroductionTitleException("공지 게시글 제목은 " + TITLE_LENGTH_LIMIT + "자를 넘을 수 없습니다."); + } + } +} diff --git a/src/main/java/com/retrip/crew/domain/vo/CrewContent.java b/src/main/java/com/retrip/crew/domain/vo/CrewContent.java deleted file mode 100644 index ff68731..0000000 --- a/src/main/java/com/retrip/crew/domain/vo/CrewContent.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.retrip.crew.domain.vo; - -import jakarta.persistence.Column; -import jakarta.persistence.Embeddable; -import lombok.AccessLevel; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@Embeddable -@EqualsAndHashCode -@NoArgsConstructor(access = AccessLevel.PROTECTED, force = true) -public class CrewContent { - private static final int NAME_LENGTH_LIMIT = 30; - private static final int DESCRIPTION_LENGTH_LIMIT = 100; - - @Column(name = "name", nullable = false, length = NAME_LENGTH_LIMIT) - private final String name; - - @Column(name = "description", nullable = false, length = DESCRIPTION_LENGTH_LIMIT) - private final String description; - - public CrewContent(String name, String description) { - validate(name, description); - this.name = name; - this.description = description; - } - - private void validate(String name, String description) { - if (name.length() > NAME_LENGTH_LIMIT) { - throw new IllegalArgumentException("크루 제목은 " + NAME_LENGTH_LIMIT + "자를 넘을 수 없습니다."); - } - if (description.length() > DESCRIPTION_LENGTH_LIMIT) { - throw new IllegalArgumentException("크루 설명은 " + DESCRIPTION_LENGTH_LIMIT + "자를 넘을 수 없습니다."); - } - } -} diff --git a/src/main/java/com/retrip/crew/domain/vo/CrewDescription.java b/src/main/java/com/retrip/crew/domain/vo/CrewDescription.java new file mode 100644 index 0000000..76c0eb9 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/vo/CrewDescription.java @@ -0,0 +1,31 @@ +package com.retrip.crew.domain.vo; + +import com.retrip.crew.domain.exception.CrewDescriptionException; +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Embeddable +@EqualsAndHashCode +@NoArgsConstructor(access = AccessLevel.PROTECTED, force = true) +public class CrewDescription { + private static final int DESCRIPTION_LENGTH_LIMIT = 200; + + @Column(name = "description", nullable = false, length = DESCRIPTION_LENGTH_LIMIT) + private final String value; + + public CrewDescription(String value) { + validate(value); + this.value = value; + } + + private void validate(String value) { + if (value.length() > DESCRIPTION_LENGTH_LIMIT) { + throw new CrewDescriptionException("크루 상세 설명은 " + DESCRIPTION_LENGTH_LIMIT + "자를 넘을 수 없습니다."); + } + } +} diff --git a/src/main/java/com/retrip/crew/domain/vo/CrewTitle.java b/src/main/java/com/retrip/crew/domain/vo/CrewTitle.java new file mode 100644 index 0000000..50cdbac --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/vo/CrewTitle.java @@ -0,0 +1,31 @@ +package com.retrip.crew.domain.vo; + +import com.retrip.crew.domain.exception.CrewTitleException; +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Embeddable +@EqualsAndHashCode +@NoArgsConstructor(access = AccessLevel.PROTECTED, force = true) +public class CrewTitle { + private static final int TITLE_LENGTH_LIMIT = 30; + + @Column(name = "title", nullable = false, length = TITLE_LENGTH_LIMIT) + private final String value; + + public CrewTitle(String value) { + validate(value); + this.value = value; + } + + private void validate(String value) { + if (value.length() > TITLE_LENGTH_LIMIT) { + throw new CrewTitleException("크루 제목은 " + TITLE_LENGTH_LIMIT + "자를 넘을 수 없습니다."); + } + } +} diff --git a/src/main/java/com/retrip/crew/domain/vo/FreeBoardContent.java b/src/main/java/com/retrip/crew/domain/vo/FreeBoardContent.java deleted file mode 100644 index c69b63f..0000000 --- a/src/main/java/com/retrip/crew/domain/vo/FreeBoardContent.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.retrip.crew.domain.vo; - -import jakarta.persistence.Column; -import jakarta.persistence.Embeddable; -import lombok.AccessLevel; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@Embeddable -@EqualsAndHashCode -@NoArgsConstructor(access = AccessLevel.PROTECTED, force = true) -public class FreeBoardContent { - private static final int TITLE_LENGTH_LIMIT = 30; - private static final int CONTENT_LENGTH_LIMIT = 100; - - @Column(name = "title", nullable = false, length = TITLE_LENGTH_LIMIT) - private final String title; - - @Column(name = "content", nullable = false, length = CONTENT_LENGTH_LIMIT) - private final String content; - - public FreeBoardContent(String title, String content) { - validate(title, content); - this.title = title; - this.content = content; - } - - private void validate(String title, String content) { - if (title.length() > TITLE_LENGTH_LIMIT) { - throw new IllegalArgumentException("자유 게시글 제목은 " + TITLE_LENGTH_LIMIT + "자를 넘을 수 없습니다."); - } - if (content.length() > CONTENT_LENGTH_LIMIT) { - throw new IllegalArgumentException("자유 게시글 내용은 " + CONTENT_LENGTH_LIMIT + "자를 넘을 수 없습니다."); - } - } -} diff --git a/src/main/java/com/retrip/crew/domain/vo/IntroductionContent.java b/src/main/java/com/retrip/crew/domain/vo/IntroductionContent.java new file mode 100644 index 0000000..6001175 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/vo/IntroductionContent.java @@ -0,0 +1,31 @@ +package com.retrip.crew.domain.vo; + +import com.retrip.crew.domain.exception.CrewDescriptionException; +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Embeddable +@EqualsAndHashCode +@NoArgsConstructor(access = AccessLevel.PROTECTED, force = true) +public class IntroductionContent { + private static final int CONTENT_LENGTH_LIMIT = 500; + + @Column(name = "content", nullable = false, length = CONTENT_LENGTH_LIMIT) + private final String value; + + public IntroductionContent(String value) { + validate(value); + this.value = value; + } + + private void validate(String value) { + if (value.length() > CONTENT_LENGTH_LIMIT) { + throw new CrewDescriptionException("자기 소개 게시글 내용은 " + CONTENT_LENGTH_LIMIT + "자를 넘을 수 없습니다."); + } + } +} diff --git a/src/main/java/com/retrip/crew/domain/vo/IntroductionTitle.java b/src/main/java/com/retrip/crew/domain/vo/IntroductionTitle.java new file mode 100644 index 0000000..7668e76 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/vo/IntroductionTitle.java @@ -0,0 +1,32 @@ +package com.retrip.crew.domain.vo; + +import com.retrip.crew.domain.exception.CrewTitleException; +import com.retrip.crew.domain.exception.IntroductionTitleException; +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Embeddable +@EqualsAndHashCode +@NoArgsConstructor(access = AccessLevel.PROTECTED, force = true) +public class IntroductionTitle { + private static final int TITLE_LENGTH_LIMIT = 20; + + @Column(name = "title", nullable = false, length = TITLE_LENGTH_LIMIT) + private final String value; + + public IntroductionTitle(String value) { + validate(value); + this.value = value; + } + + private void validate(String value) { + if (value.length() > TITLE_LENGTH_LIMIT) { + throw new IntroductionTitleException("자기 소개 게시글 제목은 " + TITLE_LENGTH_LIMIT + "자를 넘을 수 없습니다."); + } + } +} diff --git a/src/main/java/com/retrip/crew/domain/vo/PostContent.java b/src/main/java/com/retrip/crew/domain/vo/PostContent.java new file mode 100644 index 0000000..65dcb15 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/vo/PostContent.java @@ -0,0 +1,31 @@ +package com.retrip.crew.domain.vo; + +import com.retrip.crew.domain.exception.CrewDescriptionException; +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Embeddable +@EqualsAndHashCode +@NoArgsConstructor(access = AccessLevel.PROTECTED, force = true) +public class PostContent { + private static final int CONTENT_LENGTH_LIMIT = 500; + + @Column(name = "content", nullable = false, length = CONTENT_LENGTH_LIMIT) + private final String value; + + public PostContent(String value) { + validate(value); + this.value = value; + } + + private void validate(String value) { + if (value.length() > CONTENT_LENGTH_LIMIT) { + throw new CrewDescriptionException("자유 게시판 내용은 " + CONTENT_LENGTH_LIMIT + "자를 넘을 수 없습니다."); + } + } +} diff --git a/src/main/java/com/retrip/crew/domain/vo/PostTitle.java b/src/main/java/com/retrip/crew/domain/vo/PostTitle.java new file mode 100644 index 0000000..5d2f757 --- /dev/null +++ b/src/main/java/com/retrip/crew/domain/vo/PostTitle.java @@ -0,0 +1,31 @@ +package com.retrip.crew.domain.vo; + +import com.retrip.crew.domain.exception.IntroductionTitleException; +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import lombok.AccessLevel; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Embeddable +@EqualsAndHashCode +@NoArgsConstructor(access = AccessLevel.PROTECTED, force = true) +public class PostTitle { + private static final int TITLE_LENGTH_LIMIT = 20; + + @Column(name = "title", nullable = false, length = TITLE_LENGTH_LIMIT) + private final String value; + + public PostTitle(String value) { + validate(value); + this.value = value; + } + + private void validate(String value) { + if (value.length() > TITLE_LENGTH_LIMIT) { + throw new IntroductionTitleException("자유 게시판 제목은 " + TITLE_LENGTH_LIMIT + "자를 넘을 수 없습니다."); + } + } +} diff --git a/src/main/java/com/retrip/crew/domain/vo/SelfIntroduceBoardContent.java b/src/main/java/com/retrip/crew/domain/vo/SelfIntroduceBoardContent.java deleted file mode 100644 index 1c7b9eb..0000000 --- a/src/main/java/com/retrip/crew/domain/vo/SelfIntroduceBoardContent.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.retrip.crew.domain.vo; - -import jakarta.persistence.Column; -import jakarta.persistence.Embeddable; -import lombok.AccessLevel; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; - -@Getter -@Embeddable -@EqualsAndHashCode -@NoArgsConstructor(access = AccessLevel.PROTECTED, force = true) -public class SelfIntroduceBoardContent { - private static final int TITLE_LENGTH_LIMIT = 30; - private static final int CONTENT_LENGTH_LIMIT = 100; - - @Column(name = "title", nullable = false, length = TITLE_LENGTH_LIMIT) - private final String title; - - @Column(name = "content", nullable = false, length = CONTENT_LENGTH_LIMIT) - private final String content; - - public SelfIntroduceBoardContent(String title, String content) { - validate(title, content); - this.title = title; - this.content = content; - } - - private void validate(String title, String content) { - if (title.length() > TITLE_LENGTH_LIMIT) { - throw new IllegalArgumentException("자기 소개 게시글 제목은 " + TITLE_LENGTH_LIMIT + "자를 넘을 수 없습니다."); - } - if (content.length() > CONTENT_LENGTH_LIMIT) { - throw new IllegalArgumentException("자기 소개 게시글 내용은 " + CONTENT_LENGTH_LIMIT + "자를 넘을 수 없습니다."); - } - } -} diff --git a/src/main/java/com/retrip/crew/infra/adapter/out/gateway/rest/member/MemberClient.java b/src/main/java/com/retrip/crew/infra/adapter/out/gateway/rest/member/MemberClient.java deleted file mode 100644 index c050888..0000000 --- a/src/main/java/com/retrip/crew/infra/adapter/out/gateway/rest/member/MemberClient.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.retrip.crew.infra.adapter.out.gateway.rest.member; - -import com.retrip.crew.infra.adapter.out.gateway.rest.member.response.MemberResponse; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.service.annotation.GetExchange; -import org.springframework.web.service.annotation.HttpExchange; - -import java.util.UUID; - -//@HttpExchange(url = "${apis.urls.member}") -public interface MemberClient { - //@GetExchange("/{memberId}") - MemberResponse getMember(@PathVariable("memberId") UUID memberId); -} diff --git a/src/main/java/com/retrip/crew/infra/adapter/out/gateway/rest/member/MockMemberClient.java b/src/main/java/com/retrip/crew/infra/adapter/out/gateway/rest/member/MockMemberClient.java deleted file mode 100644 index 61393d2..0000000 --- a/src/main/java/com/retrip/crew/infra/adapter/out/gateway/rest/member/MockMemberClient.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.retrip.crew.infra.adapter.out.gateway.rest.member; - -import com.retrip.crew.infra.adapter.out.gateway.rest.member.response.MemberResponse; -import org.springframework.stereotype.Component; - -import java.util.UUID; - -@Component -public class MockMemberClient implements MemberClient { - - @Override - public MemberResponse getMember(UUID memberId) { - return new MemberResponse( - UUID.randomUUID(), - "김준호", - 30, - MemberResponse.GenderResponse.MALE - ); - } -} diff --git a/src/main/java/com/retrip/crew/infra/adapter/out/gateway/rest/member/response/MemberResponse.java b/src/main/java/com/retrip/crew/infra/adapter/out/gateway/rest/member/response/MemberResponse.java deleted file mode 100644 index dfbc9b1..0000000 --- a/src/main/java/com/retrip/crew/infra/adapter/out/gateway/rest/member/response/MemberResponse.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.retrip.crew.infra.adapter.out.gateway.rest.member.response; - - - -import java.util.UUID; - -public record MemberResponse ( - UUID id, - String name, - int age, - GenderResponse gender -){ - public enum GenderResponse{ - MALE, FEMALE - } -} diff --git a/src/test/java/com/retrip/crew/application/in/CrewServiceTest.java b/src/test/java/com/retrip/crew/application/in/CrewServiceTest.java index 2b5490e..df9bf29 100644 --- a/src/test/java/com/retrip/crew/application/in/CrewServiceTest.java +++ b/src/test/java/com/retrip/crew/application/in/CrewServiceTest.java @@ -3,8 +3,6 @@ import com.retrip.crew.application.in.request.CrewCreateRequest; import com.retrip.crew.application.in.response.CrewCreateResponse; import com.retrip.crew.application.out.repository.CrewRepository; -import com.retrip.crew.infra.adapter.out.gateway.rest.member.MemberClient; -import com.retrip.crew.infra.adapter.out.gateway.rest.member.response.MemberResponse; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -15,8 +13,6 @@ import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; @DataJpaTest @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) @@ -24,27 +20,17 @@ class CrewServiceTest { @Autowired CrewRepository crewRepository; - MemberClient memberClient = mock(MemberClient.class); - CrewService crewService; UUID memberId = UUID.randomUUID(); @BeforeEach void setUp() { - crewService = new CrewService(crewRepository, memberClient); + crewService = new CrewService(crewRepository); } @DisplayName("크루를 생성 한다.") @Test void createCrew() { - when(memberClient.getMember(memberId)).thenReturn(new MemberResponse( - memberId, - "김준호", - 30, - MemberResponse.GenderResponse.MALE - )); - - CrewCreateRequest request = new CrewCreateRequest( memberId, "속초 크루원 구함", @@ -53,5 +39,6 @@ void createCrew() { CrewCreateResponse response = crewService.createCrew(request); assertThat(response.id()).isNotNull(); + assertThat(response.leaderId()).isNotNull(); } } diff --git a/src/test/java/com/retrip/crew/domain/vo/CrewContentTest.java b/src/test/java/com/retrip/crew/domain/vo/CrewContentTest.java deleted file mode 100644 index 3b737b3..0000000 --- a/src/test/java/com/retrip/crew/domain/vo/CrewContentTest.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.retrip.crew.domain.vo; - -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; - -class CrewContentTest { - - @Test - @DisplayName("크루 이름은 30자 미만으로 설정해야한다.") - public void validateName() { - assertThatThrownBy(() -> new CrewContent( - "통천, 회양, 평강, 이천, 김화, 철원, 양구, 인제, 고성, 강릉, 속초 등 크루 인원 모집합니다. 다들 오세요", - "강원도 크루 모집합니다.") - ) - .isExactlyInstanceOf(IllegalArgumentException.class); - } - - @Test - @DisplayName("크루 설명은 100자 미만으로 설정해야한다.") - public void validateDescription() { - assertThatThrownBy(() -> new CrewContent( - "춘천 크루 모집 92년생~76년생", - "춘천에서 좋은분들과 식사하고 차도 마시며 살아가는 이야기를 나누는 모임입니다. 등산,낚시,골프,당구,배드민턴, 영화등 다양한 취미활동도 같이 하면서 친분을 쌓고 인맥을 넓히며 춘천에 대한 다양한 정보도 공유하고 진솔한 삶의 의미를 찾을수 있도록 인연을 무엇보다 소중하게 생각하는 모임입니다.\n" + - "\n" + - "지속적으로 모임방이 유지되는 이유는 배려심과 생각이 깊은 많은회원분들이 있기에 춘천의 대표 모임방으로 인정받은게 아닌가 싶습니다. 많은 분들이 오셔서 춘천에서 살아가는 이야기를 나눠 보자구요~\n") - ) - .isExactlyInstanceOf(IllegalArgumentException.class); - } -} diff --git a/src/test/java/com/retrip/crew/domain/vo/CrewIntroductionTitleTest.java b/src/test/java/com/retrip/crew/domain/vo/CrewIntroductionTitleTest.java new file mode 100644 index 0000000..694e249 --- /dev/null +++ b/src/test/java/com/retrip/crew/domain/vo/CrewIntroductionTitleTest.java @@ -0,0 +1,16 @@ +package com.retrip.crew.domain.vo; + +import com.retrip.crew.domain.exception.CrewTitleException; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; + +class CrewIntroductionTitleTest { + + @Test + @DisplayName("크루 이름은 30자 미만으로 설정해야한다.") + public void validateName() { + assertThatThrownBy(() -> new CrewTitle("통천, 회양, 평강, 이천, 김화, 철원, 양구, 인제, 고성, 강릉, 속초 등 크루 인원 모집합니다.")).isExactlyInstanceOf(CrewTitleException.class); + } +} From f4f6890e42485b226b5cb9c1d7a40e1cce5a279f Mon Sep 17 00:00:00 2001 From: junhokim Date: Sun, 23 Feb 2025 14:44:51 +0900 Subject: [PATCH 3/3] =?UTF-8?q?feat:=20=EC=A3=BC=EC=84=9D=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20=EB=B0=8F=20=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/retrip/crew/domain/entity/Announcement.java | 7 ++++++- .../java/com/retrip/crew/domain/entity/Announcements.java | 2 +- .../java/com/retrip/crew/domain/entity/CrewMembers.java | 2 +- .../java/com/retrip/crew/domain/entity/Introductions.java | 2 +- src/main/java/com/retrip/crew/domain/entity/Posts.java | 2 +- src/main/resources/application.yml | 4 ---- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/retrip/crew/domain/entity/Announcement.java b/src/main/java/com/retrip/crew/domain/entity/Announcement.java index 681825d..ca4def9 100644 --- a/src/main/java/com/retrip/crew/domain/entity/Announcement.java +++ b/src/main/java/com/retrip/crew/domain/entity/Announcement.java @@ -1,5 +1,7 @@ package com.retrip.crew.domain.entity; +import com.retrip.crew.domain.vo.AnnouncementContent; +import com.retrip.crew.domain.vo.AnnouncementTitle; import com.retrip.crew.domain.vo.NotificationBoardContent; import jakarta.persistence.*; import lombok.AccessLevel; @@ -17,7 +19,10 @@ public class Announcement extends BaseEntity { private UUID id; @Embedded - private NotificationBoardContent content; + private AnnouncementTitle title; + + @Embedded + private AnnouncementContent content; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn( diff --git a/src/main/java/com/retrip/crew/domain/entity/Announcements.java b/src/main/java/com/retrip/crew/domain/entity/Announcements.java index 652989d..9a85944 100644 --- a/src/main/java/com/retrip/crew/domain/entity/Announcements.java +++ b/src/main/java/com/retrip/crew/domain/entity/Announcements.java @@ -16,7 +16,7 @@ public class Announcements { @OneToMany(mappedBy = "crew", cascade = CascadeType.ALL, orphanRemoval = true) private List values = new ArrayList<>(); - public Announcements() { //리더 생성 + public Announcements() { this.values = createEmptyValues(); } diff --git a/src/main/java/com/retrip/crew/domain/entity/CrewMembers.java b/src/main/java/com/retrip/crew/domain/entity/CrewMembers.java index cabf553..90feba1 100644 --- a/src/main/java/com/retrip/crew/domain/entity/CrewMembers.java +++ b/src/main/java/com/retrip/crew/domain/entity/CrewMembers.java @@ -18,7 +18,7 @@ public class CrewMembers { @OneToMany(mappedBy = "crew", cascade = CascadeType.ALL, orphanRemoval = true) private List values = new ArrayList<>(); - public CrewMembers(Crew crew, UUID member) { //리더 생성 + public CrewMembers(Crew crew, UUID member) { this.values = createLeader(crew, member); } diff --git a/src/main/java/com/retrip/crew/domain/entity/Introductions.java b/src/main/java/com/retrip/crew/domain/entity/Introductions.java index b5d8470..6d269aa 100644 --- a/src/main/java/com/retrip/crew/domain/entity/Introductions.java +++ b/src/main/java/com/retrip/crew/domain/entity/Introductions.java @@ -14,7 +14,7 @@ public class Introductions { @OneToMany(mappedBy = "crew", cascade = CascadeType.ALL, orphanRemoval = true) private List values = new ArrayList<>(); - public Introductions() { //리더 생성 + public Introductions() { this.values = createEmptyValues(); } diff --git a/src/main/java/com/retrip/crew/domain/entity/Posts.java b/src/main/java/com/retrip/crew/domain/entity/Posts.java index 1159c46..39b9b9b 100644 --- a/src/main/java/com/retrip/crew/domain/entity/Posts.java +++ b/src/main/java/com/retrip/crew/domain/entity/Posts.java @@ -16,7 +16,7 @@ public class Posts { @OneToMany(mappedBy = "crew", cascade = CascadeType.ALL, orphanRemoval = true) private List values = new ArrayList<>(); - public Posts() { //리더 생성 + public Posts() { this.values = createEmptyValues(); } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index ca9300c..aafba9a 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -19,7 +19,3 @@ logging: level: org.hibernate.type.descriptor.sql: trace org.springframework.web.client.RestTemplate: DEBUG - -apis: - url: - member: "http://www.naver.com"