From 5369f6fa5002cb47486a47258d6119065995329f Mon Sep 17 00:00:00 2001 From: CodingLeeSeungHoon Date: Mon, 1 Apr 2024 01:57:44 +0900 Subject: [PATCH 1/7] feat : Category domain dev-ing (#49) --- .../starpage/domain/QCategoryId.java | 1 + .../category/domain/Category.java | 61 +++++++++++++++++++ .../domain/CategoryId.java | 6 +- .../category/domain/CategoryStatus.java | 24 ++++++++ ...ConfirmCategoryChangeableAdminService.java | 20 ++++++ .../category/domain/ContentRestriction.java | 39 ++++++++++++ .../category/domain/ContentType.java | 25 ++++++++ .../infra/CategoryStatusConverter.java | 21 +++++++ .../category/infra/ContentTypeConverter.java | 19 ++++++ .../starpage/application/LayoutService.java | 1 + .../domain/CategoricalLayoutLine.java | 1 + .../starpage/domain/StarPage.java | 9 ++- 12 files changed, 223 insertions(+), 4 deletions(-) create mode 100644 needeachother/src/main/java/com/neo/needeachother/category/domain/Category.java rename needeachother/src/main/java/com/neo/needeachother/{starpage => category}/domain/CategoryId.java (74%) create mode 100644 needeachother/src/main/java/com/neo/needeachother/category/domain/CategoryStatus.java create mode 100644 needeachother/src/main/java/com/neo/needeachother/category/domain/ConfirmCategoryChangeableAdminService.java create mode 100644 needeachother/src/main/java/com/neo/needeachother/category/domain/ContentRestriction.java create mode 100644 needeachother/src/main/java/com/neo/needeachother/category/domain/ContentType.java create mode 100644 needeachother/src/main/java/com/neo/needeachother/category/infra/CategoryStatusConverter.java create mode 100644 needeachother/src/main/java/com/neo/needeachother/category/infra/ContentTypeConverter.java diff --git a/needeachother/src/main/generated/com/neo/needeachother/starpage/domain/QCategoryId.java b/needeachother/src/main/generated/com/neo/needeachother/starpage/domain/QCategoryId.java index 69f6470..ac33447 100644 --- a/needeachother/src/main/generated/com/neo/needeachother/starpage/domain/QCategoryId.java +++ b/needeachother/src/main/generated/com/neo/needeachother/starpage/domain/QCategoryId.java @@ -2,6 +2,7 @@ import static com.querydsl.core.types.PathMetadataFactory.*; +import com.neo.needeachother.category.domain.CategoryId; import com.querydsl.core.types.dsl.*; import com.querydsl.core.types.PathMetadata; diff --git a/needeachother/src/main/java/com/neo/needeachother/category/domain/Category.java b/needeachother/src/main/java/com/neo/needeachother/category/domain/Category.java new file mode 100644 index 0000000..dbef924 --- /dev/null +++ b/needeachother/src/main/java/com/neo/needeachother/category/domain/Category.java @@ -0,0 +1,61 @@ +package com.neo.needeachother.category.domain; + +import com.neo.needeachother.category.infra.CategoryStatusConverter; +import com.neo.needeachother.category.infra.ContentTypeConverter; +import com.neo.needeachother.starpage.domain.StarPageId; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.NoArgsConstructor; + +@Entity +@Table(name = "neo_starpage_category") +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Category { + + @EmbeddedId + private CategoryId categoryId; + + @Column(name = "starpage_id") + private StarPageId starPageId; + + @Column(name = "category_status") + @Convert(converter = CategoryStatusConverter.class) + private CategoryStatus categoryStatus; + + @Column(name = "content_type") + @Convert(converter = ContentTypeConverter.class) + private ContentType contentType; + + @Embedded + @AttributeOverrides({ + @AttributeOverride(name = "onlyHostWriteContent", column = @Column(name = "only_host_write_content")), + @AttributeOverride(name = "isWriteAbleComment", column = @Column(name = "comment_writeable")), + @AttributeOverride(name = "useCommentRatingFilter", column = @Column(name = "comment_rating_filter")), + @AttributeOverride(name = "filteringRate", column = @Column(name = "filter_rate")), + }) + private ContentRestriction restriction; + + // 도메인 : 이 카테고리가 속한 스타페이지의 관리자에 해당하는 자만 카테고리를 변경할 수 있다. + private void isChangeAble(ConfirmCategoryChangeableAdminService confirmService, String email) { + confirmService.isChangeableCategoryBy(email, this.starPageId); + } + + // 도메인 : 삭제한 카테고리를 다시 되살릴 수 있다. + public void reOpenCategory(ConfirmCategoryChangeableAdminService confirmService, String email) { + // 요청자가 카테고리를 변경할 수 있는 권한이 있는지 확인 후 상태 변경 + isChangeAble(confirmService, email); + this.categoryStatus = CategoryStatus.OPEN; + // TODO : 카테고리 상태 변경 -> 이벤트 발생 -> 해당 카테고리 내의 포스트 Deleted 상태를 모두 OPEN으로 일괄 변경. + } + + // 도메인 : 생성한 카테고리를 삭제할 수 있다. + public void deleteCategory(ConfirmCategoryChangeableAdminService confirmService, String email) { + // 요청자가 카테고리를 변경할 수 있는 권한이 있는지 확인 후 상태 변경 + isChangeAble(confirmService, email); + this.categoryStatus = CategoryStatus.DELETED; + // TODO : 카테고리 상태 변경 -> 이벤트 발생 -> 해당 카테고리 내의 포스트를 모두 Deleted 상태로 일괄 변경 + } + +} diff --git a/needeachother/src/main/java/com/neo/needeachother/starpage/domain/CategoryId.java b/needeachother/src/main/java/com/neo/needeachother/category/domain/CategoryId.java similarity index 74% rename from needeachother/src/main/java/com/neo/needeachother/starpage/domain/CategoryId.java rename to needeachother/src/main/java/com/neo/needeachother/category/domain/CategoryId.java index 16d6694..5e51f49 100644 --- a/needeachother/src/main/java/com/neo/needeachother/starpage/domain/CategoryId.java +++ b/needeachother/src/main/java/com/neo/needeachother/category/domain/CategoryId.java @@ -1,4 +1,4 @@ -package com.neo.needeachother.starpage.domain; +package com.neo.needeachother.category.domain; import jakarta.persistence.Embeddable; import lombok.AccessLevel; @@ -6,11 +6,13 @@ import lombok.Getter; import lombok.NoArgsConstructor; +import java.io.Serializable; + @Getter @Embeddable @AllArgsConstructor @NoArgsConstructor(access = AccessLevel.PROTECTED) -public class CategoryId { +public class CategoryId implements Serializable { private String value; public static CategoryId of(String value){ diff --git a/needeachother/src/main/java/com/neo/needeachother/category/domain/CategoryStatus.java b/needeachother/src/main/java/com/neo/needeachother/category/domain/CategoryStatus.java new file mode 100644 index 0000000..773ec2d --- /dev/null +++ b/needeachother/src/main/java/com/neo/needeachother/category/domain/CategoryStatus.java @@ -0,0 +1,24 @@ +package com.neo.needeachother.category.domain; + +import com.neo.needeachother.common.exception.NEOUnexpectedException; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; + +@Getter +@RequiredArgsConstructor +public enum CategoryStatus { + OPEN("O"), + EXPOSURE("E"), + DELETED("D"); + + private final String categorySummarizedSymbol; + + public static CategoryStatus convertToCategoryStatus(String dbSymbol){ + return Arrays.stream(CategoryStatus.values()) + .filter(categoryStatus -> categoryStatus.getCategorySummarizedSymbol().equals(dbSymbol)) + .findAny() + .orElseThrow(() -> new NEOUnexpectedException("경고 : 정상적이지 않은 카테고리 상테 심볼이 DB에 저장")); + } +} diff --git a/needeachother/src/main/java/com/neo/needeachother/category/domain/ConfirmCategoryChangeableAdminService.java b/needeachother/src/main/java/com/neo/needeachother/category/domain/ConfirmCategoryChangeableAdminService.java new file mode 100644 index 0000000..9d26a1d --- /dev/null +++ b/needeachother/src/main/java/com/neo/needeachother/category/domain/ConfirmCategoryChangeableAdminService.java @@ -0,0 +1,20 @@ +package com.neo.needeachother.category.domain; + +import com.neo.needeachother.starpage.domain.NEOMember; +import com.neo.needeachother.starpage.domain.StarPage; +import com.neo.needeachother.starpage.domain.StarPageId; +import com.neo.needeachother.starpage.domain.repository.StarPageRepository; +import static com.neo.needeachother.starpage.application.StarPageServiceHelper.*; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class ConfirmCategoryChangeableAdminService { + + private final StarPageRepository starPageRepository; + + public boolean isChangeableCategoryBy(String email, StarPageId starPageId){ + StarPage foundStarPage = findExistingStarPage(starPageRepository, starPageId); + foundStarPage.isChangeableBy(NEOMember.of(email)); + return true; + } +} diff --git a/needeachother/src/main/java/com/neo/needeachother/category/domain/ContentRestriction.java b/needeachother/src/main/java/com/neo/needeachother/category/domain/ContentRestriction.java new file mode 100644 index 0000000..009c548 --- /dev/null +++ b/needeachother/src/main/java/com/neo/needeachother/category/domain/ContentRestriction.java @@ -0,0 +1,39 @@ +package com.neo.needeachother.category.domain; + +import com.neo.needeachother.common.exception.NEOUnexpectedException; +import jakarta.persistence.Embeddable; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Embeddable +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ContentRestriction { + + // 제약 사항 : 컨텐츠를 호스트만 작성 가능 ? 팬도 작성가능 + private boolean onlyHostWriteContent; + + // 제약 사항 : 댓글 제한 ? 댓글 가능 + private boolean isWriteAbleComment; + + // 제약 사항 : 댓글 필터링 여부 (팬에게는 모두 보이고, 호스트에게는 일정 수 이상의 댓글만 보여짐.) + private boolean useCommentRatingFilter; + + // 제약 사항 : 필터링 비율(0~100, 정수) + private int filteringRate; + + private boolean isOutOfFilteringRateBound(int filteringRate){ + return 0 > filteringRate || filteringRate > 100; + } + + public void changeFilteringRate(int filteringRate){ + if(isOutOfFilteringRateBound(filteringRate)){ + throw new NEOUnexpectedException("정상적인 필터링 비율 정수 범위가 아님"); + } + this.filteringRate = filteringRate; + } + +} diff --git a/needeachother/src/main/java/com/neo/needeachother/category/domain/ContentType.java b/needeachother/src/main/java/com/neo/needeachother/category/domain/ContentType.java new file mode 100644 index 0000000..8be1521 --- /dev/null +++ b/needeachother/src/main/java/com/neo/needeachother/category/domain/ContentType.java @@ -0,0 +1,25 @@ +package com.neo.needeachother.category.domain; + +import com.neo.needeachother.common.exception.NEOUnexpectedException; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import java.util.Arrays; + +@Getter +@RequiredArgsConstructor +public enum ContentType { + COMMON("C"), + ALBUM("A"), + OX("OX"), + VOTE("V"); + + private final String contentTypeSummarizedSymbol; + + public static ContentType convertToContentType(String dbSymbol){ + return Arrays.stream(ContentType.values()) + .filter(contentType -> contentType.getContentTypeSummarizedSymbol().equals(dbSymbol)) + .findAny() + .orElseThrow(() -> new NEOUnexpectedException("경고 : 예상하지 못한 카테고리 컨텐츠 타입값이 저장됨")); + } +} diff --git a/needeachother/src/main/java/com/neo/needeachother/category/infra/CategoryStatusConverter.java b/needeachother/src/main/java/com/neo/needeachother/category/infra/CategoryStatusConverter.java new file mode 100644 index 0000000..864ab3c --- /dev/null +++ b/needeachother/src/main/java/com/neo/needeachother/category/infra/CategoryStatusConverter.java @@ -0,0 +1,21 @@ +package com.neo.needeachother.category.infra; + +import com.neo.needeachother.category.domain.CategoryStatus; +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; + +@Converter +public class CategoryStatusConverter implements AttributeConverter { + + @Override + public String convertToDatabaseColumn(CategoryStatus attribute) { + return attribute.getCategorySummarizedSymbol(); + } + + @Override + public CategoryStatus convertToEntityAttribute(String dbData) { + return CategoryStatus.convertToCategoryStatus(dbData); + } + +} + diff --git a/needeachother/src/main/java/com/neo/needeachother/category/infra/ContentTypeConverter.java b/needeachother/src/main/java/com/neo/needeachother/category/infra/ContentTypeConverter.java new file mode 100644 index 0000000..25627d8 --- /dev/null +++ b/needeachother/src/main/java/com/neo/needeachother/category/infra/ContentTypeConverter.java @@ -0,0 +1,19 @@ +package com.neo.needeachother.category.infra; + +import com.neo.needeachother.category.domain.ContentType; +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.Converter; + +@Converter +public class ContentTypeConverter implements AttributeConverter { + + @Override + public String convertToDatabaseColumn(ContentType attribute) { + return attribute.getContentTypeSummarizedSymbol(); + } + + @Override + public ContentType convertToEntityAttribute(String dbData) { + return ContentType.convertToContentType(dbData); + } +} diff --git a/needeachother/src/main/java/com/neo/needeachother/starpage/application/LayoutService.java b/needeachother/src/main/java/com/neo/needeachother/starpage/application/LayoutService.java index 0b8c4f3..5039967 100644 --- a/needeachother/src/main/java/com/neo/needeachother/starpage/application/LayoutService.java +++ b/needeachother/src/main/java/com/neo/needeachother/starpage/application/LayoutService.java @@ -1,5 +1,6 @@ package com.neo.needeachother.starpage.application; +import com.neo.needeachother.category.domain.CategoryId; import com.neo.needeachother.starpage.domain.*; import com.neo.needeachother.starpage.domain.repository.StarPageRepository; import lombok.RequiredArgsConstructor; diff --git a/needeachother/src/main/java/com/neo/needeachother/starpage/domain/CategoricalLayoutLine.java b/needeachother/src/main/java/com/neo/needeachother/starpage/domain/CategoricalLayoutLine.java index c521672..21a7678 100644 --- a/needeachother/src/main/java/com/neo/needeachother/starpage/domain/CategoricalLayoutLine.java +++ b/needeachother/src/main/java/com/neo/needeachother/starpage/domain/CategoricalLayoutLine.java @@ -1,5 +1,6 @@ package com.neo.needeachother.starpage.domain; +import com.neo.needeachother.category.domain.CategoryId; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Getter; diff --git a/needeachother/src/main/java/com/neo/needeachother/starpage/domain/StarPage.java b/needeachother/src/main/java/com/neo/needeachother/starpage/domain/StarPage.java index b442e0f..2afbf5d 100644 --- a/needeachother/src/main/java/com/neo/needeachother/starpage/domain/StarPage.java +++ b/needeachother/src/main/java/com/neo/needeachother/starpage/domain/StarPage.java @@ -1,5 +1,6 @@ package com.neo.needeachother.starpage.domain; +import com.neo.needeachother.category.domain.Category; import com.neo.needeachother.common.enums.NEODomainType; import com.neo.needeachother.common.enums.NEOErrorCode; import com.neo.needeachother.common.event.Events; @@ -122,7 +123,7 @@ public void changeStarPageIntroduction(NEOMember member, StarPageIntroduction ne } // 도메인 : 스타페이지 관리자만 스타페이지를 변경할 수 있다. - private void isChangeableBy(NEOMember member) { + public void isChangeableBy(NEOMember member) { if (!this.admins.contains(member)) { throw new NEOExpectedException(NEODomainType.STARPAGE, NEOErrorCode.NOT_ADMIN_THIS_STARPAGE, @@ -215,8 +216,12 @@ private List getStarPageUniqueLayoutLinesAddList( return Collections.unmodifiableList(modifiedLayoutLines); } + // 도메인 : 스타페이지로 하여금 카테고리를 생성할 수 있다. (팩토리) + public Category createCategory(){ + return null; + } - // 도메인 : 스타페이지를 새롭게 생성할 수 있다. + // 도메인 : 스타페이지를 새롭게 생성할 수 있다. (정적 팩토리) public static StarPage create(String starNickName, String email, Set starTypeSet, List snsLines, String starPageIntroduce) { From fb51d1b2996d9695ffcd2e8e1cc2f28bf06ee51c Mon Sep 17 00:00:00 2001 From: Seung Hoon Lee Date: Mon, 1 Apr 2024 16:02:02 +0900 Subject: [PATCH 2/7] =?UTF-8?q?NEO=20Category=20DDD=20Design.drawio?= =?UTF-8?q?=EC=9D=B4=20=EC=B6=94=EA=B0=80=EB=90=98=EC=97=88=EC=8A=B5?= =?UTF-8?q?=EB=8B=88=EB=8B=A4.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NEO Category DDD Design.drawio | 124 +++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 NEO Category DDD Design.drawio diff --git a/NEO Category DDD Design.drawio b/NEO Category DDD Design.drawio new file mode 100644 index 0000000..f5c14fd --- /dev/null +++ b/NEO Category DDD Design.drawio @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 5ab34125642ac6a5c55dc85cfb5d1ec42c69ca4a Mon Sep 17 00:00:00 2001 From: Seung Hoon Lee Date: Mon, 1 Apr 2024 17:42:55 +0900 Subject: [PATCH 3/7] =?UTF-8?q?NEO=20Category=20DDD=20Design.drawio=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NEO Category DDD Design.drawio | 313 +++++++++++++++++++++++++-------- 1 file changed, 238 insertions(+), 75 deletions(-) diff --git a/NEO Category DDD Design.drawio b/NEO Category DDD Design.drawio index f5c14fd..0396501 100644 --- a/NEO Category DDD Design.drawio +++ b/NEO Category DDD Design.drawio @@ -1,123 +1,286 @@ - + - + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - + + + + + + + + - - + + - - + + - - + + - - + + - - + + + + + + + + + + + + + + + + + + + + - - + + - - + + - - + + - - + + - - - - + + + + + + + + + + + + - - - + + + + + + + + + + + + - - + + - - + + - - - - + + + + + + - - - + + + + + + + + + + + + - - + + - - + + + + + + + + - - + + + + - - + + - - + + + + - - + + - - + + + + + - - + + + + + - - - - - + + + - - - + + + + + + + + + - - - + + + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 39c2edd2c1b7ed34dfce0858bec6b8e7d2d4096d Mon Sep 17 00:00:00 2001 From: Seung Hoon Lee Date: Mon, 1 Apr 2024 17:43:31 +0900 Subject: [PATCH 4/7] =?UTF-8?q?NEO=20Category=20DDD=20Design.drawio=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NEO Category DDD Design.drawio | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEO Category DDD Design.drawio b/NEO Category DDD Design.drawio index 0396501..d8ca18c 100644 --- a/NEO Category DDD Design.drawio +++ b/NEO Category DDD Design.drawio @@ -1,4 +1,4 @@ - + From dec28a96030b3e15f0f319742cbb38753b2cc753 Mon Sep 17 00:00:00 2001 From: CodingLeeSeungHoon Date: Tue, 2 Apr 2024 19:05:47 +0900 Subject: [PATCH 5/7] =?UTF-8?q?feat=20:=20starpage=20created=20event=20log?= =?UTF-8?q?ic=20=EA=B5=AC=ED=98=84.=20->=20=EA=B8=B0=EB=B3=B8=20=EC=B9=B4?= =?UTF-8?q?=ED=85=8C=EA=B3=A0=EB=A6=AC=204=EC=A2=85=20=EC=83=9D=EC=84=B1?= =?UTF-8?q?=20(#49)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/CategoryServiceHelper.java | 12 ++ .../InitialCategoryCreationService.java | 36 ++++++ .../ModifyCategoryStatusService.java | 32 +++++ .../StarPageCreatedEventListener.java | 19 +++ .../category/domain/Category.java | 110 +++++++++++++++++- .../category/domain/CategoryId.java | 6 +- .../category/domain/CategoryInformation.java | 24 ++++ .../category/domain/CategoryStatus.java | 1 + .../category/domain/ContentRestriction.java | 45 +++++-- .../category/domain/ContentType.java | 14 ++- .../category/domain/InitCategory.java | 16 +++ ...ConfirmCategoryChangeableAdminService.java | 2 +- .../repository/CategoryCustomRepository.java | 8 ++ .../domain/repository/CategoryRepository.java | 8 ++ .../infra/CategoryCustomRepositoryImpl.java | 24 ++++ .../application/CreateStarPageService.java | 5 +- .../starpage/domain/StarPage.java | 52 +++++++-- .../starpage/domain/StarPageId.java | 5 + .../CreateCategoryFromStarPageService.java | 18 +++ .../domain/event/StarPageCreatedEvent.java | 7 ++ .../repository/StarPageCustomRepository.java | 4 + .../domain/repository/StarPageRepository.java | 1 + .../infra/StarPageCustomRepositoryImpl.java | 7 ++ .../starpage/domain/StarPageTest.java | 8 -- 24 files changed, 428 insertions(+), 36 deletions(-) create mode 100644 needeachother/src/main/java/com/neo/needeachother/category/application/CategoryServiceHelper.java create mode 100644 needeachother/src/main/java/com/neo/needeachother/category/application/InitialCategoryCreationService.java create mode 100644 needeachother/src/main/java/com/neo/needeachother/category/application/ModifyCategoryStatusService.java create mode 100644 needeachother/src/main/java/com/neo/needeachother/category/application/StarPageCreatedEventListener.java create mode 100644 needeachother/src/main/java/com/neo/needeachother/category/domain/CategoryInformation.java create mode 100644 needeachother/src/main/java/com/neo/needeachother/category/domain/InitCategory.java rename needeachother/src/main/java/com/neo/needeachother/category/domain/{ => domainservice}/ConfirmCategoryChangeableAdminService.java (92%) create mode 100644 needeachother/src/main/java/com/neo/needeachother/category/domain/repository/CategoryCustomRepository.java create mode 100644 needeachother/src/main/java/com/neo/needeachother/category/domain/repository/CategoryRepository.java create mode 100644 needeachother/src/main/java/com/neo/needeachother/category/infra/CategoryCustomRepositoryImpl.java create mode 100644 needeachother/src/main/java/com/neo/needeachother/starpage/domain/domainservice/CreateCategoryFromStarPageService.java diff --git a/needeachother/src/main/java/com/neo/needeachother/category/application/CategoryServiceHelper.java b/needeachother/src/main/java/com/neo/needeachother/category/application/CategoryServiceHelper.java new file mode 100644 index 0000000..42eba82 --- /dev/null +++ b/needeachother/src/main/java/com/neo/needeachother/category/application/CategoryServiceHelper.java @@ -0,0 +1,12 @@ +package com.neo.needeachother.category.application; + +import com.neo.needeachother.category.domain.Category; +import com.neo.needeachother.category.domain.CategoryId; +import com.neo.needeachother.category.domain.repository.CategoryRepository; + +public final class CategoryServiceHelper { + public static Category findExistingCategory(CategoryRepository repo, CategoryId categoryId){ + return repo.findById(categoryId) + .orElseThrow(); + } +} diff --git a/needeachother/src/main/java/com/neo/needeachother/category/application/InitialCategoryCreationService.java b/needeachother/src/main/java/com/neo/needeachother/category/application/InitialCategoryCreationService.java new file mode 100644 index 0000000..416d447 --- /dev/null +++ b/needeachother/src/main/java/com/neo/needeachother/category/application/InitialCategoryCreationService.java @@ -0,0 +1,36 @@ +package com.neo.needeachother.category.application; + +import com.neo.needeachother.category.domain.Category; +import com.neo.needeachother.category.domain.ContentType; +import com.neo.needeachother.category.domain.InitCategory; +import com.neo.needeachother.category.domain.repository.CategoryRepository; +import com.neo.needeachother.starpage.domain.StarPageId; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + + +@Service +@RequiredArgsConstructor +public class InitialCategoryCreationService { + + private final CategoryRepository categoryRepository; + + @Transactional(propagation = Propagation.REQUIRES_NEW) + public void createInitialCategory(StarPageId starPageId) { + List createdInitialCategory = Category.getInitialCategoryByStarPageId( + Arrays.stream(InitCategory.values()) + .map(InitCategory::getContentType) + .map(categoryRepository::getNextId) + .collect(Collectors.toList()), + starPageId); + + categoryRepository.saveAll(createdInitialCategory); + } + +} diff --git a/needeachother/src/main/java/com/neo/needeachother/category/application/ModifyCategoryStatusService.java b/needeachother/src/main/java/com/neo/needeachother/category/application/ModifyCategoryStatusService.java new file mode 100644 index 0000000..ca0953f --- /dev/null +++ b/needeachother/src/main/java/com/neo/needeachother/category/application/ModifyCategoryStatusService.java @@ -0,0 +1,32 @@ +package com.neo.needeachother.category.application; + +import com.neo.needeachother.category.domain.Category; +import com.neo.needeachother.category.domain.CategoryId; +import com.neo.needeachother.category.domain.domainservice.ConfirmCategoryChangeableAdminService; +import com.neo.needeachother.category.domain.repository.CategoryRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import static com.neo.needeachother.category.application.CategoryServiceHelper.*; + +@Service +@RequiredArgsConstructor +public class ModifyCategoryStatusService { + + private final CategoryRepository categoryRepository; + private final ConfirmCategoryChangeableAdminService confirmCategoryChangeableAdminService; + + @Transactional + public void reOpenCategory(CategoryId id, String email){ + Category foundCategory = findExistingCategory(categoryRepository, id); + foundCategory.reOpenCategory(confirmCategoryChangeableAdminService, email); + } + + @Transactional + public void deleteCategory(CategoryId id, String email){ + Category foundCategory = findExistingCategory(categoryRepository, id); + foundCategory.deleteCategory(confirmCategoryChangeableAdminService, email); + } + +} diff --git a/needeachother/src/main/java/com/neo/needeachother/category/application/StarPageCreatedEventListener.java b/needeachother/src/main/java/com/neo/needeachother/category/application/StarPageCreatedEventListener.java new file mode 100644 index 0000000..9629ea2 --- /dev/null +++ b/needeachother/src/main/java/com/neo/needeachother/category/application/StarPageCreatedEventListener.java @@ -0,0 +1,19 @@ +package com.neo.needeachother.category.application; + +import com.neo.needeachother.starpage.domain.event.StarPageCreatedEvent; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; +import org.springframework.transaction.event.TransactionPhase; +import org.springframework.transaction.event.TransactionalEventListener; + +@Component +@RequiredArgsConstructor +public class StarPageCreatedEventListener { + + private final InitialCategoryCreationService initialCategoryCreationService; + + @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT) + public void onApplicationEvent(StarPageCreatedEvent starPageCreatedEvent) { + initialCategoryCreationService.createInitialCategory(starPageCreatedEvent.getCreatedStarPageId()); + } +} diff --git a/needeachother/src/main/java/com/neo/needeachother/category/domain/Category.java b/needeachother/src/main/java/com/neo/needeachother/category/domain/Category.java index dbef924..695716d 100644 --- a/needeachother/src/main/java/com/neo/needeachother/category/domain/Category.java +++ b/needeachother/src/main/java/com/neo/needeachother/category/domain/Category.java @@ -1,13 +1,19 @@ package com.neo.needeachother.category.domain; +import com.neo.needeachother.category.domain.domainservice.ConfirmCategoryChangeableAdminService; import com.neo.needeachother.category.infra.CategoryStatusConverter; import com.neo.needeachother.category.infra.ContentTypeConverter; +import com.neo.needeachother.common.exception.NEOUnexpectedException; import com.neo.needeachother.starpage.domain.StarPageId; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.NoArgsConstructor; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; + @Entity @Table(name = "neo_starpage_category") @AllArgsConstructor @@ -28,6 +34,10 @@ public class Category { @Convert(converter = ContentTypeConverter.class) private ContentType contentType; + @Embedded + @AttributeOverride(name = "categoryTitle", column = @Column(name = "title")) + private CategoryInformation categoryInformation; + @Embedded @AttributeOverrides({ @AttributeOverride(name = "onlyHostWriteContent", column = @Column(name = "only_host_write_content")), @@ -42,6 +52,15 @@ private void isChangeAble(ConfirmCategoryChangeableAdminService confirmService, confirmService.isChangeableCategoryBy(email, this.starPageId); } + // 도메인 : 이 카테고리가 속한 스타페이지의 관리자에 해당하는 자만 카테고리를 삭제할 수 있으며 + // 스타페이지 메인화면에 노출중이라면 삭제할 수 없다. + private void isRemoveAble(ConfirmCategoryChangeableAdminService confirmService, String email) { + isChangeAble(confirmService, email); + if (this.categoryStatus == CategoryStatus.EXPOSURE) { + throw new NEOUnexpectedException("스타페이지 메인화면에 노출중인 카테고리는 삭제할 수 없음."); + } + } + // 도메인 : 삭제한 카테고리를 다시 되살릴 수 있다. public void reOpenCategory(ConfirmCategoryChangeableAdminService confirmService, String email) { // 요청자가 카테고리를 변경할 수 있는 권한이 있는지 확인 후 상태 변경 @@ -53,9 +72,98 @@ public void reOpenCategory(ConfirmCategoryChangeableAdminService confirmService, // 도메인 : 생성한 카테고리를 삭제할 수 있다. public void deleteCategory(ConfirmCategoryChangeableAdminService confirmService, String email) { // 요청자가 카테고리를 변경할 수 있는 권한이 있는지 확인 후 상태 변경 - isChangeAble(confirmService, email); + isRemoveAble(confirmService, email); this.categoryStatus = CategoryStatus.DELETED; // TODO : 카테고리 상태 변경 -> 이벤트 발생 -> 해당 카테고리 내의 포스트를 모두 Deleted 상태로 일괄 변경 } + // 도메인 : 카테고리를 스타페이지 메인 화면에 노출시킬 수 있다. + public void exposureCategory(ConfirmCategoryChangeableAdminService confirmService, String email) { + isRemoveAble(confirmService, email); + this.categoryStatus = CategoryStatus.EXPOSURE; + } + + // 도메인 : 기존의 카테고리 이름을 변경할 수 있다. + public void modifyCategoryTitle(ConfirmCategoryChangeableAdminService confirmService, + String email, String modifyingTitle) { + isChangeAble(confirmService, email); + this.categoryInformation = Stream.of(modifyingTitle) + .map(this.categoryInformation::changeCategoryTitle) + .filter(categoryInfo -> !categoryInfo.equals(this.categoryInformation)) + .findAny() + .orElseThrow(() -> new NEOUnexpectedException("변경 후 카테고리의 이름이 이전과 동일합니다.")); + } + + // 도메인 : 상위 N%의 댓글만 호스트에게 보여주는 지지투표 비율을 조정할 수 있다. (팬은 모두 보임.) + public void modifyFilteringRate(ConfirmCategoryChangeableAdminService confirmService, + String email, int filteringRate) { + isChangeAble(confirmService, email); + this.restriction = Stream.of(filteringRate) + .map(this.restriction::changeFilteringRate) + .findAny() + .orElseThrow(); + } + + // 도메인 : 댓글 지짖투표 기능을 켤 수 있다. + public void turnOnCommentRatingFilter(ConfirmCategoryChangeableAdminService confirmService, + String email) { + isChangeAble(confirmService, email); + this.restriction = this.restriction.turnOnCommentRatingFilter(); + } + + // 도메인 : 댓글 지지투표 기능을 끌 수 있다. + public void turnOffCommentRatingFilter(ConfirmCategoryChangeableAdminService confirmService, + String email) { + isChangeAble(confirmService, email); + this.restriction = this.restriction.turnOffCommentRatingFilter(); + } + + // 도메인 : 스타페이지가 생성될 때 초기 카테고리 4가지를 자동 생성하게 된다. + public static List getInitialCategoryByStarPageId(List categoryIds, StarPageId id) { + checkInitialCategoryId(categoryIds); + return List.of(createNoticeCategory(categoryIds.get(InitCategory.NOTICE.ordinal()), id), + createFreeBoardCategory(categoryIds.get(InitCategory.FREE_BOARD.ordinal()), id), + createSelfiCategory(categoryIds.get(InitCategory.SELFI.ordinal()), id), + createFreeAlbumCategory(categoryIds.get(InitCategory.FREE_ALBUM.ordinal()), id)); + } + + private static void checkInitialCategoryId(List categoryIds) { + Arrays.stream(InitCategory.values()) + .map(initCategory -> List.of(categoryIds.get(initCategory.ordinal()).getValue().split("_")[0], + initCategory.getContentType().getPrefixCategoryId())) + .filter(idAndPrefixList -> !idAndPrefixList.get(0).equals(idAndPrefixList.get(1))) + .findAny() + .ifPresent(l -> { + throw new NEOUnexpectedException(""); + }); + } + + private static Category createNoticeCategory(CategoryId categoryId, StarPageId starPageId) { + return new Category(categoryId, starPageId, CategoryStatus.OPEN, + InitCategory.NOTICE.getContentType(), + CategoryInformation.of(InitCategory.NOTICE.getKoreanTitle()), + ContentRestriction.onlyHostWriteContentAndAllCanWriteComment()); + } + + private static Category createFreeBoardCategory(CategoryId categoryId, StarPageId starPageId) { + return new Category(categoryId, starPageId, CategoryStatus.OPEN, + InitCategory.FREE_BOARD.getContentType(), + CategoryInformation.of(InitCategory.FREE_BOARD.getKoreanTitle()), + ContentRestriction.onlyHostWriteContentAndAllCanWriteComment()); + } + + private static Category createSelfiCategory(CategoryId categoryId, StarPageId starPageId) { + return new Category(categoryId, starPageId, CategoryStatus.OPEN, + InitCategory.SELFI.getContentType(), + CategoryInformation.of(InitCategory.SELFI.getKoreanTitle()), + ContentRestriction.onlyHostWriteContentAndAllCanWriteComment()); + } + + private static Category createFreeAlbumCategory(CategoryId categoryId, StarPageId starPageId) { + return new Category(categoryId, starPageId, CategoryStatus.OPEN, + InitCategory.FREE_ALBUM.getContentType(), + CategoryInformation.of(InitCategory.FREE_ALBUM.getKoreanTitle()), + ContentRestriction.onlyHostWriteContentAndAllCanWriteComment()); + } + } diff --git a/needeachother/src/main/java/com/neo/needeachother/category/domain/CategoryId.java b/needeachother/src/main/java/com/neo/needeachother/category/domain/CategoryId.java index 5e51f49..7138f35 100644 --- a/needeachother/src/main/java/com/neo/needeachother/category/domain/CategoryId.java +++ b/needeachother/src/main/java/com/neo/needeachother/category/domain/CategoryId.java @@ -1,15 +1,13 @@ package com.neo.needeachother.category.domain; import jakarta.persistence.Embeddable; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.*; import java.io.Serializable; @Getter @Embeddable +@EqualsAndHashCode @AllArgsConstructor @NoArgsConstructor(access = AccessLevel.PROTECTED) public class CategoryId implements Serializable { diff --git a/needeachother/src/main/java/com/neo/needeachother/category/domain/CategoryInformation.java b/needeachother/src/main/java/com/neo/needeachother/category/domain/CategoryInformation.java new file mode 100644 index 0000000..9921905 --- /dev/null +++ b/needeachother/src/main/java/com/neo/needeachother/category/domain/CategoryInformation.java @@ -0,0 +1,24 @@ +package com.neo.needeachother.category.domain; + +import com.neo.needeachother.common.exception.NEOUnexpectedException; +import jakarta.persistence.Embeddable; +import lombok.*; + +@Getter +@Embeddable +@EqualsAndHashCode +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class CategoryInformation { + + private String categoryTitle; + + // 도메인 : 카테고리의 제목을 변경할 수 있다. + protected CategoryInformation changeCategoryTitle(String categoryTitle){ + return new CategoryInformation(categoryTitle); + } + + public static CategoryInformation of(String title){ + return new CategoryInformation(title); + } +} diff --git a/needeachother/src/main/java/com/neo/needeachother/category/domain/CategoryStatus.java b/needeachother/src/main/java/com/neo/needeachother/category/domain/CategoryStatus.java index 773ec2d..cd8d39d 100644 --- a/needeachother/src/main/java/com/neo/needeachother/category/domain/CategoryStatus.java +++ b/needeachother/src/main/java/com/neo/needeachother/category/domain/CategoryStatus.java @@ -13,6 +13,7 @@ public enum CategoryStatus { EXPOSURE("E"), DELETED("D"); + // 카테고리의 상태 요약 심볼(DB 저장 데이터) private final String categorySummarizedSymbol; public static CategoryStatus convertToCategoryStatus(String dbSymbol){ diff --git a/needeachother/src/main/java/com/neo/needeachother/category/domain/ContentRestriction.java b/needeachother/src/main/java/com/neo/needeachother/category/domain/ContentRestriction.java index 009c548..0f9d1e2 100644 --- a/needeachother/src/main/java/com/neo/needeachother/category/domain/ContentRestriction.java +++ b/needeachother/src/main/java/com/neo/needeachother/category/domain/ContentRestriction.java @@ -2,13 +2,11 @@ import com.neo.needeachother.common.exception.NEOUnexpectedException; import jakarta.persistence.Embeddable; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.*; @Getter @Embeddable +@EqualsAndHashCode @AllArgsConstructor @NoArgsConstructor(access = AccessLevel.PROTECTED) public class ContentRestriction { @@ -25,15 +23,46 @@ public class ContentRestriction { // 제약 사항 : 필터링 비율(0~100, 정수) private int filteringRate; - private boolean isOutOfFilteringRateBound(int filteringRate){ + // 도메인 : 필터링 비율은 0~100 정수 범위다. + private boolean isOutOfFilteringRateBound(int filteringRate) { return 0 > filteringRate || filteringRate > 100; } - public void changeFilteringRate(int filteringRate){ - if(isOutOfFilteringRateBound(filteringRate)){ + // 도메인 : 필터링 비율을 변경할 수 있다. + protected ContentRestriction changeFilteringRate(int filteringRate) { + if (isOutOfFilteringRateBound(filteringRate)) { throw new NEOUnexpectedException("정상적인 필터링 비율 정수 범위가 아님"); } - this.filteringRate = filteringRate; + return ContentRestriction.of(this.onlyHostWriteContent, + this.isWriteAbleComment, + this.useCommentRatingFilter, + filteringRate); } + // 도메인 : 댓글 지지투표 필터링 기능을 켤 수 있다. + protected ContentRestriction turnOnCommentRatingFilter(){ + return ContentRestriction.of(this.onlyHostWriteContent, + this.isWriteAbleComment, + true, + this.filteringRate); + } + + // 도메인 : 댓글 지지투표 필터링 기능을 끌 수 있다. + protected ContentRestriction turnOffCommentRatingFilter(){ + return ContentRestriction.of(this.onlyHostWriteContent, + this.isWriteAbleComment, + false, + this.filteringRate); + } + + // 제한 사항 VO 정적 팩토리 메소드 + public static ContentRestriction of(boolean onlyHostWriteContent, boolean isWriteAbleComment, + boolean useCommentRatingFilter, int filteringRate) { + return new ContentRestriction(onlyHostWriteContent, isWriteAbleComment, + useCommentRatingFilter, filteringRate); + } + + public static ContentRestriction onlyHostWriteContentAndAllCanWriteComment(){ + return ContentRestriction.of(true, true, false, 0); + } } diff --git a/needeachother/src/main/java/com/neo/needeachother/category/domain/ContentType.java b/needeachother/src/main/java/com/neo/needeachother/category/domain/ContentType.java index 8be1521..1d4e873 100644 --- a/needeachother/src/main/java/com/neo/needeachother/category/domain/ContentType.java +++ b/needeachother/src/main/java/com/neo/needeachother/category/domain/ContentType.java @@ -9,17 +9,23 @@ @Getter @RequiredArgsConstructor public enum ContentType { - COMMON("C"), - ALBUM("A"), - OX("OX"), - VOTE("V"); + COMMON("C", "CO"), + ALBUM("A", "AL"), + OX("OX", "OX"), + VOTE("V", "VO"); + // 카테고리의 컨텐츠 타입 요약 심볼(DB 데이터) private final String contentTypeSummarizedSymbol; + // 카테고리 앞 접두사 + private final String prefixCategoryId; + public static ContentType convertToContentType(String dbSymbol){ return Arrays.stream(ContentType.values()) .filter(contentType -> contentType.getContentTypeSummarizedSymbol().equals(dbSymbol)) .findAny() .orElseThrow(() -> new NEOUnexpectedException("경고 : 예상하지 못한 카테고리 컨텐츠 타입값이 저장됨")); } + + } diff --git a/needeachother/src/main/java/com/neo/needeachother/category/domain/InitCategory.java b/needeachother/src/main/java/com/neo/needeachother/category/domain/InitCategory.java new file mode 100644 index 0000000..62a4efa --- /dev/null +++ b/needeachother/src/main/java/com/neo/needeachother/category/domain/InitCategory.java @@ -0,0 +1,16 @@ +package com.neo.needeachother.category.domain; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum InitCategory { + NOTICE("공지사항", ContentType.COMMON), + FREE_BOARD("자유게시판", ContentType.COMMON), + SELFI("셆카", ContentType.ALBUM), + FREE_ALBUM("일상사진", ContentType.ALBUM); + + private final String koreanTitle; + private final ContentType contentType; +} diff --git a/needeachother/src/main/java/com/neo/needeachother/category/domain/ConfirmCategoryChangeableAdminService.java b/needeachother/src/main/java/com/neo/needeachother/category/domain/domainservice/ConfirmCategoryChangeableAdminService.java similarity index 92% rename from needeachother/src/main/java/com/neo/needeachother/category/domain/ConfirmCategoryChangeableAdminService.java rename to needeachother/src/main/java/com/neo/needeachother/category/domain/domainservice/ConfirmCategoryChangeableAdminService.java index 9d26a1d..ee3687a 100644 --- a/needeachother/src/main/java/com/neo/needeachother/category/domain/ConfirmCategoryChangeableAdminService.java +++ b/needeachother/src/main/java/com/neo/needeachother/category/domain/domainservice/ConfirmCategoryChangeableAdminService.java @@ -1,4 +1,4 @@ -package com.neo.needeachother.category.domain; +package com.neo.needeachother.category.domain.domainservice; import com.neo.needeachother.starpage.domain.NEOMember; import com.neo.needeachother.starpage.domain.StarPage; diff --git a/needeachother/src/main/java/com/neo/needeachother/category/domain/repository/CategoryCustomRepository.java b/needeachother/src/main/java/com/neo/needeachother/category/domain/repository/CategoryCustomRepository.java new file mode 100644 index 0000000..655b293 --- /dev/null +++ b/needeachother/src/main/java/com/neo/needeachother/category/domain/repository/CategoryCustomRepository.java @@ -0,0 +1,8 @@ +package com.neo.needeachother.category.domain.repository; + +import com.neo.needeachother.category.domain.CategoryId; +import com.neo.needeachother.category.domain.ContentType; + +public interface CategoryCustomRepository { + CategoryId getNextId(ContentType contentType); +} diff --git a/needeachother/src/main/java/com/neo/needeachother/category/domain/repository/CategoryRepository.java b/needeachother/src/main/java/com/neo/needeachother/category/domain/repository/CategoryRepository.java new file mode 100644 index 0000000..6d40f6e --- /dev/null +++ b/needeachother/src/main/java/com/neo/needeachother/category/domain/repository/CategoryRepository.java @@ -0,0 +1,8 @@ +package com.neo.needeachother.category.domain.repository; + +import com.neo.needeachother.category.domain.Category; +import com.neo.needeachother.category.domain.CategoryId; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface CategoryRepository extends JpaRepository, CategoryCustomRepository { +} diff --git a/needeachother/src/main/java/com/neo/needeachother/category/infra/CategoryCustomRepositoryImpl.java b/needeachother/src/main/java/com/neo/needeachother/category/infra/CategoryCustomRepositoryImpl.java new file mode 100644 index 0000000..d09b32a --- /dev/null +++ b/needeachother/src/main/java/com/neo/needeachother/category/infra/CategoryCustomRepositoryImpl.java @@ -0,0 +1,24 @@ +package com.neo.needeachother.category.infra; + +import com.neo.needeachother.category.domain.CategoryId; +import com.neo.needeachother.category.domain.ContentType; +import com.neo.needeachother.category.domain.repository.CategoryCustomRepository; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; + +import java.util.UUID; + +@RequiredArgsConstructor +public class CategoryCustomRepositoryImpl implements CategoryCustomRepository { + + private final JPAQueryFactory jpaQueryFactory; + + + @Override + public CategoryId getNextId(ContentType contentType) { + String stringBuilder = contentType.getPrefixCategoryId() + + "_" + + UUID.randomUUID().toString().toUpperCase(); + return new CategoryId(stringBuilder); + } +} diff --git a/needeachother/src/main/java/com/neo/needeachother/starpage/application/CreateStarPageService.java b/needeachother/src/main/java/com/neo/needeachother/starpage/application/CreateStarPageService.java index f24ad64..90c16d1 100644 --- a/needeachother/src/main/java/com/neo/needeachother/starpage/application/CreateStarPageService.java +++ b/needeachother/src/main/java/com/neo/needeachother/starpage/application/CreateStarPageService.java @@ -4,6 +4,7 @@ import com.neo.needeachother.starpage.domain.StarPage; import com.neo.needeachother.starpage.domain.repository.StarPageRepository; import lombok.RequiredArgsConstructor; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -15,11 +16,13 @@ public class CreateStarPageService { private final StarPageRepository starPageRepository; + private final ApplicationEventPublisher eventPublisher; @Transactional public void createStarPage(String starNickName, String email, Set starTypeSet, List snsLines, String starPageIntroduce){ - StarPage createdStarPage = StarPage.create(starNickName, email, starTypeSet, snsLines, starPageIntroduce); + StarPage createdStarPage = StarPage.create(starPageRepository.getNextId(), starNickName, email, + starTypeSet, snsLines, starPageIntroduce, eventPublisher); starPageRepository.save(createdStarPage); } } diff --git a/needeachother/src/main/java/com/neo/needeachother/starpage/domain/StarPage.java b/needeachother/src/main/java/com/neo/needeachother/starpage/domain/StarPage.java index 2afbf5d..77eab22 100644 --- a/needeachother/src/main/java/com/neo/needeachother/starpage/domain/StarPage.java +++ b/needeachother/src/main/java/com/neo/needeachother/starpage/domain/StarPage.java @@ -1,17 +1,19 @@ package com.neo.needeachother.starpage.domain; -import com.neo.needeachother.category.domain.Category; +import com.neo.needeachother.category.domain.*; import com.neo.needeachother.common.enums.NEODomainType; import com.neo.needeachother.common.enums.NEOErrorCode; import com.neo.needeachother.common.event.Events; import com.neo.needeachother.common.exception.NEOExpectedException; import com.neo.needeachother.common.exception.NEOUnexpectedException; +import com.neo.needeachother.starpage.domain.domainservice.CreateCategoryFromStarPageService; import com.neo.needeachother.starpage.domain.event.StarPageCreatedEvent; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; +import org.springframework.context.ApplicationEventPublisher; import java.util.*; import java.util.stream.Collectors; @@ -26,7 +28,7 @@ public class StarPage { @EmbeddedId @AttributeOverride(name = "value", column = @Column(name = "star_page_id")) - private StarPageId starPagesId; + private StarPageId starPageId; // 스타 페이지 정보 @Embedded @@ -216,16 +218,47 @@ private List getStarPageUniqueLayoutLinesAddList( return Collections.unmodifiableList(modifiedLayoutLines); } - // 도메인 : 스타페이지로 하여금 카테고리를 생성할 수 있다. (팩토리) - public Category createCategory(){ - return null; + // 도메인 : 스타페이지로 하여금 통합 카테고리를 생성할 수 있다. (팩토리) + public Category createCommonTypeCategory(CreateCategoryFromStarPageService createCategoryService, + String title, ContentRestriction contentRestriction) { + return createCategoryWithContentType(createCategoryService, title, + contentRestriction, ContentType.COMMON); + } + + // 도메인 : 스타페이지로 하여금 앨범 카테고리를 생성할 수 있다. (팩토리) + public Category createAlbumTypeCategory(CreateCategoryFromStarPageService createCategoryService, + String title, ContentRestriction contentRestriction) { + return createCategoryWithContentType(createCategoryService, title, + contentRestriction, ContentType.ALBUM); + } + + // 도메인 : 스타페이지로 하여금 OX 카테고리를 생성할 수 있다. (팩토리) + public Category createOXTypeCategory(CreateCategoryFromStarPageService createCategoryService, + String title, ContentRestriction contentRestriction) { + return createCategoryWithContentType(createCategoryService, title, + contentRestriction, ContentType.OX); + } + + // 도메인 : 스타페이지로 하여금 투표 카테고리를 생성할 수 있다. (팩토리) + public Category createVoteTypeCategory(CreateCategoryFromStarPageService createCategoryService, + String title, ContentRestriction contentRestriction) { + return createCategoryWithContentType(createCategoryService, title, + contentRestriction, ContentType.VOTE); + } + + private Category createCategoryWithContentType(CreateCategoryFromStarPageService createCategoryService, + String title, ContentRestriction contentRestriction, + ContentType contentType) { + return new Category(createCategoryService.createCategoryId(contentType), + this.starPageId, CategoryStatus.OPEN, contentType, + CategoryInformation.of(title), contentRestriction); } // 도메인 : 스타페이지를 새롭게 생성할 수 있다. (정적 팩토리) - public static StarPage create(String starNickName, String email, Set starTypeSet, - List snsLines, String starPageIntroduce) { + public static StarPage create(StarPageId starPageId, String starNickName, String email, Set starTypeSet, + List snsLines, String starPageIntroduce, ApplicationEventPublisher eventPublisher) { - StarPage createdStarPage = new StarPage(new StarPageId(), + StarPage createdStarPage = new StarPage(starPageId, StarPageInfo.withDefaultImageOf( StarPageHost.of(starNickName, email, starTypeSet.stream() @@ -236,7 +269,8 @@ public static StarPage create(String starNickName, String email, Set sta StarPageUniqueLayoutLine.scheduleLayoutLine())); // 스타페이지 생성 이벤트 발행 - Events.raise(new StarPageCreatedEvent()); + eventPublisher.publishEvent(new StarPageCreatedEvent(createdStarPage.getStarPageId())); + // Events.raise(new StarPageCreatedEvent()); return createdStarPage; } diff --git a/needeachother/src/main/java/com/neo/needeachother/starpage/domain/StarPageId.java b/needeachother/src/main/java/com/neo/needeachother/starpage/domain/StarPageId.java index d0f899e..32aca20 100644 --- a/needeachother/src/main/java/com/neo/needeachother/starpage/domain/StarPageId.java +++ b/needeachother/src/main/java/com/neo/needeachother/starpage/domain/StarPageId.java @@ -3,12 +3,17 @@ import jakarta.persistence.Column; import jakarta.persistence.Embeddable; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; import java.io.Serializable; @Embeddable @EqualsAndHashCode +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class StarPageId implements Serializable { @Column(name = "star_page_id") diff --git a/needeachother/src/main/java/com/neo/needeachother/starpage/domain/domainservice/CreateCategoryFromStarPageService.java b/needeachother/src/main/java/com/neo/needeachother/starpage/domain/domainservice/CreateCategoryFromStarPageService.java new file mode 100644 index 0000000..b991847 --- /dev/null +++ b/needeachother/src/main/java/com/neo/needeachother/starpage/domain/domainservice/CreateCategoryFromStarPageService.java @@ -0,0 +1,18 @@ +package com.neo.needeachother.starpage.domain.domainservice; + +import com.neo.needeachother.category.domain.CategoryId; +import com.neo.needeachother.category.domain.ContentType; +import com.neo.needeachother.category.domain.repository.CategoryRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class CreateCategoryFromStarPageService { + + private final CategoryRepository categoryRepository; + + public CategoryId createCategoryId(ContentType contentType){ + return categoryRepository.getNextId(contentType); + } +} diff --git a/needeachother/src/main/java/com/neo/needeachother/starpage/domain/event/StarPageCreatedEvent.java b/needeachother/src/main/java/com/neo/needeachother/starpage/domain/event/StarPageCreatedEvent.java index c2b4f06..a58c456 100644 --- a/needeachother/src/main/java/com/neo/needeachother/starpage/domain/event/StarPageCreatedEvent.java +++ b/needeachother/src/main/java/com/neo/needeachother/starpage/domain/event/StarPageCreatedEvent.java @@ -1,4 +1,11 @@ package com.neo.needeachother.starpage.domain.event; +import com.neo.needeachother.starpage.domain.StarPageId; +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor public class StarPageCreatedEvent { + private final StarPageId createdStarPageId; } diff --git a/needeachother/src/main/java/com/neo/needeachother/starpage/domain/repository/StarPageCustomRepository.java b/needeachother/src/main/java/com/neo/needeachother/starpage/domain/repository/StarPageCustomRepository.java index 822123a..e294a1c 100644 --- a/needeachother/src/main/java/com/neo/needeachother/starpage/domain/repository/StarPageCustomRepository.java +++ b/needeachother/src/main/java/com/neo/needeachother/starpage/domain/repository/StarPageCustomRepository.java @@ -1,4 +1,8 @@ package com.neo.needeachother.starpage.domain.repository; +import com.neo.needeachother.category.domain.CategoryId; +import com.neo.needeachother.starpage.domain.StarPageId; + public interface StarPageCustomRepository { + StarPageId getNextId(); } diff --git a/needeachother/src/main/java/com/neo/needeachother/starpage/domain/repository/StarPageRepository.java b/needeachother/src/main/java/com/neo/needeachother/starpage/domain/repository/StarPageRepository.java index 180d6ca..899cac7 100644 --- a/needeachother/src/main/java/com/neo/needeachother/starpage/domain/repository/StarPageRepository.java +++ b/needeachother/src/main/java/com/neo/needeachother/starpage/domain/repository/StarPageRepository.java @@ -5,4 +5,5 @@ import org.springframework.data.jpa.repository.JpaRepository; public interface StarPageRepository extends JpaRepository, StarPageCustomRepository { + } diff --git a/needeachother/src/main/java/com/neo/needeachother/starpage/infra/StarPageCustomRepositoryImpl.java b/needeachother/src/main/java/com/neo/needeachother/starpage/infra/StarPageCustomRepositoryImpl.java index 846cd60..56ba609 100644 --- a/needeachother/src/main/java/com/neo/needeachother/starpage/infra/StarPageCustomRepositoryImpl.java +++ b/needeachother/src/main/java/com/neo/needeachother/starpage/infra/StarPageCustomRepositoryImpl.java @@ -6,6 +6,8 @@ import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; +import java.util.UUID; + import static com.neo.needeachother.starpage.domain.QStarPage.*; @RequiredArgsConstructor @@ -21,4 +23,9 @@ public void findStarPageTopViewById(StarPageId id){ } + @Override + public StarPageId getNextId(){ + return new StarPageId("SP_" + UUID.randomUUID().toString().toLowerCase()); + } + } diff --git a/needeachother/src/test/java/com/neo/needeachother/starpage/domain/StarPageTest.java b/needeachother/src/test/java/com/neo/needeachother/starpage/domain/StarPageTest.java index 7b6e58e..ed71066 100644 --- a/needeachother/src/test/java/com/neo/needeachother/starpage/domain/StarPageTest.java +++ b/needeachother/src/test/java/com/neo/needeachother/starpage/domain/StarPageTest.java @@ -11,15 +11,7 @@ class StarPageTest { @Test public void changeProfileImageTest() { - StarPage createdStarPage = StarPage.create("이승훈", "free_minkya@naver.com", - Set.of("SNS_INFLUENCER", "ACTOR", "SINGER"), - List.of(SNSLine.of(SNSType.YOUTUBE, "http://youtube.com/free_minkya")), - "하이용"); - createdStarPage.changeProfileImage(NEOMember.of("free_minkya@naver.com"), - new Image("changed")); - - assertEquals(createdStarPage.getInformation().getCurrentProfileImage().getUrl(), "changed"); } public void changeTopRepresentativeImageTest(){ From 9e6b2bf063d3e2dcd5d753f03c0d8d90607d661e Mon Sep 17 00:00:00 2001 From: CodingLeeSeungHoon Date: Tue, 2 Apr 2024 19:23:05 +0900 Subject: [PATCH 6/7] feat : application layer dev (#49) --- .../CategoryVoteFilterService.java | 37 +++++++++++++++++++ .../ModifyCategoryInformationService.java | 25 +++++++++++++ .../ModifyCategoryStatusService.java | 6 +++ 3 files changed, 68 insertions(+) create mode 100644 needeachother/src/main/java/com/neo/needeachother/category/application/CategoryVoteFilterService.java create mode 100644 needeachother/src/main/java/com/neo/needeachother/category/application/ModifyCategoryInformationService.java diff --git a/needeachother/src/main/java/com/neo/needeachother/category/application/CategoryVoteFilterService.java b/needeachother/src/main/java/com/neo/needeachother/category/application/CategoryVoteFilterService.java new file mode 100644 index 0000000..274b46c --- /dev/null +++ b/needeachother/src/main/java/com/neo/needeachother/category/application/CategoryVoteFilterService.java @@ -0,0 +1,37 @@ +package com.neo.needeachother.category.application; + +import com.neo.needeachother.category.domain.Category; +import com.neo.needeachother.category.domain.CategoryId; +import com.neo.needeachother.category.domain.domainservice.ConfirmCategoryChangeableAdminService; +import com.neo.needeachother.category.domain.repository.CategoryRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import static com.neo.needeachother.category.application.CategoryServiceHelper.*; + +@Service +@RequiredArgsConstructor +public class CategoryVoteFilterService { + + private final CategoryRepository categoryRepository; + private final ConfirmCategoryChangeableAdminService confirmCategoryChangeableAdminService; + + @Transactional + public void modifyFilteringRate(CategoryId categoryId, String email, int changingRate){ + Category foundCategory = findExistingCategory(categoryRepository, categoryId); + foundCategory.modifyFilteringRate(confirmCategoryChangeableAdminService, email, changingRate); + } + + @Transactional + public void useFilter(CategoryId categoryId, String email){ + Category foundCategory = findExistingCategory(categoryRepository, categoryId); + foundCategory.turnOnCommentRatingFilter(confirmCategoryChangeableAdminService, email); + } + + @Transactional + public void notUseFilter(CategoryId categoryId, String email){ + Category foundCategory = findExistingCategory(categoryRepository, categoryId); + foundCategory.turnOffCommentRatingFilter(confirmCategoryChangeableAdminService, email); + } +} diff --git a/needeachother/src/main/java/com/neo/needeachother/category/application/ModifyCategoryInformationService.java b/needeachother/src/main/java/com/neo/needeachother/category/application/ModifyCategoryInformationService.java new file mode 100644 index 0000000..89e8ab2 --- /dev/null +++ b/needeachother/src/main/java/com/neo/needeachother/category/application/ModifyCategoryInformationService.java @@ -0,0 +1,25 @@ +package com.neo.needeachother.category.application; + +import com.neo.needeachother.category.domain.Category; +import com.neo.needeachother.category.domain.CategoryId; +import com.neo.needeachother.category.domain.domainservice.ConfirmCategoryChangeableAdminService; +import com.neo.needeachother.category.domain.repository.CategoryRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import static com.neo.needeachother.category.application.CategoryServiceHelper.*; + +@Service +@RequiredArgsConstructor +public class ModifyCategoryInformationService { + + private final CategoryRepository categoryRepository; + private final ConfirmCategoryChangeableAdminService confirmCategoryChangeableAdminService; + + @Transactional + public void changeCategoryTitle(CategoryId categoryId, String email, String title){ + Category foundCategory = findExistingCategory(categoryRepository, categoryId); + foundCategory.modifyCategoryTitle(confirmCategoryChangeableAdminService, email, title); + } +} diff --git a/needeachother/src/main/java/com/neo/needeachother/category/application/ModifyCategoryStatusService.java b/needeachother/src/main/java/com/neo/needeachother/category/application/ModifyCategoryStatusService.java index ca0953f..eb6b758 100644 --- a/needeachother/src/main/java/com/neo/needeachother/category/application/ModifyCategoryStatusService.java +++ b/needeachother/src/main/java/com/neo/needeachother/category/application/ModifyCategoryStatusService.java @@ -29,4 +29,10 @@ public void deleteCategory(CategoryId id, String email){ foundCategory.deleteCategory(confirmCategoryChangeableAdminService, email); } + @Transactional + public void exposureCategory(CategoryId id, String email){ + Category foundCategory = findExistingCategory(categoryRepository, id); + foundCategory.exposureCategory(confirmCategoryChangeableAdminService, email); + } + } From 5343e00eff6df909881258dea78abfec8a633f26 Mon Sep 17 00:00:00 2001 From: CodingLeeSeungHoon Date: Tue, 2 Apr 2024 19:28:54 +0900 Subject: [PATCH 7/7] =?UTF-8?q?fix=20:=20querydsl=20=ED=8C=8C=ED=8A=B8=20?= =?UTF-8?q?=EC=9E=84=EC=8B=9C=20=EC=A3=BC=EC=84=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../starpage/infra/StarPageCustomRepositoryImpl.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/needeachother/src/main/java/com/neo/needeachother/starpage/infra/StarPageCustomRepositoryImpl.java b/needeachother/src/main/java/com/neo/needeachother/starpage/infra/StarPageCustomRepositoryImpl.java index 56ba609..9d5e10c 100644 --- a/needeachother/src/main/java/com/neo/needeachother/starpage/infra/StarPageCustomRepositoryImpl.java +++ b/needeachother/src/main/java/com/neo/needeachother/starpage/infra/StarPageCustomRepositoryImpl.java @@ -16,10 +16,10 @@ public class StarPageCustomRepositoryImpl implements StarPageCustomRepository { private final JPAQueryFactory queryFactory; public void findStarPageTopViewById(StarPageId id){ - queryFactory.select(starPage.information) - .from(starPage) - .where(starPage.starPagesId.eq(id)) - .fetchOne(); +// queryFactory.select(starPage.information) +// .from(starPage) +// .where(starPage.starPagesId.eq(id)) +// .fetchOne(); }