Skip to content

Commit

Permalink
✨ Scrap V2 요구사항 반영
Browse files Browse the repository at this point in the history
  • Loading branch information
swa07016 committed Jan 1, 2024
1 parent e1a7089 commit f44395a
Show file tree
Hide file tree
Showing 12 changed files with 175 additions and 72 deletions.
4 changes: 2 additions & 2 deletions src/main/java/briefing/exception/ExceptionAdvice.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
@RestControllerAdvice(annotations = {RestController.class})
public class ExceptionAdvice extends ResponseEntityExceptionHandler {

@org.springframework.web.bind.annotation.ExceptionHandler
@ExceptionHandler
public ResponseEntity<Object> validation(ConstraintViolationException e, WebRequest request) {
String errorMessage =
e.getConstraintViolations().stream()
Expand Down Expand Up @@ -73,7 +73,7 @@ public ResponseEntity<Object> handleMethodArgumentNotValid(
ex, HttpHeaders.EMPTY, ErrorCode.valueOf("_BAD_REQUEST"), request, errors);
}

@org.springframework.web.bind.annotation.ExceptionHandler
@ExceptionHandler
public ResponseEntity<Object> exception(Exception e, WebRequest request) {
e.printStackTrace();

Expand Down
21 changes: 21 additions & 0 deletions src/main/java/briefing/scrap/api/ScrapConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import briefing.briefing.domain.Briefing;
import briefing.member.domain.Member;
import briefing.scrap.application.dto.ScrapResponse;
import briefing.scrap.application.dto.ScrapV2;
import briefing.scrap.domain.Scrap;

public class ScrapConverter {
Expand All @@ -17,6 +18,17 @@ public static ScrapResponse.CreateDTO toCreateDTO(Scrap createdScrap) {
.build();
}

public static ScrapResponse.CreateDTOV2 toCreateDTOV2(ScrapV2 createdScrap) {
return ScrapResponse.CreateDTOV2.builder()
.scrapId(createdScrap.getId())
.memberId(createdScrap.getMember().getId())
.briefingId(createdScrap.getBriefing().getId())
.scrapCount(createdScrap.getScrapCount())
.isScrap(createdScrap.getIsScrap())
.createdAt(createdScrap.getCreatedAt())
.build();
}

public static Scrap toScrap(Member member, Briefing briefing) {
return Scrap.builder().member(member).briefing(briefing).build();
}
Expand All @@ -28,6 +40,15 @@ public static ScrapResponse.DeleteDTO toDeleteDTO(Scrap deletedScrap) {
.build();
}

public static ScrapResponse.DeleteDTOV2 toDeleteDTOV2(ScrapV2 deletedScrap) {
return ScrapResponse.DeleteDTOV2.builder()
.scrapId(deletedScrap.getId())
.isScrap(deletedScrap.getIsScrap())
.scrapCount(deletedScrap.getScrapCount())
.deletedAt(LocalDateTime.now())
.build();
}

public static ScrapResponse.ReadDTO toReadDTO(Scrap scrap) {
return ScrapResponse.ReadDTO.builder()
.briefingId(scrap.getBriefing().getId())
Expand Down
9 changes: 5 additions & 4 deletions src/main/java/briefing/scrap/api/ScrapV2Api.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import briefing.scrap.application.ScrapQueryService;
import briefing.scrap.application.dto.ScrapRequest;
import briefing.scrap.application.dto.ScrapResponse;
import briefing.scrap.application.dto.ScrapV2;
import briefing.scrap.domain.Scrap;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
Expand All @@ -25,18 +26,18 @@ public class ScrapV2Api {

@Operation(summary = "05-01 Scrap📁 스크랩하기 V2", description = "브리핑을 스크랩하는 API입니다.")
@PostMapping("/scraps/briefings")
public CommonResponse<ScrapResponse.CreateDTO> createV2(
public CommonResponse<ScrapResponse.CreateDTOV2> createV2(
@RequestBody ScrapRequest.CreateDTO request) {
Scrap createdScrap = scrapCommandService.create(request, APIVersion.V2);
return CommonResponse.onSuccess(ScrapConverter.toCreateDTO(createdScrap));
return CommonResponse.onSuccess(ScrapConverter.toCreateDTOV2((ScrapV2) createdScrap));
}

@Operation(summary = "05-02 Scrap📁 스크랩 취소 V2", description = "스크랩을 취소하는 API입니다.")
@DeleteMapping("/scraps/briefings/{briefingId}/members/{memberId}")
public CommonResponse<ScrapResponse.DeleteDTO> deleteV2(
public CommonResponse<ScrapResponse.DeleteDTOV2> deleteV2(
@PathVariable Long briefingId, @PathVariable Long memberId) {
Scrap deletedScrap = scrapCommandService.delete(briefingId, memberId, APIVersion.V2);
return CommonResponse.onSuccess(ScrapConverter.toDeleteDTO(deletedScrap));
return CommonResponse.onSuccess(ScrapConverter.toDeleteDTOV2((ScrapV2) deletedScrap));
}

@Operation(summary = "05-03 Scrap📁 내 스크랩 조회 V2", description = "내 스크랩을 조회하는 API입니다.")
Expand Down
24 changes: 24 additions & 0 deletions src/main/java/briefing/scrap/application/dto/ScrapResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,19 @@ public static class CreateDTO {
private LocalDateTime createdAt;
}

@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
public static class CreateDTOV2 {
private Long scrapId;
private Long memberId;
private Long briefingId;
private Boolean isScrap;
private Integer scrapCount;
private LocalDateTime createdAt;
}

@Builder
@Getter
@NoArgsConstructor
Expand All @@ -32,6 +45,17 @@ public static class DeleteDTO {
private LocalDateTime deletedAt;
}

@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
public static class DeleteDTOV2 {
private Long scrapId;
private Boolean isScrap;
private Integer scrapCount;
private LocalDateTime deletedAt;
}

@Builder
@Getter
@NoArgsConstructor
Expand Down
26 changes: 26 additions & 0 deletions src/main/java/briefing/scrap/application/dto/ScrapV2.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package briefing.scrap.application.dto;

import java.time.LocalDateTime;

import briefing.scrap.domain.Scrap;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class ScrapV2 extends Scrap {
private Integer scrapCount;
private Boolean isScrap;
private LocalDateTime createdAt;

private ScrapV2(Scrap scrap, Integer scrapCount, Boolean isScrap) {
super(scrap.getId(), scrap.getMember(), scrap.getBriefing());
this.scrapCount = scrapCount;
this.isScrap = isScrap;
this.createdAt = scrap.getCreatedAt();
}

public static ScrapV2 of(Scrap scrap, Integer scrapCount, Boolean isScrap) {
return new ScrapV2(scrap, scrapCount, isScrap);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,11 @@
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Component;

import briefing.briefing.domain.Briefing;
import briefing.briefing.domain.repository.BriefingRepository;
import briefing.common.enums.APIVersion;
import briefing.exception.ErrorCode;
import briefing.exception.handler.BriefingException;
import briefing.member.domain.Member;
import briefing.member.domain.repository.MemberRepository;
import briefing.member.exception.MemberException;
import briefing.scrap.api.ScrapConverter;
import briefing.scrap.application.dto.ScrapRequest;
import briefing.scrap.application.strategy.helper.ScrapCreationHelper;
import briefing.scrap.application.strategy.helper.ScrapDeletionHelper;
import briefing.scrap.domain.Scrap;
import briefing.scrap.domain.repository.ScrapRepository;
import briefing.scrap.exception.ScrapException;
Expand All @@ -22,30 +17,14 @@
@RequiredArgsConstructor
public class ScrapV1CommandStrategy implements ScrapCommandStrategy {

private final ScrapCreationHelper scrapCreationHelper;
private final ScrapDeletionHelper scrapDeletionHelper;
private final ScrapRepository scrapRepository;
private final MemberRepository memberRepository;
private final BriefingRepository briefingRepository;

@Override
public Scrap create(ScrapRequest.CreateDTO request) {
// 이미 스크랩한경우
if (scrapRepository.existsByMember_IdAndBriefing_Id(
request.getMemberId(), request.getBriefingId()))
throw new ScrapException(ErrorCode.SCRAP_ALREADY_EXISTS);
Scrap scrap = scrapCreationHelper.createScrap(request);

Member member =
memberRepository
.findById(request.getMemberId())
.orElseThrow(() -> new MemberException(ErrorCode.MEMBER_NOT_FOUND));

Briefing briefing =
briefingRepository
.findById(request.getBriefingId())
.orElseThrow(() -> new BriefingException(ErrorCode.NOT_FOUND_BRIEFING));

Scrap scrap = ScrapConverter.toScrap(member, briefing);

// Scrap 엔티티 저장 및 반환
try {
// Scrap 엔티티 저장 및 반환
return scrapRepository.save(scrap);
Expand All @@ -57,12 +36,7 @@ public Scrap create(ScrapRequest.CreateDTO request) {

@Override
public Scrap delete(Long briefingId, Long memberId) {
Scrap scrap =
scrapRepository
.findByBriefing_IdAndMember_Id(briefingId, memberId)
.orElseThrow(() -> new ScrapException(ErrorCode.SCRAP_NOT_FOUND));
scrapRepository.delete(scrap);
return scrap;
return scrapDeletionHelper.deleteScrap(briefingId, memberId);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,12 @@
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Component;

import briefing.briefing.domain.Briefing;
import briefing.briefing.domain.repository.BriefingRepository;
import briefing.common.enums.APIVersion;
import briefing.exception.ErrorCode;
import briefing.exception.handler.BriefingException;
import briefing.member.domain.Member;
import briefing.member.domain.repository.MemberRepository;
import briefing.member.exception.MemberException;
import briefing.scrap.api.ScrapConverter;
import briefing.scrap.application.dto.ScrapRequest;
import briefing.scrap.application.dto.ScrapV2;
import briefing.scrap.application.strategy.helper.ScrapCreationHelper;
import briefing.scrap.application.strategy.helper.ScrapDeletionHelper;
import briefing.scrap.domain.Scrap;
import briefing.scrap.domain.repository.ScrapRepository;
import briefing.scrap.exception.ScrapException;
Expand All @@ -22,33 +18,19 @@
@RequiredArgsConstructor
public class ScrapV2CommandStrategy implements ScrapCommandStrategy {

private final ScrapCreationHelper scrapCreationHelper;
private final ScrapDeletionHelper scrapDeletionHelper;
private final ScrapRepository scrapRepository;
private final MemberRepository memberRepository;
private final BriefingRepository briefingRepository;

@Override
public Scrap create(ScrapRequest.CreateDTO request) {
// 이미 스크랩한경우
if (scrapRepository.existsByMember_IdAndBriefing_Id(
request.getMemberId(), request.getBriefingId()))
throw new ScrapException(ErrorCode.SCRAP_ALREADY_EXISTS);
Scrap scrap = scrapCreationHelper.createScrap(request);

Member member =
memberRepository
.findById(request.getMemberId())
.orElseThrow(() -> new MemberException(ErrorCode.MEMBER_NOT_FOUND));

Briefing briefing =
briefingRepository
.findById(request.getBriefingId())
.orElseThrow(() -> new BriefingException(ErrorCode.NOT_FOUND_BRIEFING));

Scrap scrap = ScrapConverter.toScrap(member, briefing);

// Scrap 엔티티 저장 및 반환
try {
// Scrap 엔티티 저장 및 반환
return scrapRepository.save(scrap);
Scrap savedScrap = scrapRepository.save(scrap);
Integer scrapCount = scrapRepository.countByBriefing_Id(request.getBriefingId());
return ScrapV2.of(savedScrap, scrapCount, Boolean.TRUE);
} catch (DataIntegrityViolationException e) {
// 중복 스크랩 예외 처리
throw new ScrapException(ErrorCode.DUPLICATE_SCRAP);
Expand All @@ -57,12 +39,9 @@ public Scrap create(ScrapRequest.CreateDTO request) {

@Override
public Scrap delete(Long briefingId, Long memberId) {
Scrap scrap =
scrapRepository
.findByBriefing_IdAndMember_Id(briefingId, memberId)
.orElseThrow(() -> new ScrapException(ErrorCode.SCRAP_NOT_FOUND));
scrapRepository.delete(scrap);
return scrap;
Scrap scrap = scrapDeletionHelper.deleteScrap(briefingId, memberId);
Integer scrapCount = scrapRepository.countByBriefing_Id(briefingId);
return ScrapV2.of(scrap, scrapCount, Boolean.FALSE);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package briefing.scrap.application.strategy.helper;

import org.springframework.stereotype.Component;

import briefing.briefing.domain.Briefing;
import briefing.briefing.domain.repository.BriefingRepository;
import briefing.exception.ErrorCode;
import briefing.exception.handler.BriefingException;
import briefing.member.domain.Member;
import briefing.member.domain.repository.MemberRepository;
import briefing.member.exception.MemberException;
import briefing.scrap.api.ScrapConverter;
import briefing.scrap.application.dto.ScrapRequest;
import briefing.scrap.domain.Scrap;
import briefing.scrap.domain.repository.ScrapRepository;
import briefing.scrap.exception.ScrapException;
import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class ScrapCreationHelper {
private final ScrapRepository scrapRepository;
private final MemberRepository memberRepository;
private final BriefingRepository briefingRepository;

public Scrap createScrap(ScrapRequest.CreateDTO request) {
if (scrapRepository.existsByMember_IdAndBriefing_Id(
request.getMemberId(), request.getBriefingId()))
throw new ScrapException(ErrorCode.SCRAP_ALREADY_EXISTS);

Member member =
memberRepository
.findById(request.getMemberId())
.orElseThrow(() -> new MemberException(ErrorCode.MEMBER_NOT_FOUND));

Briefing briefing =
briefingRepository
.findById(request.getBriefingId())
.orElseThrow(() -> new BriefingException(ErrorCode.NOT_FOUND_BRIEFING));

return ScrapConverter.toScrap(member, briefing);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package briefing.scrap.application.strategy.helper;

import org.springframework.stereotype.Component;

import briefing.exception.ErrorCode;
import briefing.scrap.domain.Scrap;
import briefing.scrap.domain.repository.ScrapRepository;
import briefing.scrap.exception.ScrapException;
import lombok.RequiredArgsConstructor;

@Component
@RequiredArgsConstructor
public class ScrapDeletionHelper {
private final ScrapRepository scrapRepository;

public Scrap deleteScrap(Long briefingId, Long memberId) {
Scrap scrap =
scrapRepository
.findByBriefing_IdAndMember_Id(briefingId, memberId)
.orElseThrow(() -> new ScrapException(ErrorCode.SCRAP_NOT_FOUND));
scrapRepository.delete(scrap);
return scrap;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package briefing.scrap.domain.repository;

public interface ScrapCustomRepository {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package briefing.scrap.domain.repository;

import org.springframework.stereotype.Repository;

@Repository
public class ScrapCustomRepositoryImpl implements ScrapCustomRepository {}
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@

import briefing.scrap.domain.Scrap;

public interface ScrapRepository extends JpaRepository<Scrap, Long> {
public interface ScrapRepository extends JpaRepository<Scrap, Long>, ScrapCustomRepository {

Optional<Scrap> findByBriefing_IdAndMember_Id(Long briefingId, Long memberId);

boolean existsByMember_IdAndBriefing_Id(Long memberId, Long briefingId);

List<Scrap> findByMember_Id(Long memberId);

Integer countByBriefing_Id(Long briefingId);
}

0 comments on commit f44395a

Please sign in to comment.