From 1a252ca43c075926f3c59031bee849e81a45ed4a Mon Sep 17 00:00:00 2001 From: kdomo Date: Thu, 2 Nov 2023 21:27:15 +0900 Subject: [PATCH 1/2] =?UTF-8?q?[#134]=20feat:=20=EC=8B=A4=ED=8C=A8?= =?UTF-8?q?=EA=B8=B0=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domains/failure/domain/Failure.java | 9 ++++ .../failure/service/FailureDomainService.java | 30 ++++++++----- .../api/web/failure/FailureController.java | 11 +++++ .../dto/request/FailureModifyRequest.java | 16 +++++++ .../failure/usecase/FailureModifyUseCase.java | 44 +++++++++++++++++++ 5 files changed, 100 insertions(+), 10 deletions(-) create mode 100644 TodaysFail-Interface/src/main/java/com/todaysfail/api/web/failure/dto/request/FailureModifyRequest.java create mode 100644 TodaysFail-Interface/src/main/java/com/todaysfail/api/web/failure/usecase/FailureModifyUseCase.java diff --git a/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/domain/Failure.java b/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/domain/Failure.java index 2c5ad39..74ebb33 100644 --- a/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/domain/Failure.java +++ b/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/domain/Failure.java @@ -62,4 +62,13 @@ public void validateOwnership(Long userId) { throw FailureOwnedByUserException.EXCEPTION; } } + + public void modify(Failure failure) { + this.categoryId = failure.getCategoryId(); + this.failureDate = failure.getFailureDate(); + this.title = failure.getTitle(); + this.content = failure.getContent(); + this.tags = failure.getTags(); + this.secret = failure.isSecret(); + } } diff --git a/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/service/FailureDomainService.java b/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/service/FailureDomainService.java index 55107c3..65e8a00 100644 --- a/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/service/FailureDomainService.java +++ b/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/service/FailureDomainService.java @@ -39,6 +39,26 @@ public Failure register(final Failure failure, Category category, List tags return failureCommandPort.save(failure); } + @Transactional + @RedissonLock(lockName = "실패좋아요", identifier = "failureId") + public void likeFailure(Long userId, Long failureId) { + Failure failure = failureCommandPort.queryFailure(failureId); + failure.validateOwnership(userId); + failure.like(); + failureLikeQueryPort.checkAlreadyLiked(userId, failureId); + failureLikeCommandPort.save(FailureLike.of(userId, failureId)); + } + + @Transactional + public Failure modifyFailure(Long failureId, Failure failure, Category category) { + validateFailureTagSize(failure.getTags()); + validateFailureDate(failure.getFailureDate()); + category.validateOwnership(failure.getUserId()); + Failure originFailure = failureCommandPort.queryFailure(failureId); + originFailure.modify(failure); + return originFailure; + } + private void validateFailureTagSize(List tags) { /** 태그는 최대 3개까지만 등록 가능하다. */ if (tags.size() > 3) { @@ -51,14 +71,4 @@ private void validateFailureDate(LocalDate date) { throw FutureFailureDateException.EXCEPTION; } } - - @Transactional - @RedissonLock(lockName = "실패좋아요", identifier = "failureId") - public void likeFailure(Long userId, Long failureId) { - Failure failure = failureCommandPort.queryFailure(failureId); - failure.validateOwnership(userId); - failure.like(); - failureLikeQueryPort.checkAlreadyLiked(userId, failureId); - failureLikeCommandPort.save(FailureLike.of(userId, failureId)); - } } diff --git a/TodaysFail-Interface/src/main/java/com/todaysfail/api/web/failure/FailureController.java b/TodaysFail-Interface/src/main/java/com/todaysfail/api/web/failure/FailureController.java index 8fbb423..cd84e63 100644 --- a/TodaysFail-Interface/src/main/java/com/todaysfail/api/web/failure/FailureController.java +++ b/TodaysFail-Interface/src/main/java/com/todaysfail/api/web/failure/FailureController.java @@ -1,6 +1,7 @@ package com.todaysfail.api.web.failure; import com.todaysfail.api.web.common.SliceResponse; +import com.todaysfail.api.web.failure.dto.request.FailureModifyRequest; import com.todaysfail.api.web.failure.dto.request.FailureRegisterRequest; import com.todaysfail.api.web.failure.dto.response.FailureByCategoryResponse; import com.todaysfail.api.web.failure.dto.response.FailureMonthlyDailyStatusResponse; @@ -8,6 +9,7 @@ import com.todaysfail.api.web.failure.usecase.FailureByCategoryQueryUseCase; import com.todaysfail.api.web.failure.usecase.FailureFeedQueryUseCase; import com.todaysfail.api.web.failure.usecase.FailureLikeUseCase; +import com.todaysfail.api.web.failure.usecase.FailureModifyUseCase; import com.todaysfail.api.web.failure.usecase.FailureMonthlyDailyStatusUseCase; import com.todaysfail.api.web.failure.usecase.FailureRegisterUseCase; import io.swagger.v3.oas.annotations.Operation; @@ -24,6 +26,7 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -36,6 +39,7 @@ @RequiredArgsConstructor public class FailureController { private final FailureRegisterUseCase failureRegisterUseCase; + private final FailureModifyUseCase failureModifyUseCase; private final FailureFeedQueryUseCase failureFeedQueryUseCase; private final FailureLikeUseCase failureLikeUseCase; private final FailureMonthlyDailyStatusUseCase failureMonthlyDailyStatusUseCase; @@ -47,6 +51,13 @@ public FailureResponse registerFailure(@RequestBody @Valid FailureRegisterReques return failureRegisterUseCase.execute(request); } + @Operation(summary = "실패 수정") + @PutMapping("/{failureId}") + public FailureResponse modifyFailure( + @PathVariable Long failureId, @RequestBody FailureModifyRequest request) { + return failureModifyUseCase.execute(failureId, request); + } + @Operation(summary = "피드") @GetMapping("/feed") public SliceResponse queryFeed( diff --git a/TodaysFail-Interface/src/main/java/com/todaysfail/api/web/failure/dto/request/FailureModifyRequest.java b/TodaysFail-Interface/src/main/java/com/todaysfail/api/web/failure/dto/request/FailureModifyRequest.java new file mode 100644 index 0000000..2f2e619 --- /dev/null +++ b/TodaysFail-Interface/src/main/java/com/todaysfail/api/web/failure/dto/request/FailureModifyRequest.java @@ -0,0 +1,16 @@ +package com.todaysfail.api.web.failure.dto.request; + +import java.time.LocalDate; +import java.util.Set; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import org.springframework.format.annotation.DateTimeFormat; + +public record FailureModifyRequest( + @NotNull Long categoryId, + @NotNull @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate date, + @NotNull @Size(min = 1, max = 50) String title, + @NotNull @Size(min = 1, max = 500) String content, + @NotNull @Size(min = 1, max = 500) String impression, + @NotNull @Size(min = 1, max = 3) Set tagNameSet, + @NotNull boolean secret) {} diff --git a/TodaysFail-Interface/src/main/java/com/todaysfail/api/web/failure/usecase/FailureModifyUseCase.java b/TodaysFail-Interface/src/main/java/com/todaysfail/api/web/failure/usecase/FailureModifyUseCase.java new file mode 100644 index 0000000..52933af --- /dev/null +++ b/TodaysFail-Interface/src/main/java/com/todaysfail/api/web/failure/usecase/FailureModifyUseCase.java @@ -0,0 +1,44 @@ +package com.todaysfail.api.web.failure.usecase; + +import com.todaysfail.api.web.failure.dto.request.FailureModifyRequest; +import com.todaysfail.api.web.failure.dto.response.FailureResponse; +import com.todaysfail.api.web.failure.mapper.FailureMapper; +import com.todaysfail.common.annotation.UseCase; +import com.todaysfail.config.security.SecurityUtils; +import com.todaysfail.domains.category.domain.Category; +import com.todaysfail.domains.category.port.CategoryQueryPort; +import com.todaysfail.domains.failure.domain.Failure; +import com.todaysfail.domains.failure.service.FailureDomainService; +import com.todaysfail.domains.tag.domain.Tag; +import com.todaysfail.domains.tag.service.TagDomainService; +import java.util.List; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; + +@UseCase +@RequiredArgsConstructor +public class FailureModifyUseCase { + private final FailureMapper failureMapper; + private final FailureDomainService failureDomainService; + private final TagDomainService tagDomainService; + private final CategoryQueryPort categoryQueryPort; + + public FailureResponse execute(final Long failureId, final FailureModifyRequest request) { + final Long userId = SecurityUtils.getCurrentUserId(); + List tags = tagDomainService.saveAndRetrieveAllTags(request.tagNameSet()); + Category category = categoryQueryPort.queryCategory(request.categoryId()); + Failure failure = + Failure.builder() + .userId(userId) + .categoryId(request.categoryId()) + .failureDate(request.date()) + .title(request.title()) + .content(request.content()) + .impression(request.impression()) + .tags(tags.stream().map(Tag::getId).collect(Collectors.toList())) + .secret(request.secret()) + .build(); + Failure modifyFailure = failureDomainService.modifyFailure(failureId, failure, category); + return failureMapper.toFailureResponse(modifyFailure); + } +} From d2a4624a6daab018b0b7d03a07c3076755a152b8 Mon Sep 17 00:00:00 2001 From: kdomo Date: Thu, 2 Nov 2023 21:35:28 +0900 Subject: [PATCH 2/2] =?UTF-8?q?[#134]=20feat:=20=EC=8B=A4=ED=8C=A8=20?= =?UTF-8?q?=EA=B8=B0=EB=A1=9D=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../failure/adapter/FailureCommandAdapter.java | 5 +++++ .../domains/failure/domain/Failure.java | 7 +++---- .../failure/exception/FailureErrorCode.java | 2 +- .../FailureNotOwnedByUserException.java | 11 +++++++++++ .../exception/FailureOwnedByUserException.java | 11 ----------- .../failure/port/FailureCommandPort.java | 2 ++ .../failure/service/FailureDomainService.java | 7 ++++++- .../api/web/failure/FailureController.java | 9 +++++++++ .../failure/usecase/FailureDeleteUseCase.java | 17 +++++++++++++++++ 9 files changed, 54 insertions(+), 17 deletions(-) create mode 100644 TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/exception/FailureNotOwnedByUserException.java delete mode 100644 TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/exception/FailureOwnedByUserException.java create mode 100644 TodaysFail-Interface/src/main/java/com/todaysfail/api/web/failure/usecase/FailureDeleteUseCase.java diff --git a/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/adapter/FailureCommandAdapter.java b/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/adapter/FailureCommandAdapter.java index 8541204..0d100f8 100644 --- a/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/adapter/FailureCommandAdapter.java +++ b/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/adapter/FailureCommandAdapter.java @@ -25,4 +25,9 @@ public Failure queryFailure(Long failureId) { .findById(failureId) .orElseThrow(() -> FailureNotFoundException.EXCEPTION); } + + @Override + public void delete(Failure failure) { + failureRepository.delete(failure); + } } diff --git a/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/domain/Failure.java b/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/domain/Failure.java index 74ebb33..2e904f4 100644 --- a/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/domain/Failure.java +++ b/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/domain/Failure.java @@ -2,7 +2,7 @@ import com.todaysfail.common.BaseTimeEntity; import com.todaysfail.config.converter.LongArrayConverter; -import com.todaysfail.domains.failure.exception.FailureOwnedByUserException; +import com.todaysfail.domains.failure.exception.FailureNotOwnedByUserException; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; @@ -57,9 +57,8 @@ public void like() { } public void validateOwnership(Long userId) { - // 본인이 생성 한 실패 기록일 경우 - if (this.userId.equals(userId)) { - throw FailureOwnedByUserException.EXCEPTION; + if (!this.userId.equals(userId)) { + throw FailureNotOwnedByUserException.EXCEPTION; } } diff --git a/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/exception/FailureErrorCode.java b/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/exception/FailureErrorCode.java index ba22b27..47abf2c 100644 --- a/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/exception/FailureErrorCode.java +++ b/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/exception/FailureErrorCode.java @@ -20,7 +20,7 @@ public enum FailureErrorCode implements BaseErrorCode { FAILURE_DATE_IS_FUTURE(NOT_FOUND, "FAILURE_400_2", "입력 한 날짜가 미래일 수 없습니다."), @ExplainError("본인이 생성한 실패 기록 입니다.") - FAILURE_OWNED_BY_USER(BAD_REQUEST, "FAILURE_400_3", "본인이 생성한 실패 기록 입니다."), + FAILURE_NOT_OWNED_BY_USER(BAD_REQUEST, "FAILURE_400_3", "본인이 생성한 실패 기록이 아닙니다."), ; private Integer status; diff --git a/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/exception/FailureNotOwnedByUserException.java b/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/exception/FailureNotOwnedByUserException.java new file mode 100644 index 0000000..0eed409 --- /dev/null +++ b/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/exception/FailureNotOwnedByUserException.java @@ -0,0 +1,11 @@ +package com.todaysfail.domains.failure.exception; + +import com.todaysfail.common.exception.TodaysFailCodeException; + +public class FailureNotOwnedByUserException extends TodaysFailCodeException { + public static final TodaysFailCodeException EXCEPTION = new FailureNotOwnedByUserException(); + + public FailureNotOwnedByUserException() { + super(FailureErrorCode.FAILURE_NOT_OWNED_BY_USER); + } +} diff --git a/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/exception/FailureOwnedByUserException.java b/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/exception/FailureOwnedByUserException.java deleted file mode 100644 index 5599271..0000000 --- a/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/exception/FailureOwnedByUserException.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.todaysfail.domains.failure.exception; - -import com.todaysfail.common.exception.TodaysFailCodeException; - -public class FailureOwnedByUserException extends TodaysFailCodeException { - public static final TodaysFailCodeException EXCEPTION = new FailureOwnedByUserException(); - - public FailureOwnedByUserException() { - super(FailureErrorCode.FAILURE_OWNED_BY_USER); - } -} diff --git a/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/port/FailureCommandPort.java b/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/port/FailureCommandPort.java index 9f7a024..212c68c 100644 --- a/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/port/FailureCommandPort.java +++ b/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/port/FailureCommandPort.java @@ -6,4 +6,6 @@ public interface FailureCommandPort { Failure save(Failure failure); Failure queryFailure(Long failureId); + + void delete(Failure failure); } diff --git a/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/service/FailureDomainService.java b/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/service/FailureDomainService.java index 65e8a00..75fd83c 100644 --- a/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/service/FailureDomainService.java +++ b/TodaysFail-Domain/src/main/java/com/todaysfail/domains/failure/service/FailureDomainService.java @@ -43,7 +43,6 @@ public Failure register(final Failure failure, Category category, List tags @RedissonLock(lockName = "실패좋아요", identifier = "failureId") public void likeFailure(Long userId, Long failureId) { Failure failure = failureCommandPort.queryFailure(failureId); - failure.validateOwnership(userId); failure.like(); failureLikeQueryPort.checkAlreadyLiked(userId, failureId); failureLikeCommandPort.save(FailureLike.of(userId, failureId)); @@ -71,4 +70,10 @@ private void validateFailureDate(LocalDate date) { throw FutureFailureDateException.EXCEPTION; } } + + public void deleteFailure(final Long failureId, final Long userId) { + Failure failure = failureCommandPort.queryFailure(failureId); + failure.validateOwnership(userId); + failureCommandPort.delete(failure); + } } diff --git a/TodaysFail-Interface/src/main/java/com/todaysfail/api/web/failure/FailureController.java b/TodaysFail-Interface/src/main/java/com/todaysfail/api/web/failure/FailureController.java index cd84e63..89dd9db 100644 --- a/TodaysFail-Interface/src/main/java/com/todaysfail/api/web/failure/FailureController.java +++ b/TodaysFail-Interface/src/main/java/com/todaysfail/api/web/failure/FailureController.java @@ -7,6 +7,7 @@ import com.todaysfail.api.web.failure.dto.response.FailureMonthlyDailyStatusResponse; import com.todaysfail.api.web.failure.dto.response.FailureResponse; import com.todaysfail.api.web.failure.usecase.FailureByCategoryQueryUseCase; +import com.todaysfail.api.web.failure.usecase.FailureDeleteUseCase; import com.todaysfail.api.web.failure.usecase.FailureFeedQueryUseCase; import com.todaysfail.api.web.failure.usecase.FailureLikeUseCase; import com.todaysfail.api.web.failure.usecase.FailureModifyUseCase; @@ -23,6 +24,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.web.PageableDefault; import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; @@ -44,6 +46,7 @@ public class FailureController { private final FailureLikeUseCase failureLikeUseCase; private final FailureMonthlyDailyStatusUseCase failureMonthlyDailyStatusUseCase; private final FailureByCategoryQueryUseCase failureByCategoryQueryUseCase; + private final FailureDeleteUseCase failureDeleteUseCase; @Operation(summary = "실패 등록") @PostMapping @@ -58,6 +61,12 @@ public FailureResponse modifyFailure( return failureModifyUseCase.execute(failureId, request); } + @Operation(summary = "실패 삭제") + @DeleteMapping("/{failureId}") + public void deleteFailure(@PathVariable Long failureId) { + failureDeleteUseCase.execute(failureId); + } + @Operation(summary = "피드") @GetMapping("/feed") public SliceResponse queryFeed( diff --git a/TodaysFail-Interface/src/main/java/com/todaysfail/api/web/failure/usecase/FailureDeleteUseCase.java b/TodaysFail-Interface/src/main/java/com/todaysfail/api/web/failure/usecase/FailureDeleteUseCase.java new file mode 100644 index 0000000..3e123d3 --- /dev/null +++ b/TodaysFail-Interface/src/main/java/com/todaysfail/api/web/failure/usecase/FailureDeleteUseCase.java @@ -0,0 +1,17 @@ +package com.todaysfail.api.web.failure.usecase; + +import com.todaysfail.common.annotation.UseCase; +import com.todaysfail.config.security.SecurityUtils; +import com.todaysfail.domains.failure.service.FailureDomainService; +import lombok.RequiredArgsConstructor; + +@UseCase +@RequiredArgsConstructor +public class FailureDeleteUseCase { + private final FailureDomainService failureDomainService; + + public void execute(final Long failureId) { + final Long userId = SecurityUtils.getCurrentUserId(); + failureDomainService.deleteFailure(failureId, userId); + } +}