diff --git a/src/main/java/briefing/briefing/api/BriefingApi.java b/src/main/java/briefing/briefing/api/BriefingApi.java index b8810d0..02c01dd 100644 --- a/src/main/java/briefing/briefing/api/BriefingApi.java +++ b/src/main/java/briefing/briefing/api/BriefingApi.java @@ -1,8 +1,5 @@ package briefing.briefing.api; -import java.util.List; -import java.util.Optional; - import jakarta.validation.Valid; import org.springdoc.core.annotations.ParameterObject; @@ -10,15 +7,11 @@ import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; -import briefing.briefing.application.BriefingCommandService; -import briefing.briefing.application.BriefingQueryService; +import briefing.briefing.application.BriefingFacade; import briefing.briefing.application.dto.*; -import briefing.briefing.domain.Briefing; import briefing.common.aop.annotation.CacheEvictByBriefingId; -import briefing.common.enums.APIVersion; import briefing.common.response.CommonResponse; import briefing.member.domain.Member; -import briefing.scrap.application.ScrapQueryService; import briefing.security.handler.annotation.AuthMember; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -30,19 +23,14 @@ @RequiredArgsConstructor public class BriefingApi { - private final BriefingQueryService briefingQueryService; - private final BriefingCommandService briefingCommandService; - private final ScrapQueryService scrapQueryService; + private final BriefingFacade briefingFacade; @GetMapping("/briefings") @Parameter(name = "timeOfDay", hidden = true) @Operation(summary = "03-01Briefing \uD83D\uDCF0 브리핑 목록 조회 V1", description = "") public CommonResponse findBriefings( @ParameterObject @ModelAttribute BriefingRequestParam.BriefingPreviewListParam params) { - - List briefingList = briefingQueryService.findBriefings(params, APIVersion.V1); - return CommonResponse.onSuccess( - BriefingConverter.toBriefingPreviewListDTO(params.getDate(), briefingList)); + return CommonResponse.onSuccess(briefingFacade.findBriefings(params)); } @GetMapping("/briefings/{id}") @@ -50,21 +38,7 @@ public CommonResponse findBriefings( @Operation(summary = "03-02Briefing \uD83D\uDCF0 브리핑 단건 조회 V1", description = "") public CommonResponse findBriefing( @PathVariable final Long id, @AuthMember Member member) { - - Boolean isScrap = - Optional.ofNullable(member) - .map(m -> scrapQueryService.existsByMemberIdAndBriefingId(m.getId(), id)) - .orElseGet(() -> Boolean.FALSE); - - Boolean isBriefingOpen = false; - Boolean isWarning = false; - - return CommonResponse.onSuccess( - BriefingConverter.toBriefingDetailDTO( - briefingQueryService.findBriefing(id, APIVersion.V1), - isScrap, - isBriefingOpen, - isWarning)); + return CommonResponse.onSuccess(briefingFacade.findBriefing(id, member)); } @CacheEvict(value = "findBriefingsV2", key = "#request.getBriefingType()") @@ -72,7 +46,7 @@ public CommonResponse findBriefing( @ResponseStatus(HttpStatus.CREATED) @Operation(summary = "03-03Briefing \uD83D\uDCF0 브리핑 등록", description = "") public void createBriefing(@RequestBody final BriefingRequestDTO.BriefingCreate request) { - briefingCommandService.createBriefing(request); + briefingFacade.createBriefing(request); } /* @@ -92,8 +66,6 @@ public void createBriefing(@RequestBody final BriefingRequestDTO.BriefingCreate public CommonResponse patchBriefingContent( @PathVariable(name = "id") Long id, @RequestBody @Valid BriefingRequestDTO.BriefingUpdateDTO request) { - - Briefing briefing = briefingCommandService.updateBriefing(id, request); - return CommonResponse.onSuccess(BriefingConverter.toBriefingUpdateDTO(briefing)); + return CommonResponse.onSuccess(briefingFacade.updateBriefing(id, request)); } } diff --git a/src/main/java/briefing/briefing/api/BriefingV2Api.java b/src/main/java/briefing/briefing/api/BriefingV2Api.java index b887e5f..bfe3d21 100644 --- a/src/main/java/briefing/briefing/api/BriefingV2Api.java +++ b/src/main/java/briefing/briefing/api/BriefingV2Api.java @@ -1,21 +1,14 @@ package briefing.briefing.api; -import java.util.List; -import java.util.Optional; - import org.springdoc.core.annotations.ParameterObject; import org.springframework.cache.annotation.Cacheable; import org.springframework.web.bind.annotation.*; -import briefing.briefing.application.BriefingCommandService; -import briefing.briefing.application.BriefingQueryService; +import briefing.briefing.application.BriefingV2Facade; import briefing.briefing.application.dto.BriefingRequestParam; import briefing.briefing.application.dto.BriefingResponseDTO; -import briefing.briefing.domain.Briefing; -import briefing.common.enums.APIVersion; import briefing.common.response.CommonResponse; import briefing.member.domain.Member; -import briefing.scrap.application.ScrapQueryService; import briefing.security.handler.annotation.AuthMember; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -27,18 +20,14 @@ @RequiredArgsConstructor @RequestMapping("/v2") public class BriefingV2Api { - private final BriefingQueryService briefingQueryService; - private final BriefingCommandService briefingCommandService; - private final ScrapQueryService scrapQueryService; + private final BriefingV2Facade briefingFacade; @GetMapping("/briefings") @Operation(summary = "03-01Briefing \uD83D\uDCF0 브리핑 목록 조회 V2", description = "") @Cacheable(value = "findBriefingsV2", key = "#params.getType()") public CommonResponse findBriefingsV2( @ParameterObject @ModelAttribute BriefingRequestParam.BriefingPreviewListParam params) { - List briefingList = briefingQueryService.findBriefings(params, APIVersion.V2); - return CommonResponse.onSuccess( - BriefingConverter.toBriefingPreviewListDTOV2(params.getDate(), briefingList)); + return CommonResponse.onSuccess(briefingFacade.findBriefings(params)); } @GetMapping("/briefings/{id}") @@ -46,20 +35,6 @@ public CommonResponse findBriefing @Parameter(name = "member", hidden = true) public CommonResponse findBriefingV2( @PathVariable final Long id, @AuthMember Member member) { - - Boolean isScrap = - Optional.ofNullable(member) - .map(m -> scrapQueryService.existsByMemberIdAndBriefingId(m.getId(), id)) - .orElseGet(() -> Boolean.FALSE); - - Boolean isBriefingOpen = false; - Boolean isWarning = false; - - return CommonResponse.onSuccess( - BriefingConverter.toBriefingDetailDTOV2( - briefingQueryService.findBriefing(id, APIVersion.V2), - isScrap, - isBriefingOpen, - isWarning)); + return CommonResponse.onSuccess(briefingFacade.findBriefing(id, member)); } } diff --git a/src/main/java/briefing/briefing/application/BriefingCommandService.java b/src/main/java/briefing/briefing/application/BriefingCommandService.java deleted file mode 100644 index a0b5cca..0000000 --- a/src/main/java/briefing/briefing/application/BriefingCommandService.java +++ /dev/null @@ -1,53 +0,0 @@ -package briefing.briefing.application; - -import java.util.List; - -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import briefing.briefing.api.BriefingConverter; -import briefing.briefing.application.dto.BriefingRequestDTO; -import briefing.briefing.domain.Article; -import briefing.briefing.domain.Briefing; -import briefing.briefing.domain.BriefingArticle; -import briefing.briefing.domain.repository.ArticleRepository; -import briefing.briefing.domain.repository.BriefingArticleRepository; -import briefing.briefing.domain.repository.BriefingRepository; -import briefing.exception.ErrorCode; -import briefing.exception.handler.BriefingException; -import lombok.RequiredArgsConstructor; - -@Service -@Transactional -@RequiredArgsConstructor -public class BriefingCommandService { - - private final BriefingRepository briefingRepository; - private final ArticleRepository articleRepository; - private final BriefingArticleRepository briefingArticleRepository; - - public void createBriefing(final BriefingRequestDTO.BriefingCreate request) { - final Briefing briefing = BriefingConverter.toBriefing(request); - final List
articles = - request.getArticles().stream().map(BriefingConverter::toArticle).toList(); - - briefingRepository.save(briefing); - articleRepository.saveAll(articles); - - final List briefingArticles = - articles.stream().map(article -> new BriefingArticle(briefing, article)).toList(); - briefingArticleRepository.saveAll(briefingArticles); - } - - public Briefing updateBriefing(Long id, final BriefingRequestDTO.BriefingUpdateDTO request) { - - Briefing briefing = - briefingRepository - .findById(id) - .orElseThrow(() -> new BriefingException(ErrorCode.NOT_FOUND_BRIEFING)); - - briefing.updateBriefing(request.getTitle(), request.getSubTitle(), request.getContent()); - - return briefing; - } -} diff --git a/src/main/java/briefing/briefing/application/BriefingFacade.java b/src/main/java/briefing/briefing/application/BriefingFacade.java new file mode 100644 index 0000000..0d947ff --- /dev/null +++ b/src/main/java/briefing/briefing/application/BriefingFacade.java @@ -0,0 +1,82 @@ +package briefing.briefing.application; + +import java.util.List; +import java.util.Optional; + +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import briefing.briefing.api.BriefingConverter; +import briefing.briefing.application.dto.BriefingRequestDTO; +import briefing.briefing.application.dto.BriefingRequestParam; +import briefing.briefing.application.dto.BriefingResponseDTO; +import briefing.briefing.application.service.ArticleCommandService; +import briefing.briefing.application.service.BriefingArticleCommandService; +import briefing.briefing.application.service.BriefingCommandService; +import briefing.briefing.application.service.BriefingQueryService; +import briefing.briefing.domain.Article; +import briefing.briefing.domain.Briefing; +import briefing.briefing.domain.BriefingArticle; +import briefing.common.enums.APIVersion; +import briefing.member.domain.Member; +import briefing.scrap.application.ScrapQueryService; +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +public class BriefingFacade { + private final ScrapQueryService scrapQueryService; + private final BriefingQueryService briefingQueryService; + private final BriefingCommandService briefingCommandService; + private final ArticleCommandService articleCommandService; + private final BriefingArticleCommandService briefingArticleCommandService; + private static final APIVersion version = APIVersion.V1; + + @Transactional(readOnly = true) + public BriefingResponseDTO.BriefingPreviewListDTO findBriefings( + BriefingRequestParam.BriefingPreviewListParam params) { + List briefingList = briefingQueryService.findBriefings(params, version); + return BriefingConverter.toBriefingPreviewListDTO(params.getDate(), briefingList); + } + + @Transactional(readOnly = true) + public BriefingResponseDTO.BriefingDetailDTO findBriefing(final Long id, Member member) { + Boolean isScrap = + Optional.ofNullable(member) + .map(m -> scrapQueryService.existsByMemberIdAndBriefingId(m.getId(), id)) + .orElseGet(() -> Boolean.FALSE); + + Boolean isBriefingOpen = false; + Boolean isWarning = false; + + return BriefingConverter.toBriefingDetailDTO( + briefingQueryService.findBriefing(id, version), isScrap, isBriefingOpen, isWarning); + } + + @Transactional + public void createBriefing(final BriefingRequestDTO.BriefingCreate request) { + final List
articles = + request.getArticles().stream().map(BriefingConverter::toArticle).toList(); + + Briefing createdBriefing = + briefingCommandService.create(BriefingConverter.toBriefing(request)); + List
createdArticles = articleCommandService.createAll(articles); + + final List briefingArticles = + createdArticles.stream() + .map(article -> new BriefingArticle(createdBriefing, article)) + .toList(); + + briefingArticleCommandService.createAll(briefingArticles); + } + + @Transactional + public BriefingResponseDTO.BriefingUpdateDTO updateBriefing( + Long id, final BriefingRequestDTO.BriefingUpdateDTO request) { + Briefing briefing = briefingQueryService.findBriefing(id, APIVersion.V1); + Briefing updatedBriefing = + briefingCommandService.update( + briefing, request.getTitle(), request.getSubTitle(), request.getContent()); + return BriefingConverter.toBriefingUpdateDTO(updatedBriefing); + } +} diff --git a/src/main/java/briefing/briefing/application/BriefingV2Facade.java b/src/main/java/briefing/briefing/application/BriefingV2Facade.java new file mode 100644 index 0000000..0051bce --- /dev/null +++ b/src/main/java/briefing/briefing/application/BriefingV2Facade.java @@ -0,0 +1,47 @@ +package briefing.briefing.application; + +import java.util.List; +import java.util.Optional; + +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import briefing.briefing.api.BriefingConverter; +import briefing.briefing.application.dto.BriefingRequestParam; +import briefing.briefing.application.dto.BriefingResponseDTO; +import briefing.briefing.application.service.BriefingQueryService; +import briefing.briefing.domain.Briefing; +import briefing.common.enums.APIVersion; +import briefing.member.domain.Member; +import briefing.scrap.application.ScrapQueryService; +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +public class BriefingV2Facade { + + private final BriefingQueryService briefingQueryService; + private final ScrapQueryService scrapQueryService; + private static final APIVersion version = APIVersion.V2; + + @Transactional(readOnly = true) + public BriefingResponseDTO.BriefingPreviewListDTOV2 findBriefings( + BriefingRequestParam.BriefingPreviewListParam params) { + List briefingList = briefingQueryService.findBriefings(params, version); + return BriefingConverter.toBriefingPreviewListDTOV2(params.getDate(), briefingList); + } + + @Transactional(readOnly = true) + public BriefingResponseDTO.BriefingDetailDTOV2 findBriefing(final Long id, Member member) { + Boolean isScrap = + Optional.ofNullable(member) + .map(m -> scrapQueryService.existsByMemberIdAndBriefingId(m.getId(), id)) + .orElseGet(() -> Boolean.FALSE); + + Boolean isBriefingOpen = false; + Boolean isWarning = false; + + return BriefingConverter.toBriefingDetailDTOV2( + briefingQueryService.findBriefing(id, version), isScrap, isBriefingOpen, isWarning); + } +} diff --git a/src/main/java/briefing/briefing/application/service/ArticleCommandService.java b/src/main/java/briefing/briefing/application/service/ArticleCommandService.java new file mode 100644 index 0000000..d60a183 --- /dev/null +++ b/src/main/java/briefing/briefing/application/service/ArticleCommandService.java @@ -0,0 +1,19 @@ +package briefing.briefing.application.service; + +import java.util.List; + +import org.springframework.stereotype.Service; + +import briefing.briefing.domain.Article; +import briefing.briefing.domain.repository.ArticleRepository; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class ArticleCommandService { + private final ArticleRepository articleRepository; + + public List
createAll(final List
articles) { + return articleRepository.saveAll(articles); + } +} diff --git a/src/main/java/briefing/briefing/application/service/BriefingArticleCommandService.java b/src/main/java/briefing/briefing/application/service/BriefingArticleCommandService.java new file mode 100644 index 0000000..fb44963 --- /dev/null +++ b/src/main/java/briefing/briefing/application/service/BriefingArticleCommandService.java @@ -0,0 +1,19 @@ +package briefing.briefing.application.service; + +import java.util.List; + +import org.springframework.stereotype.Service; + +import briefing.briefing.domain.BriefingArticle; +import briefing.briefing.domain.repository.BriefingArticleRepository; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class BriefingArticleCommandService { + private final BriefingArticleRepository briefingArticleRepository; + + public List createAll(final List briefingArticles) { + return briefingArticleRepository.saveAll(briefingArticles); + } +} diff --git a/src/main/java/briefing/briefing/application/service/BriefingCommandService.java b/src/main/java/briefing/briefing/application/service/BriefingCommandService.java new file mode 100644 index 0000000..4d9f1ab --- /dev/null +++ b/src/main/java/briefing/briefing/application/service/BriefingCommandService.java @@ -0,0 +1,24 @@ +package briefing.briefing.application.service; + +import org.springframework.stereotype.Service; + +import briefing.briefing.domain.Briefing; +import briefing.briefing.domain.repository.BriefingRepository; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class BriefingCommandService { + + private final BriefingRepository briefingRepository; + + public Briefing create(final Briefing briefing) { + return briefingRepository.save(briefing); + } + + public Briefing update( + Briefing briefing, final String title, final String subTitle, final String content) { + briefing.updateBriefing(title, subTitle, content); + return briefing; + } +} diff --git a/src/main/java/briefing/briefing/application/BriefingQueryService.java b/src/main/java/briefing/briefing/application/service/BriefingQueryService.java similarity index 90% rename from src/main/java/briefing/briefing/application/BriefingQueryService.java rename to src/main/java/briefing/briefing/application/service/BriefingQueryService.java index 931245a..1b90db0 100644 --- a/src/main/java/briefing/briefing/application/BriefingQueryService.java +++ b/src/main/java/briefing/briefing/application/service/BriefingQueryService.java @@ -1,9 +1,8 @@ -package briefing.briefing.application; +package briefing.briefing.application.service; import java.util.List; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; import briefing.briefing.application.context.BriefingQueryContext; import briefing.briefing.application.context.BriefingQueryContextFactory; @@ -15,7 +14,6 @@ import lombok.RequiredArgsConstructor; @Service -@Transactional(readOnly = true) @RequiredArgsConstructor public class BriefingQueryService { diff --git a/src/test/java/briefing/briefing/application/BriefingQueryServiceTest.java b/src/test/java/briefing/briefing/application/BriefingQueryServiceTest.java index ff0dba9..72e0c91 100644 --- a/src/test/java/briefing/briefing/application/BriefingQueryServiceTest.java +++ b/src/test/java/briefing/briefing/application/BriefingQueryServiceTest.java @@ -18,6 +18,7 @@ import org.springframework.test.context.jdbc.Sql; import org.springframework.test.context.jdbc.Sql.ExecutionPhase; +import briefing.briefing.application.service.BriefingQueryService; import briefing.briefing.domain.Article; import briefing.briefing.domain.Briefing; import briefing.briefing.domain.BriefingArticle;