From dec28a96030b3e15f0f319742cbb38753b2cc753 Mon Sep 17 00:00:00 2001 From: CodingLeeSeungHoon Date: Tue, 2 Apr 2024 19:05:47 +0900 Subject: [PATCH] =?UTF-8?q?feat=20:=20starpage=20created=20event=20logic?= =?UTF-8?q?=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(){