From 6bb84cd23436467b99626a392f2975ce477f0ddd Mon Sep 17 00:00:00 2001 From: junwon Date: Sat, 31 Aug 2024 10:33:58 +0900 Subject: [PATCH] =?UTF-8?q?refactor=20:=20=EB=AF=B9=EC=8A=A4=ED=8C=A8?= =?UTF-8?q?=EB=84=90=20=ED=8C=A8=ED=82=A4=EC=A7=80=20=EA=B5=AC=EC=A1=B0=20?= =?UTF-8?q?=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../spot/domain/mixpanel/MixpanelEvent.java | 19 ++++++++++ infrastructure/build.gradle.kts | 3 ++ .../mixpanel/property/MixpanelProperties.java | 6 ++++ .../repository/MixpanelRepositoryImpl.java | 35 ++++++------------- .../port/out/mixpanel/MixpanelRepository.java | 7 ++++ .../service/review/CreateReviewService.java | 8 ++--- .../service/review/ReadReviewService.java | 8 ++--- .../review/like/ReviewLikeService.java | 10 +++--- .../review/scrap/ReviewScrapService.java | 9 ++--- .../review/ReviewScrapServiceTest.java | 5 ++- 10 files changed, 69 insertions(+), 41 deletions(-) create mode 100644 domain/src/main/java/org/depromeet/spot/domain/mixpanel/MixpanelEvent.java create mode 100644 infrastructure/src/main/java/org/depromeet/spot/infrastructure/mixpanel/property/MixpanelProperties.java rename usecase/src/main/java/org/depromeet/spot/usecase/service/util/MixpanelUtil.java => infrastructure/src/main/java/org/depromeet/spot/infrastructure/mixpanel/repository/MixpanelRepositoryImpl.java (60%) create mode 100644 usecase/src/main/java/org/depromeet/spot/usecase/port/out/mixpanel/MixpanelRepository.java diff --git a/domain/src/main/java/org/depromeet/spot/domain/mixpanel/MixpanelEvent.java b/domain/src/main/java/org/depromeet/spot/domain/mixpanel/MixpanelEvent.java new file mode 100644 index 00000000..ad4758f3 --- /dev/null +++ b/domain/src/main/java/org/depromeet/spot/domain/mixpanel/MixpanelEvent.java @@ -0,0 +1,19 @@ +package org.depromeet.spot.domain.mixpanel; + +import lombok.Getter; + +@Getter +public enum MixpanelEvent { + REVIEW_REGISTER("review_register"), + REVIEW_REGISTER_MAX("review_register"), + REVIEW_OPEN_COUNT("review_open_count"), + REVIEW_LIKE_COUNT("review_like_count"), + REVIEW_SCRAP_COUNT("review_scrap_count"), + ; + + String value; + + MixpanelEvent(String value) { + this.value = value; + } +} diff --git a/infrastructure/build.gradle.kts b/infrastructure/build.gradle.kts index 04303df5..6ce66765 100644 --- a/infrastructure/build.gradle.kts +++ b/infrastructure/build.gradle.kts @@ -39,6 +39,9 @@ dependencies { // caffeine cache implementation("com.github.ben-manes.caffeine:caffeine:_") + + // Mixpanel + implementation("com.mixpanel:mixpanel-java:_") } tasks.bootJar { enabled = false } diff --git a/infrastructure/src/main/java/org/depromeet/spot/infrastructure/mixpanel/property/MixpanelProperties.java b/infrastructure/src/main/java/org/depromeet/spot/infrastructure/mixpanel/property/MixpanelProperties.java new file mode 100644 index 00000000..8d437e82 --- /dev/null +++ b/infrastructure/src/main/java/org/depromeet/spot/infrastructure/mixpanel/property/MixpanelProperties.java @@ -0,0 +1,6 @@ +package org.depromeet.spot.infrastructure.mixpanel.property; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +@ConfigurationProperties(prefix = "mixpanel") +public record MixpanelProperties(String token) {} diff --git a/usecase/src/main/java/org/depromeet/spot/usecase/service/util/MixpanelUtil.java b/infrastructure/src/main/java/org/depromeet/spot/infrastructure/mixpanel/repository/MixpanelRepositoryImpl.java similarity index 60% rename from usecase/src/main/java/org/depromeet/spot/usecase/service/util/MixpanelUtil.java rename to infrastructure/src/main/java/org/depromeet/spot/infrastructure/mixpanel/repository/MixpanelRepositoryImpl.java index be23d151..3d6980b1 100644 --- a/usecase/src/main/java/org/depromeet/spot/usecase/service/util/MixpanelUtil.java +++ b/infrastructure/src/main/java/org/depromeet/spot/infrastructure/mixpanel/repository/MixpanelRepositoryImpl.java @@ -1,32 +1,35 @@ -package org.depromeet.spot.usecase.service.util; +package org.depromeet.spot.infrastructure.mixpanel.repository; import java.io.IOException; +import org.depromeet.spot.domain.mixpanel.MixpanelEvent; +import org.depromeet.spot.infrastructure.mixpanel.property.MixpanelProperties; +import org.depromeet.spot.usecase.port.out.mixpanel.MixpanelRepository; import org.json.JSONObject; -import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import com.mixpanel.mixpanelapi.ClientDelivery; import com.mixpanel.mixpanelapi.MessageBuilder; import com.mixpanel.mixpanelapi.MixpanelAPI; -import lombok.Getter; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @Slf4j @Component -public class MixpanelUtil { +@RequiredArgsConstructor +public class MixpanelRepositoryImpl implements MixpanelRepository { - @Value("${mixpanel.token}") - private String mixpanelToken; + private final MixpanelProperties mixpanelProperties; // mixpanelEvent는 eventName(이 단위로 이벤트가 묶임) // distinctId는 사용자를 구분하는 데 사용됨. - public void track(MixpanelEvent mixpanelEvent, String distinctId) { + @Override + public void eventTrack(MixpanelEvent mixpanelEvent, String distinctId) { try { // 믹스패널 이벤트 메시지 생성 - MessageBuilder messageBuilder = new MessageBuilder(mixpanelToken); + MessageBuilder messageBuilder = new MessageBuilder(mixpanelProperties.token()); // 이벤트 생성 JSONObject sentEvent = messageBuilder.event(distinctId, mixpanelEvent.getValue(), null); @@ -42,20 +45,4 @@ public void track(MixpanelEvent mixpanelEvent, String distinctId) { e.printStackTrace(); } } - - @Getter - public enum MixpanelEvent { - REVIEW_REGISTER("review_register"), - REVIEW_REGISTER_MAX("review_register"), - REVIEW_OPEN_COUNT("review_open_count"), - REVIEW_LIKE_COUNT("review_like_count"), - REVIEW_SCRAP_COUNT("review_scrap_count"), - ; - - String value; - - MixpanelEvent(String value) { - this.value = value; - } - } } diff --git a/usecase/src/main/java/org/depromeet/spot/usecase/port/out/mixpanel/MixpanelRepository.java b/usecase/src/main/java/org/depromeet/spot/usecase/port/out/mixpanel/MixpanelRepository.java new file mode 100644 index 00000000..09ca9d30 --- /dev/null +++ b/usecase/src/main/java/org/depromeet/spot/usecase/port/out/mixpanel/MixpanelRepository.java @@ -0,0 +1,7 @@ +package org.depromeet.spot.usecase.port.out.mixpanel; + +import org.depromeet.spot.domain.mixpanel.MixpanelEvent; + +public interface MixpanelRepository { + void eventTrack(MixpanelEvent mixpanelEvent, String distinctId); +} diff --git a/usecase/src/main/java/org/depromeet/spot/usecase/service/review/CreateReviewService.java b/usecase/src/main/java/org/depromeet/spot/usecase/service/review/CreateReviewService.java index 32090e99..38ea038a 100644 --- a/usecase/src/main/java/org/depromeet/spot/usecase/service/review/CreateReviewService.java +++ b/usecase/src/main/java/org/depromeet/spot/usecase/service/review/CreateReviewService.java @@ -4,17 +4,17 @@ import java.util.Map; import org.depromeet.spot.domain.member.Member; +import org.depromeet.spot.domain.mixpanel.MixpanelEvent; import org.depromeet.spot.domain.review.Review; import org.depromeet.spot.domain.review.keyword.Keyword; import org.depromeet.spot.usecase.port.in.review.CreateReviewUsecase; import org.depromeet.spot.usecase.port.out.member.MemberRepository; +import org.depromeet.spot.usecase.port.out.mixpanel.MixpanelRepository; import org.depromeet.spot.usecase.port.out.review.ReviewRepository; import org.depromeet.spot.usecase.service.member.processor.MemberLevelProcessor; import org.depromeet.spot.usecase.service.review.processor.ReviewCreationProcessor; import org.depromeet.spot.usecase.service.review.processor.ReviewImageProcessor; import org.depromeet.spot.usecase.service.review.processor.ReviewKeywordProcessor; -import org.depromeet.spot.usecase.service.util.MixpanelUtil; -import org.depromeet.spot.usecase.service.util.MixpanelUtil.MixpanelEvent; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -32,7 +32,7 @@ public class CreateReviewService implements CreateReviewUsecase { private final ReviewImageProcessor reviewImageProcessor; private final ReviewKeywordProcessor reviewKeywordProcessor; private final MemberLevelProcessor memberLevelProcessor; - private final MixpanelUtil mixpanelUtil; + private final MixpanelRepository mixpanelRepository; @Override @Transactional @@ -50,7 +50,7 @@ public CreateReviewResult create(Long blockId, Long memberId, CreateReviewComman Member levelUpdateMember = memberLevelProcessor.calculateAndUpdateMemberLevel(member); // 믹스패널 이벤트(후기 등록 완료) 호출 - mixpanelUtil.track(MixpanelEvent.REVIEW_REGISTER, String.valueOf(memberId)); + mixpanelRepository.eventTrack(MixpanelEvent.REVIEW_REGISTER, String.valueOf(memberId)); return new CreateReviewResult(savedReview, levelUpdateMember, review.getSeat()); } diff --git a/usecase/src/main/java/org/depromeet/spot/usecase/service/review/ReadReviewService.java b/usecase/src/main/java/org/depromeet/spot/usecase/service/review/ReadReviewService.java index 441978d4..5dc439df 100644 --- a/usecase/src/main/java/org/depromeet/spot/usecase/service/review/ReadReviewService.java +++ b/usecase/src/main/java/org/depromeet/spot/usecase/service/review/ReadReviewService.java @@ -5,6 +5,7 @@ import java.util.stream.Collectors; import org.depromeet.spot.domain.member.Member; +import org.depromeet.spot.domain.mixpanel.MixpanelEvent; import org.depromeet.spot.domain.review.Review; import org.depromeet.spot.domain.review.Review.ReviewType; import org.depromeet.spot.domain.review.Review.SortCriteria; @@ -15,6 +16,7 @@ import org.depromeet.spot.domain.team.BaseballTeam; import org.depromeet.spot.usecase.port.in.review.ReadReviewUsecase; import org.depromeet.spot.usecase.port.out.member.MemberRepository; +import org.depromeet.spot.usecase.port.out.mixpanel.MixpanelRepository; import org.depromeet.spot.usecase.port.out.review.BlockTopKeywordRepository; import org.depromeet.spot.usecase.port.out.review.KeywordRepository; import org.depromeet.spot.usecase.port.out.review.ReviewImageRepository; @@ -24,8 +26,6 @@ import org.depromeet.spot.usecase.port.out.team.BaseballTeamRepository; import org.depromeet.spot.usecase.service.review.processor.PaginationProcessor; import org.depromeet.spot.usecase.service.review.processor.ReadReviewProcessor; -import org.depromeet.spot.usecase.service.util.MixpanelUtil; -import org.depromeet.spot.usecase.service.util.MixpanelUtil.MixpanelEvent; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -48,7 +48,7 @@ public class ReadReviewService implements ReadReviewUsecase { private final ReviewScrapRepository reviewScrapRepository; private final ReadReviewProcessor readReviewProcessor; private final PaginationProcessor paginationProcessor; - private final MixpanelUtil mixpanelUtil; + private final MixpanelRepository mixpanelRepository; private static final int TOP_KEYWORDS_LIMIT = 5; private static final int TOP_IMAGES_LIMIT = 5; @@ -193,7 +193,7 @@ public ReadReviewResult findReviewById(Long reviewId, Long memberId) { Review reviewWithKeywords = mapKeywordsToSingleReview(review); // 믹스패널 이벤트(조회수) 발생 - mixpanelUtil.track(MixpanelEvent.REVIEW_OPEN_COUNT, String.valueOf(memberId)); + mixpanelRepository.eventTrack(MixpanelEvent.REVIEW_OPEN_COUNT, String.valueOf(memberId)); return ReadReviewResult.builder().review(reviewWithKeywords).build(); } diff --git a/usecase/src/main/java/org/depromeet/spot/usecase/service/review/like/ReviewLikeService.java b/usecase/src/main/java/org/depromeet/spot/usecase/service/review/like/ReviewLikeService.java index 2326fd7f..e0eb93c4 100644 --- a/usecase/src/main/java/org/depromeet/spot/usecase/service/review/like/ReviewLikeService.java +++ b/usecase/src/main/java/org/depromeet/spot/usecase/service/review/like/ReviewLikeService.java @@ -7,8 +7,6 @@ import org.depromeet.spot.usecase.port.in.review.UpdateReviewUsecase; import org.depromeet.spot.usecase.port.in.review.like.ReviewLikeUsecase; import org.depromeet.spot.usecase.port.out.review.ReviewLikeRepository; -import org.depromeet.spot.usecase.service.util.MixpanelUtil; -import org.depromeet.spot.usecase.service.util.MixpanelUtil.MixpanelEvent; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -24,7 +22,9 @@ public class ReviewLikeService implements ReviewLikeUsecase { private final ReadReviewUsecase readReviewUsecase; private final UpdateReviewUsecase updateReviewUsecase; private final ReviewLikeRepository reviewLikeRepository; - private final MixpanelUtil mixpanelUtil; + + // TODO : Service 코드와 분리하기 + // private final MixpanelRepository mixpanelRepository; @Override @DistributedLock(key = "#reviewId") @@ -38,8 +38,10 @@ public void toggleLike(final Long memberId, final long reviewId) { addLike(memberId, reviewId, review); + // TODO : 테스트 시에도 이벤트 발생함. // 믹스패널 이벤트(좋아요 수) 발생 - mixpanelUtil.track(MixpanelEvent.REVIEW_LIKE_COUNT, String.valueOf(memberId)); + // mixpanelRepository.eventTrack(MixpanelEvent.REVIEW_LIKE_COUNT, + // String.valueOf(memberId)); } public void cancelLike(final long memberId, final long reviewId, Review review) { diff --git a/usecase/src/main/java/org/depromeet/spot/usecase/service/review/scrap/ReviewScrapService.java b/usecase/src/main/java/org/depromeet/spot/usecase/service/review/scrap/ReviewScrapService.java index 73a1ca0b..5c372400 100644 --- a/usecase/src/main/java/org/depromeet/spot/usecase/service/review/scrap/ReviewScrapService.java +++ b/usecase/src/main/java/org/depromeet/spot/usecase/service/review/scrap/ReviewScrapService.java @@ -2,18 +2,18 @@ import java.util.List; +import org.depromeet.spot.domain.mixpanel.MixpanelEvent; import org.depromeet.spot.domain.review.Review; import org.depromeet.spot.domain.review.scrap.ReviewScrap; import org.depromeet.spot.usecase.port.in.review.ReadReviewUsecase; import org.depromeet.spot.usecase.port.in.review.UpdateReviewUsecase; import org.depromeet.spot.usecase.port.in.review.page.PageCommand; import org.depromeet.spot.usecase.port.in.review.scrap.ReviewScrapUsecase; +import org.depromeet.spot.usecase.port.out.mixpanel.MixpanelRepository; import org.depromeet.spot.usecase.port.out.review.ReviewScrapRepository; import org.depromeet.spot.usecase.service.review.ReadReviewService; import org.depromeet.spot.usecase.service.review.processor.PaginationProcessor; import org.depromeet.spot.usecase.service.review.processor.ReadReviewProcessor; -import org.depromeet.spot.usecase.service.util.MixpanelUtil; -import org.depromeet.spot.usecase.service.util.MixpanelUtil.MixpanelEvent; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -30,7 +30,8 @@ public class ReviewScrapService implements ReviewScrapUsecase { private final ReadReviewService readReviewService; private final ReadReviewProcessor readReviewProcessor; private final PaginationProcessor paginationProcessor; - private final MixpanelUtil mixpanelUtil; + + private final MixpanelRepository mixpanelRepository; @Override public MyScrapListResult findMyScrappedReviews( @@ -91,7 +92,7 @@ public boolean toggleScrap(final long memberId, final long reviewId) { addScrap(memberId, reviewId, review); // 믹스패널 이벤트(스크랩 수) 발생 - mixpanelUtil.track(MixpanelEvent.REVIEW_SCRAP_COUNT, String.valueOf(memberId)); + mixpanelRepository.eventTrack(MixpanelEvent.REVIEW_SCRAP_COUNT, String.valueOf(memberId)); return true; } diff --git a/usecase/src/test/java/org/depromeet/spot/usecase/service/review/ReviewScrapServiceTest.java b/usecase/src/test/java/org/depromeet/spot/usecase/service/review/ReviewScrapServiceTest.java index 458de70f..a88718bc 100644 --- a/usecase/src/test/java/org/depromeet/spot/usecase/service/review/ReviewScrapServiceTest.java +++ b/usecase/src/test/java/org/depromeet/spot/usecase/service/review/ReviewScrapServiceTest.java @@ -18,6 +18,7 @@ import org.depromeet.spot.usecase.port.in.review.page.PageCommand; import org.depromeet.spot.usecase.port.in.review.scrap.ReviewScrapUsecase.MyScrapCommand; import org.depromeet.spot.usecase.port.in.review.scrap.ReviewScrapUsecase.MyScrapListResult; +import org.depromeet.spot.usecase.port.out.mixpanel.MixpanelRepository; import org.depromeet.spot.usecase.service.fake.FakeReviewScrapRepository; import org.depromeet.spot.usecase.service.review.processor.PaginationProcessor; import org.depromeet.spot.usecase.service.review.processor.ReadReviewProcessor; @@ -37,6 +38,7 @@ class ReviewScrapServiceTest { @Mock private ReadReviewService readReviewService; @Mock private ReadReviewProcessor readReviewProcessor; @Mock private PaginationProcessor paginationProcessor; + @Mock private MixpanelRepository mixpanelRepository; @BeforeEach void init() { @@ -49,7 +51,8 @@ void init() { fakeReviewScrapRepository, readReviewService, readReviewProcessor, - paginationProcessor); + paginationProcessor, + mixpanelRepository); } @Test