diff --git a/src/main/java/com/magamochi/catalog/service/MangaService.java b/src/main/java/com/magamochi/catalog/service/MangaService.java index a9cc546..e30f240 100644 --- a/src/main/java/com/magamochi/catalog/service/MangaService.java +++ b/src/main/java/com/magamochi/catalog/service/MangaService.java @@ -8,10 +8,10 @@ import com.magamochi.catalog.model.dto.MangaListFilterDTO; import com.magamochi.catalog.model.entity.Manga; import com.magamochi.catalog.model.repository.MangaRepository; import com.magamochi.common.exception.NotFoundException; -import com.magamochi.model.repository.UserMangaFollowRepository; import com.magamochi.model.specification.MangaSpecification; import com.magamochi.user.service.UserService; import com.magamochi.userinteraction.model.repository.UserFavoriteMangaRepository; +import com.magamochi.userinteraction.model.repository.UserMangaFollowRepository; import java.util.List; import java.util.Set; import java.util.stream.Collectors; diff --git a/src/main/java/com/magamochi/controller/MangaController.java b/src/main/java/com/magamochi/controller/MangaController.java index 5c17b85..ceab0cf 100644 --- a/src/main/java/com/magamochi/controller/MangaController.java +++ b/src/main/java/com/magamochi/controller/MangaController.java @@ -23,28 +23,4 @@ public class MangaController { return DefaultResponseDTO.ok().build(); } - - @Operation( - summary = "Follow the manga specified by its ID", - description = "Follow the manga specified by its ID.", - tags = {"Manga"}, - operationId = "followManga") - @PostMapping("/{mangaId}/followManga") - public DefaultResponseDTO followManga(@PathVariable Long mangaId) { - oldMangaService.follow(mangaId); - - return DefaultResponseDTO.ok().build(); - } - - @Operation( - summary = "Unfollow the manga specified by its ID", - description = "Unfollow the manga specified by its ID.", - tags = {"Manga"}, - operationId = "unfollowManga") - @PostMapping("/{mangaId}/unfollowManga") - public DefaultResponseDTO unfollowManga(@PathVariable Long mangaId) { - oldMangaService.unfollow(mangaId); - - return DefaultResponseDTO.ok().build(); - } } diff --git a/src/main/java/com/magamochi/service/OldMangaService.java b/src/main/java/com/magamochi/service/OldMangaService.java index 412cdb8..c3e3934 100644 --- a/src/main/java/com/magamochi/service/OldMangaService.java +++ b/src/main/java/com/magamochi/service/OldMangaService.java @@ -1,30 +1,23 @@ package com.magamochi.service; -import com.magamochi.catalog.model.entity.Manga; import com.magamochi.catalog.model.repository.MangaContentProviderRepository; -import com.magamochi.catalog.model.repository.MangaRepository; import com.magamochi.common.exception.NotFoundException; import com.magamochi.content.model.entity.MangaContent; import com.magamochi.model.dto.*; -import com.magamochi.model.entity.UserMangaFollow; -import com.magamochi.model.repository.*; import com.magamochi.queue.MangaChapterDownloadProducer; import com.magamochi.user.service.UserService; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; @Log4j2 @Service @RequiredArgsConstructor public class OldMangaService { private final UserService userService; - private final MangaRepository mangaRepository; - private final MangaContentProviderRepository mangaContentProviderRepository; - private final UserMangaFollowRepository userMangaFollowRepository; + private final MangaContentProviderRepository mangaContentProviderRepository; private final MangaChapterDownloadProducer mangaChapterDownloadProducer; @@ -81,36 +74,4 @@ public class OldMangaService { // mangaProvider.getContentProvider().getName()))); // } - public Manga findMangaByIdThrowIfNotFound(Long mangaId) { - return mangaRepository - .findById(mangaId) - .orElseThrow(() -> new NotFoundException("Manga not found for ID: " + mangaId)); - } - - @Transactional - public void follow(Long mangaId) { - var user = userService.getLoggedUserThrowIfNotFound(); - - var manga = findMangaByIdThrowIfNotFound(mangaId); - manga.setFollow(true); - - if (userMangaFollowRepository.existsByUserAndManga(user, manga)) { - return; - } - - userMangaFollowRepository.save(UserMangaFollow.builder().user(user).manga(manga).build()); - } - - @Transactional - public void unfollow(Long mangaId) { - var user = userService.getLoggedUserThrowIfNotFound(); - var manga = findMangaByIdThrowIfNotFound(mangaId); - - var userMangaFollow = userMangaFollowRepository.findByUserAndManga(user, manga); - userMangaFollow.ifPresent(userMangaFollowRepository::delete); - - if (!userMangaFollowRepository.existsByManga(manga)) { - manga.setFollow(false); - } - } } diff --git a/src/main/java/com/magamochi/task/MangaFollowUpdateTask.java b/src/main/java/com/magamochi/task/MangaFollowUpdateTask.java index 9099c23..a2ec682 100644 --- a/src/main/java/com/magamochi/task/MangaFollowUpdateTask.java +++ b/src/main/java/com/magamochi/task/MangaFollowUpdateTask.java @@ -7,7 +7,6 @@ import com.magamochi.queue.UpdateMangaFollowChapterListProducer; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Value; -import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; @@ -22,7 +21,7 @@ public class MangaFollowUpdateTask { private final UpdateMangaFollowChapterListProducer producer; - @Scheduled(cron = "${manga-follow.cron-expression}") + // @Scheduled(cron = "${manga-follow.cron-expression}") @Transactional public void updateMangaFollow() { if (!updateEnabled) { diff --git a/src/main/java/com/magamochi/userinteraction/controller/UserInteractionController.java b/src/main/java/com/magamochi/userinteraction/controller/UserInteractionController.java index 33f0d77..56b5fe7 100644 --- a/src/main/java/com/magamochi/userinteraction/controller/UserInteractionController.java +++ b/src/main/java/com/magamochi/userinteraction/controller/UserInteractionController.java @@ -3,6 +3,7 @@ package com.magamochi.userinteraction.controller; import com.magamochi.common.model.dto.DefaultResponseDTO; import com.magamochi.userinteraction.service.UserFavoriteMangaService; import com.magamochi.userinteraction.service.UserMangaContentReadService; +import com.magamochi.userinteraction.service.UserMangaFollowService; import io.swagger.v3.oas.annotations.Operation; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.PathVariable; @@ -16,6 +17,7 @@ import org.springframework.web.bind.annotation.RestController; public class UserInteractionController { private final UserFavoriteMangaService userFavoriteMangaService; private final UserMangaContentReadService userMangaContentReadService; + private final UserMangaFollowService userMangaFollowService; @Operation( summary = "Favorite a manga", @@ -52,4 +54,28 @@ public class UserInteractionController { return DefaultResponseDTO.ok().build(); } + + @Operation( + summary = "Follow the manga specified by its ID", + description = "Follow the manga specified by its ID.", + tags = {"User Interaction"}, + operationId = "followManga") + @PostMapping("/manga/{mangaId}/follow") + public DefaultResponseDTO followManga(@PathVariable Long mangaId) { + userMangaFollowService.follow(mangaId); + + return DefaultResponseDTO.ok().build(); + } + + @Operation( + summary = "Unfollow the manga specified by its ID", + description = "Unfollow the manga specified by its ID.", + tags = {"User Interaction"}, + operationId = "unfollowManga") + @PostMapping("/manga/{mangaId}/unfollow") + public DefaultResponseDTO unfollowManga(@PathVariable Long mangaId) { + userMangaFollowService.unfollow(mangaId); + + return DefaultResponseDTO.ok().build(); + } } diff --git a/src/main/java/com/magamochi/model/entity/UserMangaFollow.java b/src/main/java/com/magamochi/userinteraction/model/entity/UserMangaFollow.java similarity index 90% rename from src/main/java/com/magamochi/model/entity/UserMangaFollow.java rename to src/main/java/com/magamochi/userinteraction/model/entity/UserMangaFollow.java index 36a7d63..909e7dc 100644 --- a/src/main/java/com/magamochi/model/entity/UserMangaFollow.java +++ b/src/main/java/com/magamochi/userinteraction/model/entity/UserMangaFollow.java @@ -1,4 +1,4 @@ -package com.magamochi.model.entity; +package com.magamochi.userinteraction.model.entity; import com.magamochi.catalog.model.entity.Manga; import com.magamochi.user.model.entity.User; diff --git a/src/main/java/com/magamochi/model/repository/UserMangaFollowRepository.java b/src/main/java/com/magamochi/userinteraction/model/repository/UserMangaFollowRepository.java similarity index 82% rename from src/main/java/com/magamochi/model/repository/UserMangaFollowRepository.java rename to src/main/java/com/magamochi/userinteraction/model/repository/UserMangaFollowRepository.java index db84305..5b77731 100644 --- a/src/main/java/com/magamochi/model/repository/UserMangaFollowRepository.java +++ b/src/main/java/com/magamochi/userinteraction/model/repository/UserMangaFollowRepository.java @@ -1,8 +1,8 @@ -package com.magamochi.model.repository; +package com.magamochi.userinteraction.model.repository; import com.magamochi.catalog.model.entity.Manga; -import com.magamochi.model.entity.UserMangaFollow; import com.magamochi.user.model.entity.User; +import com.magamochi.userinteraction.model.entity.UserMangaFollow; import java.util.List; import java.util.Optional; import org.springframework.data.jpa.repository.JpaRepository; diff --git a/src/main/java/com/magamochi/userinteraction/service/UserMangaFollowService.java b/src/main/java/com/magamochi/userinteraction/service/UserMangaFollowService.java new file mode 100644 index 0000000..f01a744 --- /dev/null +++ b/src/main/java/com/magamochi/userinteraction/service/UserMangaFollowService.java @@ -0,0 +1,53 @@ +package com.magamochi.userinteraction.service; + +import com.magamochi.catalog.model.entity.Manga; +import com.magamochi.catalog.model.repository.MangaRepository; +import com.magamochi.common.exception.NotFoundException; +import com.magamochi.user.service.UserService; +import com.magamochi.userinteraction.model.entity.UserMangaFollow; +import com.magamochi.userinteraction.model.repository.UserMangaFollowRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +public class UserMangaFollowService { + private final UserService userService; + + private final MangaRepository mangaRepository; + private final UserMangaFollowRepository userMangaFollowRepository; + + @Transactional + public void follow(Long mangaId) { + var user = userService.getLoggedUserThrowIfNotFound(); + + var manga = findMangaByIdThrowIfNotFound(mangaId); + manga.setFollow(true); + + if (userMangaFollowRepository.existsByUserAndManga(user, manga)) { + return; + } + + userMangaFollowRepository.save(UserMangaFollow.builder().user(user).manga(manga).build()); + } + + @Transactional + public void unfollow(Long mangaId) { + var user = userService.getLoggedUserThrowIfNotFound(); + var manga = findMangaByIdThrowIfNotFound(mangaId); + + var userMangaFollow = userMangaFollowRepository.findByUserAndManga(user, manga); + userMangaFollow.ifPresent(userMangaFollowRepository::delete); + + if (!userMangaFollowRepository.existsByManga(manga)) { + manga.setFollow(false); + } + } + + public Manga findMangaByIdThrowIfNotFound(Long mangaId) { + return mangaRepository + .findById(mangaId) + .orElseThrow(() -> new NotFoundException("Manga not found for ID: " + mangaId)); + } +}