From eba52f849c35c2b8f6ab8b233e9d22d585975d72 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 17:21:32 +0900 Subject: [PATCH 01/38] =?UTF-8?q?FLASH-270=20feat:=20=ED=95=B4=EC=84=A4=20?= =?UTF-8?q?=EB=8C=93=EA=B8=80=20=EC=97=94=ED=8B=B0=ED=8B=B0=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solution/domain/SolutionComment.java | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/main/java/com/first/flash/climbing/solution/domain/SolutionComment.java diff --git a/src/main/java/com/first/flash/climbing/solution/domain/SolutionComment.java b/src/main/java/com/first/flash/climbing/solution/domain/SolutionComment.java new file mode 100644 index 00000000..9ac01622 --- /dev/null +++ b/src/main/java/com/first/flash/climbing/solution/domain/SolutionComment.java @@ -0,0 +1,57 @@ +package com.first.flash.climbing.solution.domain; + +import com.first.flash.global.domain.BaseEntity; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import java.util.UUID; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Entity +@NoArgsConstructor +@AllArgsConstructor +@Getter +@ToString +public class SolutionComment extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column + private String content; + + @Column + private String commenter; + + @Column + private UUID commenterId; + + @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinColumn(name = "solution_id", nullable = false) + private Solution solution; + + protected SolutionComment(final String content, final String commenter, final UUID commenterId, final Solution solution) { + this.content = content; + this.commenter = commenter; + this.commenterId = commenterId; + this.solution = solution; + } + + public static SolutionComment of(final String content, final String commenter, final UUID commenterId, final Solution solution) { + return new SolutionComment(content, commenter, commenterId, solution); + } + + public void updateContent(final String content) { + this.content = content; + } +} From 8c5bedfcd8be19ae6741603b01a6c42dd0740d0d Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 17:21:51 +0900 Subject: [PATCH 02/38] =?UTF-8?q?FLASH-270=20feat:=20=EA=B8=B0=EB=B3=B8?= =?UTF-8?q?=EC=A0=81=EC=9D=B8=20=EC=83=9D=EC=84=B1=EA=B3=BC=20=ED=95=B4?= =?UTF-8?q?=EC=84=A4=20=EC=95=84=EC=9D=B4=EB=94=94=EB=A1=9C=20=EB=8C=93?= =?UTF-8?q?=EA=B8=80=EC=9D=84=20=EC=A1=B0=ED=9A=8C=ED=95=98=EB=8A=94=20?= =?UTF-8?q?=EC=8B=9C=EB=82=98=EB=A6=AC=EC=98=A4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/SolutionCommentService.java | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java diff --git a/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java b/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java new file mode 100644 index 00000000..232eb036 --- /dev/null +++ b/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java @@ -0,0 +1,49 @@ +package com.first.flash.climbing.solution.application; + +import com.first.flash.account.member.application.MemberService; +import com.first.flash.account.member.domain.Member; +import com.first.flash.climbing.solution.application.dto.SolutionCommentCreateRequestDto; +import com.first.flash.climbing.solution.application.dto.SolutionCommentCreateResponseDto; +import com.first.flash.climbing.solution.application.dto.SolutionCommentResponseDto; +import com.first.flash.climbing.solution.application.dto.SolutionCommentsResponseDto; +import com.first.flash.climbing.solution.domain.Solution; +import com.first.flash.climbing.solution.domain.SolutionComment; +import com.first.flash.climbing.solution.infrastructure.SolutionCommentRepository; +import com.first.flash.global.util.AuthUtil; +import java.util.List; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class SolutionCommentService { + + private final MemberService memberService; + private final SolutionCommentRepository solutionCommentRepository; + private final SolutionService solutionService; + + public SolutionCommentCreateResponseDto createComment(final Long solutionId, + final SolutionCommentCreateRequestDto requestDto) { + UUID id = AuthUtil.getId(); + Member member = memberService.findById(id); + + Solution solution = solutionService.findSolutionById(solutionId); + SolutionComment solutionComment = SolutionComment.of(requestDto.content(), + member.getNickName(), member.getId(), solution); + SolutionComment savedSolutionComment = solutionCommentRepository.save(solutionComment); + + return SolutionCommentCreateResponseDto.toDto(savedSolutionComment); + } + + public SolutionCommentsResponseDto findBySolutionId(final Long solutionId) { + List comments = solutionCommentRepository.findBySolutionId(solutionId); + List commentsResponse = comments.stream() + .map( + SolutionCommentResponseDto::toDto) + .toList(); + return SolutionCommentsResponseDto.from(commentsResponse); + } +} From 46dfd2fabd98bf1b4619c3fd2c003bc629b2d28c Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 17:22:20 +0900 Subject: [PATCH 03/38] =?UTF-8?q?FLASH-270=20feat:=20=ED=95=B4=EC=84=A4=20?= =?UTF-8?q?=EB=8C=93=EA=B8=80=EC=9D=98=20=EB=A6=AC=ED=8F=AC=EC=A7=80?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=20=EA=B0=9D=EC=B2=B4=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SolutionCommentJpaRepository.java | 12 ++++++++++ .../SolutionCommentRepository.java | 13 +++++++++++ .../SolutionCommentRepositoryImpl.java | 23 +++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentJpaRepository.java create mode 100644 src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentRepository.java create mode 100644 src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentRepositoryImpl.java diff --git a/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentJpaRepository.java b/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentJpaRepository.java new file mode 100644 index 00000000..afc5bf67 --- /dev/null +++ b/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentJpaRepository.java @@ -0,0 +1,12 @@ +package com.first.flash.climbing.solution.infrastructure; + +import com.first.flash.climbing.solution.domain.SolutionComment; +import java.util.List; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface SolutionCommentJpaRepository extends JpaRepository { + + SolutionComment save(final SolutionComment solutionComment); + + List findBySolutionId(final Long solutionId); +} diff --git a/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentRepository.java b/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentRepository.java new file mode 100644 index 00000000..19867bc8 --- /dev/null +++ b/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentRepository.java @@ -0,0 +1,13 @@ +package com.first.flash.climbing.solution.infrastructure; + +import com.first.flash.climbing.solution.domain.SolutionComment; +import java.util.List; +import org.springframework.stereotype.Repository; + +@Repository +public interface SolutionCommentRepository { + + SolutionComment save(final SolutionComment solutionComment); + + List findBySolutionId(Long solutionId); +} diff --git a/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentRepositoryImpl.java b/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentRepositoryImpl.java new file mode 100644 index 00000000..1dac70b3 --- /dev/null +++ b/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentRepositoryImpl.java @@ -0,0 +1,23 @@ +package com.first.flash.climbing.solution.infrastructure; + +import com.first.flash.climbing.solution.domain.SolutionComment; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +@Repository +@RequiredArgsConstructor +public class SolutionCommentRepositoryImpl implements SolutionCommentRepository { + + private final SolutionCommentJpaRepository solutionCommentJpaRepository; + + @Override + public SolutionComment save(final SolutionComment solutionComment) { + return solutionCommentJpaRepository.save(solutionComment); + } + + @Override + public List findBySolutionId(final Long solutionId) { + return solutionCommentJpaRepository.findBySolutionId(solutionId); + } +} From 8517ed66cbbf6aaad862419c0c6bec59131a13e6 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 17:22:50 +0900 Subject: [PATCH 04/38] =?UTF-8?q?FLASH-270=20feat:=20=ED=95=B4=EC=84=A4=20?= =?UTF-8?q?=EB=8C=93=EA=B8=80=20=EC=83=9D=EC=84=B1=20=EC=9A=94=EC=B2=AD/?= =?UTF-8?q?=EC=9D=91=EB=8B=B5=20dto=20=ED=8B=80=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/SolutionCommentCreateRequestDto.java | 5 +++++ .../dto/SolutionCommentCreateResponseDto.java | 11 +++++++++++ 2 files changed, 16 insertions(+) create mode 100644 src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentCreateRequestDto.java create mode 100644 src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentCreateResponseDto.java diff --git a/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentCreateRequestDto.java b/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentCreateRequestDto.java new file mode 100644 index 00000000..78f138b7 --- /dev/null +++ b/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentCreateRequestDto.java @@ -0,0 +1,5 @@ +package com.first.flash.climbing.solution.application.dto; + +public record SolutionCommentCreateRequestDto(String content) { + +} diff --git a/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentCreateResponseDto.java b/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentCreateResponseDto.java new file mode 100644 index 00000000..4a0ce09a --- /dev/null +++ b/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentCreateResponseDto.java @@ -0,0 +1,11 @@ +package com.first.flash.climbing.solution.application.dto; + +import com.first.flash.climbing.solution.domain.SolutionComment; + +public record SolutionCommentCreateResponseDto() { + + public static SolutionCommentCreateResponseDto toDto( + final SolutionComment savedSolutionComment) { + return new SolutionCommentCreateResponseDto(); + } +} From 93afd07f4fa03e0c8acafd54590837ade55492ba Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 17:23:09 +0900 Subject: [PATCH 05/38] =?UTF-8?q?FLASH-270=20feat:=20=ED=95=B4=EC=84=A4=20?= =?UTF-8?q?=EB=8C=93=EA=B8=80=20=EC=9D=91=EB=8B=B5=20dto=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/dto/SolutionCommentResponseDto.java | 10 ++++++++++ .../application/dto/SolutionCommentsResponseDto.java | 11 +++++++++++ 2 files changed, 21 insertions(+) create mode 100644 src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentResponseDto.java create mode 100644 src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentsResponseDto.java diff --git a/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentResponseDto.java b/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentResponseDto.java new file mode 100644 index 00000000..27a470d0 --- /dev/null +++ b/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentResponseDto.java @@ -0,0 +1,10 @@ +package com.first.flash.climbing.solution.application.dto; + +import com.first.flash.climbing.solution.domain.SolutionComment; + +public record SolutionCommentResponseDto() { + + public static SolutionCommentResponseDto toDto(final SolutionComment solutionComment) { + return new SolutionCommentResponseDto(); + } +} diff --git a/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentsResponseDto.java b/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentsResponseDto.java new file mode 100644 index 00000000..b53dc0df --- /dev/null +++ b/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentsResponseDto.java @@ -0,0 +1,11 @@ +package com.first.flash.climbing.solution.application.dto; + +import java.util.List; + +public record SolutionCommentsResponseDto(List comments) { + + public static SolutionCommentsResponseDto from( + final List commentsResponse) { + return new SolutionCommentsResponseDto(commentsResponse); + } +} From b617dc030684bb5aecfd218fef72cc9a59f4cb14 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 17:43:23 +0900 Subject: [PATCH 06/38] =?UTF-8?q?FLASH-270=20feat:=20=EB=8C=93=EA=B8=80?= =?UTF-8?q?=EC=9D=84=20=EB=8B=A8=20=EC=82=AC=EB=9E=8C=EC=97=90=20=EB=8C=80?= =?UTF-8?q?=ED=95=9C=20=EC=A0=95=EB=B3=B4=20=EA=B0=92=ED=83=80=EC=9E=85?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solution/domain/CommenterDetail.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/main/java/com/first/flash/climbing/solution/domain/CommenterDetail.java diff --git a/src/main/java/com/first/flash/climbing/solution/domain/CommenterDetail.java b/src/main/java/com/first/flash/climbing/solution/domain/CommenterDetail.java new file mode 100644 index 00000000..d577e23a --- /dev/null +++ b/src/main/java/com/first/flash/climbing/solution/domain/CommenterDetail.java @@ -0,0 +1,32 @@ +package com.first.flash.climbing.solution.domain; + +import jakarta.persistence.Column; +import jakarta.persistence.Embeddable; +import java.util.UUID; +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.ToString; + +@Embeddable +@NoArgsConstructor +@EqualsAndHashCode +@Getter +@ToString +public class CommenterDetail { + + @Column(columnDefinition = "BINARY(16)") + private UUID commenterId; + private String commenter; + private String profileImageUrl; + + protected CommenterDetail(final UUID commenterId, final String commenter, final String profileImageUrl) { + this.commenterId = commenterId; + this.commenter = commenter; + this.profileImageUrl = profileImageUrl; + } + + public static CommenterDetail of(final UUID commenterId, final String commenter, final String profileImageUrl) { + return new CommenterDetail(commenterId, commenter, profileImageUrl); + } +} From afad970b09cfaf45355b46bc22e3e61537b67292 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 17:43:43 +0900 Subject: [PATCH 07/38] =?UTF-8?q?FLASH-270=20feat:=20=ED=95=B4=EC=84=A4=20?= =?UTF-8?q?=EB=8C=93=EA=B8=80=20querydsl=20repository=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SolutionCommentQueryDslRepository.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentQueryDslRepository.java diff --git a/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentQueryDslRepository.java b/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentQueryDslRepository.java new file mode 100644 index 00000000..802e35db --- /dev/null +++ b/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentQueryDslRepository.java @@ -0,0 +1,25 @@ +package com.first.flash.climbing.solution.infrastructure; + +import static com.first.flash.climbing.solution.domain.QSolutionComment.solutionComment; + +import com.querydsl.jpa.impl.JPAQueryFactory; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +@Repository +@RequiredArgsConstructor +public class SolutionCommentQueryDslRepository { + + private final JPAQueryFactory jpaQueryFactory; + + + public void updateCommenterInfo(final UUID commenterId, final String nickName, + final String profileImageUrl) { + jpaQueryFactory.update(solutionComment) + .set(solutionComment.commenterDetail.commenter, nickName) + .set(solutionComment.commenterDetail.profileImageUrl, profileImageUrl) + .where(solutionComment.commenterDetail.commenterId.eq(commenterId)) + .execute(); + } +} From b121a0191770c6f45d1a9aa2d628e5ab2c8b1df6 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 18:11:47 +0900 Subject: [PATCH 08/38] =?UTF-8?q?FLASH-270=20feat:=20=EA=B8=B0=EB=B3=B8?= =?UTF-8?q?=EC=A0=81=EC=9D=B8=20=EC=A1=B0=ED=9A=8C,=20=EC=88=98=EC=A0=95,?= =?UTF-8?q?=20=EC=82=AD=EC=A0=9C=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/SolutionCommentService.java | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java b/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java index 232eb036..80f771c4 100644 --- a/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java +++ b/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java @@ -8,6 +8,8 @@ import com.first.flash.climbing.solution.application.dto.SolutionCommentsResponseDto; import com.first.flash.climbing.solution.domain.Solution; import com.first.flash.climbing.solution.domain.SolutionComment; +import com.first.flash.climbing.solution.exception.exceptions.SolutionCommentAccessDeniedException; +import com.first.flash.climbing.solution.exception.exceptions.SolutionCommentNotFoundException; import com.first.flash.climbing.solution.infrastructure.SolutionCommentRepository; import com.first.flash.global.util.AuthUtil; import java.util.List; @@ -25,6 +27,7 @@ public class SolutionCommentService { private final SolutionCommentRepository solutionCommentRepository; private final SolutionService solutionService; + @Transactional public SolutionCommentCreateResponseDto createComment(final Long solutionId, final SolutionCommentCreateRequestDto requestDto) { UUID id = AuthUtil.getId(); @@ -32,12 +35,17 @@ public SolutionCommentCreateResponseDto createComment(final Long solutionId, Solution solution = solutionService.findSolutionById(solutionId); SolutionComment solutionComment = SolutionComment.of(requestDto.content(), - member.getNickName(), member.getId(), solution); + member.getNickName(), member.getProfileImageUrl(), member.getId(), solution); SolutionComment savedSolutionComment = solutionCommentRepository.save(solutionComment); return SolutionCommentCreateResponseDto.toDto(savedSolutionComment); } + public SolutionComment findById(final Long id) { + return solutionCommentRepository.findById(id) + .orElseThrow(() -> new SolutionCommentNotFoundException(id)); + } + public SolutionCommentsResponseDto findBySolutionId(final Long solutionId) { List comments = solutionCommentRepository.findBySolutionId(solutionId); List commentsResponse = comments.stream() @@ -46,4 +54,28 @@ public SolutionCommentsResponseDto findBySolutionId(final Long solutionId) { .toList(); return SolutionCommentsResponseDto.from(commentsResponse); } + + @Transactional + public void updateCommenterInfo(final Long commentId, final UUID commenterId, final String nickName, + final String profileImageUrl) { + SolutionComment comment = findById(commentId); + if (!AuthUtil.isSameId(comment.getCommenterDetail().getCommenterId())) { + throw new SolutionCommentAccessDeniedException(); + } + solutionCommentRepository.updateCommenterInfo(commenterId, nickName, profileImageUrl); + } + + @Transactional + public void deleteComment(final Long commentId) { + SolutionComment comment = findById(commentId); + if (!AuthUtil.isSameId(comment.getCommenterDetail().getCommenterId())) { + throw new SolutionCommentAccessDeniedException(); + } + solutionCommentRepository.delete(comment); + } + + @Transactional + public void deleteByCommenterId(final UUID commenterId) { + solutionCommentRepository.deleteByCommenterId(commenterId); + } } From bfd93966001f039dfd619dcbcde9b16b5a7c1467 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 18:12:52 +0900 Subject: [PATCH 09/38] =?UTF-8?q?FLASH-270=20feat:=20=EB=8B=A8=EA=B1=B4=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C,=20=EC=88=98=EC=A0=95,=20=EC=82=AD=EC=A0=9C?= =?UTF-8?q?=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SolutionCommentJpaRepository.java | 5 ++++ .../SolutionCommentRepository.java | 12 +++++++++- .../SolutionCommentRepositoryImpl.java | 24 +++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentJpaRepository.java b/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentJpaRepository.java index afc5bf67..57aed8b6 100644 --- a/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentJpaRepository.java +++ b/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentJpaRepository.java @@ -2,6 +2,7 @@ import com.first.flash.climbing.solution.domain.SolutionComment; import java.util.List; +import java.util.UUID; import org.springframework.data.jpa.repository.JpaRepository; public interface SolutionCommentJpaRepository extends JpaRepository { @@ -9,4 +10,8 @@ public interface SolutionCommentJpaRepository extends JpaRepository findBySolutionId(final Long solutionId); + + void deleteByCommenterDetailCommenterId(final UUID commenterId); + + void delete(final SolutionComment comment); } diff --git a/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentRepository.java b/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentRepository.java index 19867bc8..0f6eeb1c 100644 --- a/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentRepository.java +++ b/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentRepository.java @@ -2,6 +2,8 @@ import com.first.flash.climbing.solution.domain.SolutionComment; import java.util.List; +import java.util.Optional; +import java.util.UUID; import org.springframework.stereotype.Repository; @Repository @@ -9,5 +11,13 @@ public interface SolutionCommentRepository { SolutionComment save(final SolutionComment solutionComment); - List findBySolutionId(Long solutionId); + Optional findById(final Long id); + + List findBySolutionId(final Long solutionId); + + void deleteByCommenterId(final UUID commenterId); + + void updateCommenterInfo(final UUID commenterId, final String nickName, final String profileImageUrl); + + void delete(final SolutionComment comment); } diff --git a/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentRepositoryImpl.java b/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentRepositoryImpl.java index 1dac70b3..0f9976cc 100644 --- a/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentRepositoryImpl.java +++ b/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionCommentRepositoryImpl.java @@ -2,6 +2,8 @@ import com.first.flash.climbing.solution.domain.SolutionComment; import java.util.List; +import java.util.Optional; +import java.util.UUID; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; @@ -10,14 +12,36 @@ public class SolutionCommentRepositoryImpl implements SolutionCommentRepository { private final SolutionCommentJpaRepository solutionCommentJpaRepository; + private final SolutionCommentQueryDslRepository solutionCommentQueryDslRepository; @Override public SolutionComment save(final SolutionComment solutionComment) { return solutionCommentJpaRepository.save(solutionComment); } + @Override + public Optional findById(final Long id) { + return solutionCommentJpaRepository.findById(id); + } + @Override public List findBySolutionId(final Long solutionId) { return solutionCommentJpaRepository.findBySolutionId(solutionId); } + + @Override + public void deleteByCommenterId(final UUID commenterId) { + solutionCommentJpaRepository.deleteByCommenterDetailCommenterId(commenterId); + } + + @Override + public void updateCommenterInfo(final UUID commenterId, final String nickName, + final String profileImageUrl) { + solutionCommentQueryDslRepository.updateCommenterInfo(commenterId, nickName, profileImageUrl); + } + + @Override + public void delete(final SolutionComment comment) { + solutionCommentJpaRepository.delete(comment); + } } From 8d6905c85090abfc673ce7d5206d5ba506a515a8 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 18:13:42 +0900 Subject: [PATCH 10/38] =?UTF-8?q?FLASH-270=20feat:=20id=EB=A1=9C=20?= =?UTF-8?q?=EB=8B=A8=EA=B1=B4=20=EC=A1=B0=ED=9A=8C=EC=8B=9C=20=EC=B0=BE?= =?UTF-8?q?=EC=A7=80=20=EB=AA=BB=ED=96=88=EC=9D=84=20=EB=95=8C=20=EC=98=88?= =?UTF-8?q?=EC=99=B8=20=EA=B0=9D=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exceptions/SolutionCommentNotFoundException.java | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/main/java/com/first/flash/climbing/solution/exception/exceptions/SolutionCommentNotFoundException.java diff --git a/src/main/java/com/first/flash/climbing/solution/exception/exceptions/SolutionCommentNotFoundException.java b/src/main/java/com/first/flash/climbing/solution/exception/exceptions/SolutionCommentNotFoundException.java new file mode 100644 index 00000000..882bf258 --- /dev/null +++ b/src/main/java/com/first/flash/climbing/solution/exception/exceptions/SolutionCommentNotFoundException.java @@ -0,0 +1,8 @@ +package com.first.flash.climbing.solution.exception.exceptions; + +public class SolutionCommentNotFoundException extends RuntimeException { + + public SolutionCommentNotFoundException(final Long id) { + super(String.format("아이디가 %s인 댓글을 찾을 수 없습니다.", id)); + } +} From 91cfe6f0bd891ebc117ecb667be9113857fd6453 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 18:14:02 +0900 Subject: [PATCH 11/38] =?UTF-8?q?FLASH-270=20feat:=20=EB=B3=B8=EC=9D=B8?= =?UTF-8?q?=EC=9D=98=20=EB=8C=93=EA=B8=80=20=EC=9D=B4=EC=99=B8=20=EB=8C=93?= =?UTF-8?q?=EA=B8=80=EC=97=90=20=EB=8C=80=ED=95=9C=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?=EC=9A=94=EC=B2=AD=EC=9D=84=20=EB=B3=B4=EB=83=88=EC=9D=84=20?= =?UTF-8?q?=EB=95=8C=20=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exceptions/SolutionCommentAccessDeniedException.java | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/main/java/com/first/flash/climbing/solution/exception/exceptions/SolutionCommentAccessDeniedException.java diff --git a/src/main/java/com/first/flash/climbing/solution/exception/exceptions/SolutionCommentAccessDeniedException.java b/src/main/java/com/first/flash/climbing/solution/exception/exceptions/SolutionCommentAccessDeniedException.java new file mode 100644 index 00000000..b4a2af09 --- /dev/null +++ b/src/main/java/com/first/flash/climbing/solution/exception/exceptions/SolutionCommentAccessDeniedException.java @@ -0,0 +1,8 @@ +package com.first.flash.climbing.solution.exception.exceptions; + +public class SolutionCommentAccessDeniedException extends RuntimeException { + + public SolutionCommentAccessDeniedException() { + super("해당 댓글에 접근할 권한이 없습니다."); + } +} From 034d3586321e392713f0b0c5757ffd377cdf72c6 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 18:14:24 +0900 Subject: [PATCH 12/38] =?UTF-8?q?FLASH-270=20feat:=20=EB=8C=93=EA=B8=80=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1=EC=9E=90=20=EB=94=94=ED=85=8C=EC=9D=BC=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../climbing/solution/domain/SolutionComment.java | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/first/flash/climbing/solution/domain/SolutionComment.java b/src/main/java/com/first/flash/climbing/solution/domain/SolutionComment.java index 9ac01622..3ed563d0 100644 --- a/src/main/java/com/first/flash/climbing/solution/domain/SolutionComment.java +++ b/src/main/java/com/first/flash/climbing/solution/domain/SolutionComment.java @@ -30,25 +30,20 @@ public class SolutionComment extends BaseEntity { @Column private String content; - @Column - private String commenter; - - @Column - private UUID commenterId; + private CommenterDetail commenterDetail; @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinColumn(name = "solution_id", nullable = false) private Solution solution; - protected SolutionComment(final String content, final String commenter, final UUID commenterId, final Solution solution) { + protected SolutionComment(final String content, final CommenterDetail commenter, final Solution solution) { this.content = content; - this.commenter = commenter; - this.commenterId = commenterId; + this.commenterDetail = commenter; this.solution = solution; } - public static SolutionComment of(final String content, final String commenter, final UUID commenterId, final Solution solution) { - return new SolutionComment(content, commenter, commenterId, solution); + public static SolutionComment of(final String content, final String commenter, final String profileImage, final UUID commenterId, final Solution solution) { + return new SolutionComment(content, CommenterDetail.of(commenterId, commenter, profileImage), solution); } public void updateContent(final String content) { From 6fa4e113f28ba9ccaff2ccfe7770b3e14a5538c5 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 18:18:52 +0900 Subject: [PATCH 13/38] =?UTF-8?q?FLASH-270=20feat:=20=EB=8C=93=EA=B8=80=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1=EC=9E=90=EC=9D=98=20=EC=A0=95=EB=B3=B4=20?= =?UTF-8?q?=EC=88=98=EC=A0=95,=20=EC=82=AD=EC=A0=9C=EB=A5=BC=20=EB=8C=93?= =?UTF-8?q?=EA=B8=80=EC=97=90=EB=8F=84=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../climbing/solution/application/SolutionEventHandler.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/com/first/flash/climbing/solution/application/SolutionEventHandler.java b/src/main/java/com/first/flash/climbing/solution/application/SolutionEventHandler.java index ca528e71..15a5175f 100644 --- a/src/main/java/com/first/flash/climbing/solution/application/SolutionEventHandler.java +++ b/src/main/java/com/first/flash/climbing/solution/application/SolutionEventHandler.java @@ -13,17 +13,22 @@ public class SolutionEventHandler { private final SolutionSaveService solutionSaveService; private final SolutionService solutionService; + private final SolutionCommentService solutionCommentService; @EventListener @Transactional public void updateSolutionInfo(final MemberInfoUpdatedEvent event) { solutionSaveService.updateUploaderInfo(event.getMemberId(), event.getNickName(), event.getInstagramId(), event.getProfileImageUrl()); + + solutionCommentService.updateCommenterInfo(event.getMemberId(), event.getNickName(), + event.getProfileImageUrl()); } @EventListener @Transactional public void deleteSolution(final MemberDeletedEvent event) { solutionService.deleteByUploaderId(event.getMemberId()); + solutionCommentService.deleteByCommenterId(event.getMemberId()); } } From 3ec74d5cd1bb15ab0035030a21912518aef5d8e6 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 18:19:21 +0900 Subject: [PATCH 14/38] =?UTF-8?q?FLASH-270=20feat:=20=EB=8C=93=EA=B8=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EC=8B=9C=EB=82=98=EB=A6=AC=EC=98=A4=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/SolutionCommentService.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java b/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java index 80f771c4..81b3413f 100644 --- a/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java +++ b/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java @@ -43,7 +43,8 @@ public SolutionCommentCreateResponseDto createComment(final Long solutionId, public SolutionComment findById(final Long id) { return solutionCommentRepository.findById(id) - .orElseThrow(() -> new SolutionCommentNotFoundException(id)); + .orElseThrow( + () -> new SolutionCommentNotFoundException(id)); } public SolutionCommentsResponseDto findBySolutionId(final Long solutionId) { @@ -56,13 +57,12 @@ public SolutionCommentsResponseDto findBySolutionId(final Long solutionId) { } @Transactional - public void updateCommenterInfo(final Long commentId, final UUID commenterId, final String nickName, - final String profileImageUrl) { + public void updateComment(final Long commentId, final String content) { SolutionComment comment = findById(commentId); if (!AuthUtil.isSameId(comment.getCommenterDetail().getCommenterId())) { throw new SolutionCommentAccessDeniedException(); } - solutionCommentRepository.updateCommenterInfo(commenterId, nickName, profileImageUrl); + comment.updateContent(content); } @Transactional @@ -78,4 +78,10 @@ public void deleteComment(final Long commentId) { public void deleteByCommenterId(final UUID commenterId) { solutionCommentRepository.deleteByCommenterId(commenterId); } + + @Transactional + public void updateCommenterInfo(final UUID commenterId, final String nickName, + final String profileImageUrl) { + solutionCommentRepository.updateCommenterInfo(commenterId, nickName, profileImageUrl); + } } From 2fe256c4a5e0212e8cd9da5eaf9344d32d2e8ee9 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 18:23:28 +0900 Subject: [PATCH 15/38] =?UTF-8?q?FLASH-270=20feat:=20=ED=95=B4=EC=84=A4?= =?UTF-8?q?=EC=9D=98=20=EB=8C=93=EA=B8=80=20CRUD=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EB=B0=9C=EC=83=9D=ED=95=98=EB=8A=94=20=EC=98=88=EC=99=B8=20?= =?UTF-8?q?=ED=95=B8=EB=93=A4=EB=9F=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exception/SolutionExceptionHandler.java | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/first/flash/climbing/solution/exception/SolutionExceptionHandler.java b/src/main/java/com/first/flash/climbing/solution/exception/SolutionExceptionHandler.java index 535c6bd1..a993de56 100644 --- a/src/main/java/com/first/flash/climbing/solution/exception/SolutionExceptionHandler.java +++ b/src/main/java/com/first/flash/climbing/solution/exception/SolutionExceptionHandler.java @@ -1,6 +1,8 @@ package com.first.flash.climbing.solution.exception; import com.first.flash.climbing.solution.exception.exceptions.SolutionAccessDeniedException; +import com.first.flash.climbing.solution.exception.exceptions.SolutionCommentAccessDeniedException; +import com.first.flash.climbing.solution.exception.exceptions.SolutionCommentNotFoundException; import com.first.flash.climbing.solution.exception.exceptions.SolutionNotFoundException; import com.first.flash.global.dto.ErrorResponseDto; import org.springframework.http.HttpStatus; @@ -14,16 +16,31 @@ public class SolutionExceptionHandler { @ExceptionHandler(SolutionNotFoundException.class) public ResponseEntity handleSolutionNotFoundException( final SolutionNotFoundException exception) { - ErrorResponseDto errorResponse = new ErrorResponseDto(exception.getMessage()); - return ResponseEntity.status(HttpStatus.NOT_FOUND) - .body(errorResponse); + return getResponseWithStatus(HttpStatus.NOT_FOUND, exception); } @ExceptionHandler(SolutionAccessDeniedException.class) public ResponseEntity handleSolutionAccessDeniedException( final SolutionAccessDeniedException exception) { + return getResponseWithStatus(HttpStatus.FORBIDDEN, exception); + } + + @ExceptionHandler(SolutionCommentAccessDeniedException.class) + public ResponseEntity handleSolutionCommentAccessDeniedException( + final SolutionCommentAccessDeniedException exception) { + return getResponseWithStatus(HttpStatus.FORBIDDEN, exception); + } + + @ExceptionHandler(SolutionCommentNotFoundException.class) + public ResponseEntity handleSolutionCommentNotFoundException( + final SolutionCommentNotFoundException exception) { + return getResponseWithStatus(HttpStatus.NOT_FOUND, exception); + } + + private ResponseEntity getResponseWithStatus(final HttpStatus httpStatus, + final RuntimeException exception) { ErrorResponseDto errorResponse = new ErrorResponseDto(exception.getMessage()); - return ResponseEntity.status(HttpStatus.FORBIDDEN) + return ResponseEntity.status(httpStatus) .body(errorResponse); } } From 156934a89c64c8c7a7f43f052d10db3f3a5b6d52 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 18:27:12 +0900 Subject: [PATCH 16/38] =?UTF-8?q?FLASH-270=20feat:=20=ED=95=B4=EC=84=A4?= =?UTF-8?q?=EC=9D=84=20=EC=A1=B0=ED=9A=8C=ED=96=88=EC=9D=84=20=EB=95=8C=20?= =?UTF-8?q?=EC=9D=91=EB=8B=B5=20dto=20=EA=B0=92=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/dto/SolutionCommentResponseDto.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentResponseDto.java b/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentResponseDto.java index 27a470d0..8ba5d9f9 100644 --- a/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentResponseDto.java +++ b/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentResponseDto.java @@ -1,10 +1,15 @@ package com.first.flash.climbing.solution.application.dto; import com.first.flash.climbing.solution.domain.SolutionComment; +import java.util.UUID; -public record SolutionCommentResponseDto() { +public record SolutionCommentResponseDto(Long id, String content, UUID commenterId, String nickName, + String profileImageUrl) { public static SolutionCommentResponseDto toDto(final SolutionComment solutionComment) { - return new SolutionCommentResponseDto(); + return new SolutionCommentResponseDto(solutionComment.getId(), solutionComment.getContent(), + solutionComment.getCommenterDetail().getCommenterId(), + solutionComment.getCommenterDetail().getCommenter(), + solutionComment.getCommenterDetail().getProfileImageUrl()); } } From 6bca747c40827c9f42ccd25d4d94e50995772536 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 18:27:24 +0900 Subject: [PATCH 17/38] =?UTF-8?q?FLASH-270=20feat:=20=ED=95=B4=EC=84=A4?= =?UTF-8?q?=EC=9D=84=20=EC=83=9D=EC=84=B1=ED=96=88=EC=9D=84=20=EB=95=8C=20?= =?UTF-8?q?=EC=9D=91=EB=8B=B5=20dto=20=EA=B0=92=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/SolutionCommentCreateResponseDto.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentCreateResponseDto.java b/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentCreateResponseDto.java index 4a0ce09a..799979d0 100644 --- a/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentCreateResponseDto.java +++ b/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentCreateResponseDto.java @@ -1,11 +1,16 @@ package com.first.flash.climbing.solution.application.dto; import com.first.flash.climbing.solution.domain.SolutionComment; +import java.util.UUID; -public record SolutionCommentCreateResponseDto() { +public record SolutionCommentCreateResponseDto(Long id, String content, UUID commenterId, + String nickName, String profileImageUrl) { public static SolutionCommentCreateResponseDto toDto( - final SolutionComment savedSolutionComment) { - return new SolutionCommentCreateResponseDto(); + final SolutionComment comment) { + return new SolutionCommentCreateResponseDto(comment.getId(), comment.getContent(), + comment.getCommenterDetail().getCommenterId(), + comment.getCommenterDetail().getCommenter(), + comment.getCommenterDetail().getProfileImageUrl()); } } From 19aff7998b634888efe708f33b922025676b7a5c Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 18:34:54 +0900 Subject: [PATCH 18/38] =?UTF-8?q?FLASH-270=20refactor:=20=ED=95=B4?= =?UTF-8?q?=EC=84=A4=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EC=8B=9C=20?= =?UTF-8?q?dto=EB=A5=BC=20=ED=86=B5=ED=95=B4=20=EC=88=98=EC=A0=95=EC=82=AC?= =?UTF-8?q?=ED=95=AD=EC=9D=84=20=EB=B0=9B=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solution/application/SolutionCommentService.java | 5 +++-- .../application/dto/SolutionCommentUpdateRequestDto.java | 5 +++++ 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentUpdateRequestDto.java diff --git a/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java b/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java index 81b3413f..464cd0f0 100644 --- a/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java +++ b/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java @@ -5,6 +5,7 @@ import com.first.flash.climbing.solution.application.dto.SolutionCommentCreateRequestDto; import com.first.flash.climbing.solution.application.dto.SolutionCommentCreateResponseDto; import com.first.flash.climbing.solution.application.dto.SolutionCommentResponseDto; +import com.first.flash.climbing.solution.application.dto.SolutionCommentUpdateRequestDto; import com.first.flash.climbing.solution.application.dto.SolutionCommentsResponseDto; import com.first.flash.climbing.solution.domain.Solution; import com.first.flash.climbing.solution.domain.SolutionComment; @@ -57,12 +58,12 @@ public SolutionCommentsResponseDto findBySolutionId(final Long solutionId) { } @Transactional - public void updateComment(final Long commentId, final String content) { + public void updateComment(final Long commentId, final SolutionCommentUpdateRequestDto request) { SolutionComment comment = findById(commentId); if (!AuthUtil.isSameId(comment.getCommenterDetail().getCommenterId())) { throw new SolutionCommentAccessDeniedException(); } - comment.updateContent(content); + comment.updateContent(request.content()); } @Transactional diff --git a/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentUpdateRequestDto.java b/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentUpdateRequestDto.java new file mode 100644 index 00000000..09063b68 --- /dev/null +++ b/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentUpdateRequestDto.java @@ -0,0 +1,5 @@ +package com.first.flash.climbing.solution.application.dto; + +public record SolutionCommentUpdateRequestDto(String content) { + +} From c28665bc5425ee2ca33e4deb4dd86e5faa02de34 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 18:35:14 +0900 Subject: [PATCH 19/38] =?UTF-8?q?FLASH-270=20feat:=20=ED=95=B4=EC=84=A4=20?= =?UTF-8?q?=EB=8C=93=EA=B8=80=20Controller=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/SolutionCommentController.java | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java diff --git a/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java b/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java new file mode 100644 index 00000000..fa3626ba --- /dev/null +++ b/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java @@ -0,0 +1,57 @@ +package com.first.flash.climbing.solution.ui; + +import com.first.flash.climbing.solution.application.SolutionCommentService; +import com.first.flash.climbing.solution.application.dto.SolutionCommentCreateRequestDto; +import com.first.flash.climbing.solution.application.dto.SolutionCommentCreateResponseDto; +import com.first.flash.climbing.solution.application.dto.SolutionCommentUpdateRequestDto; +import com.first.flash.climbing.solution.application.dto.SolutionCommentsResponseDto; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PatchMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +@Tag(name = "solutions", description = "해설 관리 API") +@RestController +@RequiredArgsConstructor +public class SolutionCommentController { + + private final SolutionCommentService solutionCommentService; + + @PostMapping("/solutions/{solutionId}/comments") + public ResponseEntity createSolutionComment( + @PathVariable final Long solutionId, + @RequestBody final SolutionCommentCreateRequestDto request) { + SolutionCommentCreateResponseDto comment = solutionCommentService + .createComment(solutionId, request); + return ResponseEntity.ok(comment); + } + + @GetMapping("/solutions/{solutionId}/comments") + public ResponseEntity getSolutionComments( + @PathVariable final Long solutionId) { + SolutionCommentsResponseDto comments = solutionCommentService + .findBySolutionId(solutionId); + return ResponseEntity.ok(comments); + } + + @PatchMapping("/comments/{commentId}") + public ResponseEntity updateComment( + @PathVariable final Long commentId, + @RequestBody final SolutionCommentUpdateRequestDto content) { + solutionCommentService.updateComment(commentId, content); + return ResponseEntity.ok().build(); + } + + @DeleteMapping("/comments/{commentId}") + public ResponseEntity deleteComment( + @PathVariable final Long commentId) { + solutionCommentService.deleteComment(commentId); + return ResponseEntity.ok().build(); + } +} From f3dc721e78eb77d07c6a6894d2ea67b6745aa217 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 18:37:39 +0900 Subject: [PATCH 20/38] =?UTF-8?q?FLASH-270=20feat:=20=ED=95=B4=EC=84=A4=20?= =?UTF-8?q?=EB=8C=93=EA=B8=80=20=EC=83=9D=EC=84=B1,=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=20=EC=8B=9C=20dto=20=EC=9C=A0=ED=9A=A8=EC=84=B1=20=EA=B2=80?= =?UTF-8?q?=EC=82=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/dto/SolutionCommentCreateRequestDto.java | 4 +++- .../application/dto/SolutionCommentUpdateRequestDto.java | 4 +++- .../climbing/solution/ui/SolutionCommentController.java | 9 ++++++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentCreateRequestDto.java b/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentCreateRequestDto.java index 78f138b7..3f08064b 100644 --- a/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentCreateRequestDto.java +++ b/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentCreateRequestDto.java @@ -1,5 +1,7 @@ package com.first.flash.climbing.solution.application.dto; -public record SolutionCommentCreateRequestDto(String content) { +import jakarta.validation.constraints.NotEmpty; + +public record SolutionCommentCreateRequestDto(@NotEmpty String content) { } diff --git a/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentUpdateRequestDto.java b/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentUpdateRequestDto.java index 09063b68..8e1b94dc 100644 --- a/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentUpdateRequestDto.java +++ b/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentUpdateRequestDto.java @@ -1,5 +1,7 @@ package com.first.flash.climbing.solution.application.dto; -public record SolutionCommentUpdateRequestDto(String content) { +import jakarta.validation.constraints.NotNull; + +public record SolutionCommentUpdateRequestDto(@NotNull String content) { } diff --git a/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java b/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java index fa3626ba..a7253db5 100644 --- a/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java +++ b/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java @@ -6,7 +6,9 @@ import com.first.flash.climbing.solution.application.dto.SolutionCommentUpdateRequestDto; import com.first.flash.climbing.solution.application.dto.SolutionCommentsResponseDto; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -26,10 +28,11 @@ public class SolutionCommentController { @PostMapping("/solutions/{solutionId}/comments") public ResponseEntity createSolutionComment( @PathVariable final Long solutionId, - @RequestBody final SolutionCommentCreateRequestDto request) { + @RequestBody @Valid final SolutionCommentCreateRequestDto request) { SolutionCommentCreateResponseDto comment = solutionCommentService .createComment(solutionId, request); - return ResponseEntity.ok(comment); + return ResponseEntity.status(HttpStatus.CREATED) + .body(comment); } @GetMapping("/solutions/{solutionId}/comments") @@ -43,7 +46,7 @@ public ResponseEntity getSolutionComments( @PatchMapping("/comments/{commentId}") public ResponseEntity updateComment( @PathVariable final Long commentId, - @RequestBody final SolutionCommentUpdateRequestDto content) { + @RequestBody @Valid final SolutionCommentUpdateRequestDto content) { solutionCommentService.updateComment(commentId, content); return ResponseEntity.ok().build(); } From 924d508229aff05f600cfa7fcce4ec8079949984 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 18:46:48 +0900 Subject: [PATCH 21/38] =?UTF-8?q?FLASH-270=20feat:=20=EB=8C=93=EA=B8=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EC=8B=9C=EC=97=90=EB=8F=84=20=EC=9D=91?= =?UTF-8?q?=EB=8B=B5=EC=9D=84=20=EB=B0=9B=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../climbing/solution/application/SolutionCommentService.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java b/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java index 464cd0f0..299d1b63 100644 --- a/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java +++ b/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java @@ -7,6 +7,7 @@ import com.first.flash.climbing.solution.application.dto.SolutionCommentResponseDto; import com.first.flash.climbing.solution.application.dto.SolutionCommentUpdateRequestDto; import com.first.flash.climbing.solution.application.dto.SolutionCommentsResponseDto; +import com.first.flash.climbing.solution.application.dto.SolutionResponseDto; import com.first.flash.climbing.solution.domain.Solution; import com.first.flash.climbing.solution.domain.SolutionComment; import com.first.flash.climbing.solution.exception.exceptions.SolutionCommentAccessDeniedException; @@ -58,12 +59,13 @@ public SolutionCommentsResponseDto findBySolutionId(final Long solutionId) { } @Transactional - public void updateComment(final Long commentId, final SolutionCommentUpdateRequestDto request) { + public SolutionResponseDto updateComment(final Long commentId, final SolutionCommentUpdateRequestDto request) { SolutionComment comment = findById(commentId); if (!AuthUtil.isSameId(comment.getCommenterDetail().getCommenterId())) { throw new SolutionCommentAccessDeniedException(); } comment.updateContent(request.content()); + return SolutionResponseDto.toDto(comment.getSolution()); } @Transactional From 135c6c49f4ee0795e2ea07a7d575579b3ffefa66 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 18:47:03 +0900 Subject: [PATCH 22/38] =?UTF-8?q?FLASH-270=20feat:=20api=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20swagger=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/SolutionCommentController.java | 69 +++++++++++++++++-- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java b/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java index a7253db5..26e4c978 100644 --- a/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java +++ b/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java @@ -5,6 +5,13 @@ import com.first.flash.climbing.solution.application.dto.SolutionCommentCreateResponseDto; import com.first.flash.climbing.solution.application.dto.SolutionCommentUpdateRequestDto; import com.first.flash.climbing.solution.application.dto.SolutionCommentsResponseDto; +import com.first.flash.climbing.solution.application.dto.SolutionResponseDto; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -25,6 +32,19 @@ public class SolutionCommentController { private final SolutionCommentService solutionCommentService; + @Operation(summary = "해설 댓글 생성", description = "특정 해설에 대한 댓글 생성") + @ApiResponses(value = { + @ApiResponse(responseCode = "201", description = "성공적으로 댓글 생성", + content = @Content(mediaType = "application/json", schema = @Schema(implementation = SolutionCommentCreateRequestDto.class))), + @ApiResponse(responseCode = "400", description = "유효하지 않은 요청 형식", + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "요청값 누락", value = "{\"error\": \"content는 필수입니다.\"}"), + })), + @ApiResponse(responseCode = "404", description = "해설을 찾을 수 없음", + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "해설 없음", value = "{\"error\": \"아이디가 1인 해설을 찾을 수 없습니다.\"}") + })) + }) @PostMapping("/solutions/{solutionId}/comments") public ResponseEntity createSolutionComment( @PathVariable final Long solutionId, @@ -35,6 +55,15 @@ public ResponseEntity createSolutionComment( .body(comment); } + @Operation(summary = "댓글 조회", description = "특정 해설에 대한 댓글 조회") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "성공적으로 댓글을 조회함", + content = @Content(mediaType = "application/json", schema = @Schema(implementation = SolutionCommentsResponseDto.class))), + @ApiResponse(responseCode = "404", description = "해설을 찾을 수 없음", + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "해설 없음", value = "{\"error\": \"아이디가 1인 해설을 찾을 수 없습니다.\"}") + })) + }) @GetMapping("/solutions/{solutionId}/comments") public ResponseEntity getSolutionComments( @PathVariable final Long solutionId) { @@ -43,18 +72,50 @@ public ResponseEntity getSolutionComments( return ResponseEntity.ok(comments); } + @Operation(summary = "댓글 수정", description = "내 댓글 수정") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "성공적으로 댓글을 수정함", + content = @Content(mediaType = "application/json", schema = @Schema(implementation = SolutionResponseDto.class))), + @ApiResponse(responseCode = "400", description = "유효하지 않은 요청 형식", + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "요청값 누락", value = "{\"error\": \"content는 필수입니다.\"}"), + })), + @ApiResponse(responseCode = "403", description = "본인의 댓글이 아님", + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "수정 권한 없음", value = "{\"error\": \"해당 댓글에 접근할 권한이 없습니다.\"}"), + })), + @ApiResponse(responseCode = "404", description = "리소스를 찾을 수 없음", + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "댓글 없음", value = "{\"error\": \"아이디가 1인 댓글을 찾을 수 없습니다.\"}") + })) + }) @PatchMapping("/comments/{commentId}") - public ResponseEntity updateComment( + public ResponseEntity updateComment( @PathVariable final Long commentId, @RequestBody @Valid final SolutionCommentUpdateRequestDto content) { - solutionCommentService.updateComment(commentId, content); - return ResponseEntity.ok().build(); + SolutionResponseDto response = solutionCommentService.updateComment(commentId, + content); + return ResponseEntity.status(HttpStatus.OK) + .body(response); } + @Operation(summary = "댓글 삭제", description = "특정 댓글 삭제") + @ApiResponses(value = { + @ApiResponse(responseCode = "204", description = "성공적으로 댓글을 삭제함", + content = @Content(mediaType = "application/json")), + @ApiResponse(responseCode = "403", description = "본인의 댓글이 아님", + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "삭제 권한 없음", value = "{\"error\": \"해당 댓글에 접근할 권한이 없습니다.\"}"), + })), + @ApiResponse(responseCode = "404", description = "리소스를 찾을 수 없음", + content = @Content(mediaType = "application/json", examples = { + @ExampleObject(name = "댓글 없음", value = "{\"error\": \"아이디가 1인 댓글을 찾을 수 없습니다.\"}") + })) + }) @DeleteMapping("/comments/{commentId}") public ResponseEntity deleteComment( @PathVariable final Long commentId) { solutionCommentService.deleteComment(commentId); - return ResponseEntity.ok().build(); + return ResponseEntity.noContent().build(); } } From 0a5c57a2942a64aec27eb0490916ad51b9588f68 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 19:16:38 +0900 Subject: [PATCH 23/38] =?UTF-8?q?FLASH-270=20feat:=20=EB=82=B4=20=EB=8C=93?= =?UTF-8?q?=EA=B8=80=EC=9D=B8=EC=A7=80=20=EC=97=AC=EB=B6=80=EB=A5=BC=20?= =?UTF-8?q?=EC=95=8C=EB=A0=A4=EC=A3=BC=EB=8A=94=20=ED=95=84=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../application/dto/SolutionCommentResponseDto.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentResponseDto.java b/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentResponseDto.java index 8ba5d9f9..22e8e904 100644 --- a/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentResponseDto.java +++ b/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionCommentResponseDto.java @@ -1,15 +1,18 @@ package com.first.flash.climbing.solution.application.dto; import com.first.flash.climbing.solution.domain.SolutionComment; +import com.first.flash.global.util.AuthUtil; import java.util.UUID; public record SolutionCommentResponseDto(Long id, String content, UUID commenterId, String nickName, - String profileImageUrl) { + String profileImageUrl, boolean isMine) { public static SolutionCommentResponseDto toDto(final SolutionComment solutionComment) { return new SolutionCommentResponseDto(solutionComment.getId(), solutionComment.getContent(), solutionComment.getCommenterDetail().getCommenterId(), solutionComment.getCommenterDetail().getCommenter(), - solutionComment.getCommenterDetail().getProfileImageUrl()); + solutionComment.getCommenterDetail().getProfileImageUrl(), + solutionComment.getCommenterDetail().getCommenterId().equals(AuthUtil.getId()) + ); } } From ff3086756f7c824c962611f10532fcf45d935de1 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 20:24:30 +0900 Subject: [PATCH 24/38] =?UTF-8?q?FLASH-270=20feat:=20cascade=20solution=20?= =?UTF-8?q?=EC=AA=BD=EC=97=90=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../first/flash/climbing/solution/domain/SolutionComment.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/first/flash/climbing/solution/domain/SolutionComment.java b/src/main/java/com/first/flash/climbing/solution/domain/SolutionComment.java index 3ed563d0..5b48e4a6 100644 --- a/src/main/java/com/first/flash/climbing/solution/domain/SolutionComment.java +++ b/src/main/java/com/first/flash/climbing/solution/domain/SolutionComment.java @@ -1,7 +1,6 @@ package com.first.flash.climbing.solution.domain; import com.first.flash.global.domain.BaseEntity; -import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; @@ -32,7 +31,7 @@ public class SolutionComment extends BaseEntity { private CommenterDetail commenterDetail; - @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "solution_id", nullable = false) private Solution solution; From 2bfe9a1a196b6cfe1ab36301910fbb8743d9a4bb Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 20:24:48 +0900 Subject: [PATCH 25/38] =?UTF-8?q?FLASH-270=20feat:=20=EC=88=9C=ED=99=98=20?= =?UTF-8?q?=EC=B0=B8=EC=A1=B0=EB=A5=BC=20=ED=94=BC=ED=95=98=EA=B8=B0=20?= =?UTF-8?q?=EC=9C=84=ED=95=B4=20comments=EC=9D=98=20toString=20=EC=A0=9C?= =?UTF-8?q?=EC=99=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/first/flash/climbing/solution/domain/Solution.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/com/first/flash/climbing/solution/domain/Solution.java b/src/main/java/com/first/flash/climbing/solution/domain/Solution.java index f8d67812..2f3245c4 100644 --- a/src/main/java/com/first/flash/climbing/solution/domain/Solution.java +++ b/src/main/java/com/first/flash/climbing/solution/domain/Solution.java @@ -3,11 +3,14 @@ import com.first.flash.climbing.solution.domain.vo.SolutionDetail; import com.first.flash.climbing.solution.domain.vo.UploaderDetail; import com.first.flash.global.domain.BaseEntity; +import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import java.util.List; import java.util.UUID; import lombok.AllArgsConstructor; import lombok.Getter; @@ -31,6 +34,9 @@ public class Solution extends BaseEntity { private SolutionDetail solutionDetail; private UploaderDetail uploaderDetail; private Long optionalWeight; + @OneToMany(mappedBy = "solution", cascade = CascadeType.ALL, orphanRemoval = true) + @ToString.Exclude + private List comments; protected Solution(final String uploader, final String review, final String instagramId, final String videoUrl, final UUID problemId, final UUID uploaderId, From 4eb209c0e232f01f0e9819ccf3fbf2066ff675f0 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 20:25:37 +0900 Subject: [PATCH 26/38] =?UTF-8?q?FLASH-270=20fix:=20=EB=8C=93=EA=B8=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20=EC=9D=91=EB=8B=B5=20dto=20=EC=98=AC?= =?UTF-8?q?=EB=B0=94=EB=A5=B4=EA=B2=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solution/application/SolutionCommentService.java | 5 +++-- .../climbing/solution/ui/SolutionCommentController.java | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java b/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java index 299d1b63..b690668b 100644 --- a/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java +++ b/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java @@ -59,13 +59,14 @@ public SolutionCommentsResponseDto findBySolutionId(final Long solutionId) { } @Transactional - public SolutionResponseDto updateComment(final Long commentId, final SolutionCommentUpdateRequestDto request) { + public SolutionCommentResponseDto updateComment(final Long commentId, + final SolutionCommentUpdateRequestDto request) { SolutionComment comment = findById(commentId); if (!AuthUtil.isSameId(comment.getCommenterDetail().getCommenterId())) { throw new SolutionCommentAccessDeniedException(); } comment.updateContent(request.content()); - return SolutionResponseDto.toDto(comment.getSolution()); + return SolutionCommentResponseDto.toDto(comment); } @Transactional diff --git a/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java b/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java index 26e4c978..ea4dbbe8 100644 --- a/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java +++ b/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java @@ -3,6 +3,7 @@ import com.first.flash.climbing.solution.application.SolutionCommentService; import com.first.flash.climbing.solution.application.dto.SolutionCommentCreateRequestDto; import com.first.flash.climbing.solution.application.dto.SolutionCommentCreateResponseDto; +import com.first.flash.climbing.solution.application.dto.SolutionCommentResponseDto; import com.first.flash.climbing.solution.application.dto.SolutionCommentUpdateRequestDto; import com.first.flash.climbing.solution.application.dto.SolutionCommentsResponseDto; import com.first.flash.climbing.solution.application.dto.SolutionResponseDto; @@ -90,10 +91,10 @@ public ResponseEntity getSolutionComments( })) }) @PatchMapping("/comments/{commentId}") - public ResponseEntity updateComment( + public ResponseEntity updateComment( @PathVariable final Long commentId, @RequestBody @Valid final SolutionCommentUpdateRequestDto content) { - SolutionResponseDto response = solutionCommentService.updateComment(commentId, + SolutionCommentResponseDto response = solutionCommentService.updateComment(commentId, content); return ResponseEntity.status(HttpStatus.OK) .body(response); From 31c4182a07bc6b650064f47bd964d233f3adbb58 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Thu, 10 Oct 2024 20:26:04 +0900 Subject: [PATCH 27/38] =?UTF-8?q?FLASH-270=20feat:=20=EB=8C=93=EA=B8=80=20?= =?UTF-8?q?=EC=97=AC=EB=9F=AC=20=EA=B1=B4=20=EC=A1=B0=ED=9A=8C=20=EC=8B=9C?= =?UTF-8?q?=20solution=20=EC=9D=B4=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../climbing/solution/application/SolutionCommentService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java b/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java index b690668b..f912ea56 100644 --- a/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java +++ b/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java @@ -7,7 +7,6 @@ import com.first.flash.climbing.solution.application.dto.SolutionCommentResponseDto; import com.first.flash.climbing.solution.application.dto.SolutionCommentUpdateRequestDto; import com.first.flash.climbing.solution.application.dto.SolutionCommentsResponseDto; -import com.first.flash.climbing.solution.application.dto.SolutionResponseDto; import com.first.flash.climbing.solution.domain.Solution; import com.first.flash.climbing.solution.domain.SolutionComment; import com.first.flash.climbing.solution.exception.exceptions.SolutionCommentAccessDeniedException; @@ -50,7 +49,8 @@ public SolutionComment findById(final Long id) { } public SolutionCommentsResponseDto findBySolutionId(final Long solutionId) { - List comments = solutionCommentRepository.findBySolutionId(solutionId); + List comments = solutionService.findSolutionById(solutionId) + .getComments(); List commentsResponse = comments.stream() .map( SolutionCommentResponseDto::toDto) From 8314888c47bec392b22e3be76b23eef87eb64016 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Fri, 11 Oct 2024 13:18:49 +0900 Subject: [PATCH 28/38] =?UTF-8?q?FLASH-270=20refactor:=20dto=20=EB=B3=80?= =?UTF-8?q?=EC=88=98=EB=AA=85=20=ED=86=B5=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../climbing/solution/application/SolutionCommentService.java | 4 ++-- .../flash/climbing/solution/ui/SolutionCommentController.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java b/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java index f912ea56..e9d48275 100644 --- a/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java +++ b/src/main/java/com/first/flash/climbing/solution/application/SolutionCommentService.java @@ -30,12 +30,12 @@ public class SolutionCommentService { @Transactional public SolutionCommentCreateResponseDto createComment(final Long solutionId, - final SolutionCommentCreateRequestDto requestDto) { + final SolutionCommentCreateRequestDto request) { UUID id = AuthUtil.getId(); Member member = memberService.findById(id); Solution solution = solutionService.findSolutionById(solutionId); - SolutionComment solutionComment = SolutionComment.of(requestDto.content(), + SolutionComment solutionComment = SolutionComment.of(request.content(), member.getNickName(), member.getProfileImageUrl(), member.getId(), solution); SolutionComment savedSolutionComment = solutionCommentRepository.save(solutionComment); diff --git a/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java b/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java index ea4dbbe8..28ff245f 100644 --- a/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java +++ b/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java @@ -93,9 +93,9 @@ public ResponseEntity getSolutionComments( @PatchMapping("/comments/{commentId}") public ResponseEntity updateComment( @PathVariable final Long commentId, - @RequestBody @Valid final SolutionCommentUpdateRequestDto content) { + @RequestBody @Valid final SolutionCommentUpdateRequestDto request) { SolutionCommentResponseDto response = solutionCommentService.updateComment(commentId, - content); + request); return ResponseEntity.status(HttpStatus.OK) .body(response); } From 21d027c5d1d860fbdb759bc4b5ceec94576412a8 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Fri, 11 Oct 2024 13:19:50 +0900 Subject: [PATCH 29/38] =?UTF-8?q?FLASH-270=20fix:=20swagger=20=EC=9D=91?= =?UTF-8?q?=EB=8B=B5=20=EA=B0=9D=EC=B2=B4=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../flash/climbing/solution/ui/SolutionCommentController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java b/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java index 28ff245f..8300e306 100644 --- a/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java +++ b/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java @@ -36,7 +36,7 @@ public class SolutionCommentController { @Operation(summary = "해설 댓글 생성", description = "특정 해설에 대한 댓글 생성") @ApiResponses(value = { @ApiResponse(responseCode = "201", description = "성공적으로 댓글 생성", - content = @Content(mediaType = "application/json", schema = @Schema(implementation = SolutionCommentCreateRequestDto.class))), + content = @Content(mediaType = "application/json", schema = @Schema(implementation = SolutionCommentCreateResponseDto.class))), @ApiResponse(responseCode = "400", description = "유효하지 않은 요청 형식", content = @Content(mediaType = "application/json", examples = { @ExampleObject(name = "요청값 누락", value = "{\"error\": \"content는 필수입니다.\"}"), From 43ca0555612e825dccab2e07c815559aaf02ece1 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Fri, 11 Oct 2024 15:54:16 +0900 Subject: [PATCH 30/38] =?UTF-8?q?FLASH-293=20feat:=20=EC=93=B0=EA=B8=B0=20?= =?UTF-8?q?=EC=9E=91=EC=97=85=EC=97=90=20=EB=8C=80=ED=95=9C=20Solution=20?= =?UTF-8?q?=EC=9D=91=EB=8B=B5=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/SolutionWriteResponseDto.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/main/java/com/first/flash/climbing/solution/application/dto/SolutionWriteResponseDto.java diff --git a/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionWriteResponseDto.java b/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionWriteResponseDto.java new file mode 100644 index 00000000..b6c7360d --- /dev/null +++ b/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionWriteResponseDto.java @@ -0,0 +1,24 @@ +package com.first.flash.climbing.solution.application.dto; + +import com.first.flash.climbing.solution.domain.Solution; +import com.first.flash.climbing.solution.domain.vo.SolutionDetail; +import com.first.flash.climbing.solution.domain.vo.UploaderDetail; +import com.first.flash.global.util.AuthUtil; +import java.util.UUID; + +public record SolutionWriteResponseDto(Long id, String uploader, String review, String instagramId, + String videoUrl, UUID uploaderId, Boolean isUploader, + String profileImageUrl) { + + public static SolutionWriteResponseDto toDto(final Solution solution) { + SolutionDetail solutionDetail = solution.getSolutionDetail(); + UploaderDetail uploaderDetail = solution.getUploaderDetail(); + UUID uploaderId = uploaderDetail.getUploaderId(); + Boolean isUploader = AuthUtil.isSameId(uploaderId); + + return new SolutionWriteResponseDto(solution.getId(), uploaderDetail.getUploader(), + solutionDetail.getReview(), uploaderDetail.getInstagramId(), + solutionDetail.getVideoUrl(), uploaderDetail.getUploaderId(), isUploader, + uploaderDetail.getProfileImageUrl()); + } +} From c7ab254ff5be0a4e3d7c09feba5b952b9dbc4e5f Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Fri, 11 Oct 2024 15:56:05 +0900 Subject: [PATCH 31/38] =?UTF-8?q?FLASH-293=20feat:=20=EC=93=B0=EA=B8=B0=20?= =?UTF-8?q?=EC=9E=91=EC=97=85=EC=97=90=20=EB=8C=80=ED=95=9C=20dto=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../climbing/solution/ui/SolutionController.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/first/flash/climbing/solution/ui/SolutionController.java b/src/main/java/com/first/flash/climbing/solution/ui/SolutionController.java index 7664dd1e..594003d6 100644 --- a/src/main/java/com/first/flash/climbing/solution/ui/SolutionController.java +++ b/src/main/java/com/first/flash/climbing/solution/ui/SolutionController.java @@ -2,8 +2,8 @@ import com.first.flash.climbing.solution.application.SolutionSaveService; import com.first.flash.climbing.solution.application.SolutionService; -import com.first.flash.climbing.solution.application.dto.SolutionResponseDto; import com.first.flash.climbing.solution.application.dto.SolutionUpdateRequestDto; +import com.first.flash.climbing.solution.application.dto.SolutionWriteResponseDto; import com.first.flash.climbing.solution.application.dto.SolutionsPageResponseDto; import com.first.flash.climbing.solution.application.dto.SolutionsResponseDto; import com.first.flash.climbing.solution.application.dto.UnregisteredMemberSolutionCreateRequest; @@ -92,7 +92,7 @@ public ResponseEntity getSolutions(@PathVariable final UUI @Operation(summary = "해설 업로드", description = "특정 문제에 대한 해설 업로드") @ApiResponses(value = { @ApiResponse(responseCode = "201", description = "성공적으로 해설을 업로드함", - content = @Content(mediaType = "application/json", schema = @Schema(implementation = SolutionResponseDto.class))), + content = @Content(mediaType = "application/json", schema = @Schema(implementation = SolutionWriteResponseDto.class))), @ApiResponse(responseCode = "400", description = "유효하지 않은 요청 형식", content = @Content(mediaType = "application/json", examples = { @ExampleObject(name = "요청값 누락", value = "{\"videoUrl\": \"비디오 URL은 필수입니다.\"}"), @@ -103,7 +103,7 @@ public ResponseEntity getSolutions(@PathVariable final UUI })) }) @PostMapping("problems/{problemId}/solutions") - public ResponseEntity createSolution(@PathVariable final UUID problemId, + public ResponseEntity createSolution(@PathVariable final UUID problemId, @Valid @RequestBody final SolutionCreateRequestDto solutionCreateRequestDto) { return ResponseEntity.status(HttpStatus.CREATED) @@ -115,7 +115,7 @@ public ResponseEntity createSolution(@PathVariable final UU @Operation(summary = "없는 유저의 영상으로 해설 업로드", description = "없는 유저의 영상으로 해설 업로드") @ApiResponses(value = { @ApiResponse(responseCode = "201", description = "성공적으로 해설을 업로드함", - content = @Content(mediaType = "application/json", schema = @Schema(implementation = SolutionResponseDto.class))), + content = @Content(mediaType = "application/json", schema = @Schema(implementation = SolutionWriteResponseDto.class))), @ApiResponse(responseCode = "400", description = "유효하지 않은 요청 형식", content = @Content(mediaType = "application/json", examples = { @ExampleObject(name = "요청값 누락", value = "{\"videoUrl\": \"비디오 URL은 필수입니다.\"}"), @@ -126,7 +126,7 @@ public ResponseEntity createSolution(@PathVariable final UU })) }) @PostMapping("admin/problems/{problemId}/solutions") - public ResponseEntity createUnregisteredMemberSolution( + public ResponseEntity createUnregisteredMemberSolution( @PathVariable final UUID problemId, @Valid @RequestBody final UnregisteredMemberSolutionCreateRequest createRequestDto) { @@ -139,7 +139,7 @@ public ResponseEntity createUnregisteredMemberSolution( @Operation(summary = "해설 수정", description = "특정 해설 정보 수정") @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "성공적으로 해설을 수정함", - content = @Content(mediaType = "application/json", schema = @Schema(implementation = SolutionResponseDto.class))), + content = @Content(mediaType = "application/json", schema = @Schema(implementation = SolutionWriteResponseDto.class))), @ApiResponse(responseCode = "400", description = "유효하지 않은 요청 형식", content = @Content(mediaType = "application/json", examples = { @ExampleObject(name = "요청값 누락", value = "{\"videoUrl\": \"비디오 URL은 필수입니다.\"}"), @@ -154,7 +154,7 @@ public ResponseEntity createUnregisteredMemberSolution( })) }) @PatchMapping("/solutions/{solutionId}") - public ResponseEntity updateSolution(@PathVariable Long solutionId, + public ResponseEntity updateSolution(@PathVariable Long solutionId, @Valid @RequestBody final SolutionUpdateRequestDto solutionUpdateRequestDto) { return ResponseEntity.status(HttpStatus.OK) .body( From a3d98c83db24bfac8a46884ef82367669995018f Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Fri, 11 Oct 2024 15:57:53 +0900 Subject: [PATCH 32/38] =?UTF-8?q?FLASH-293=20feat:=20=EC=9D=BD=EA=B8=B0=20?= =?UTF-8?q?=EC=9E=91=EC=97=85=EC=97=90=20=EB=8C=80=ED=95=9C=20=EC=9D=91?= =?UTF-8?q?=EB=8B=B5=20dto=20=EC=9C=84=EC=B9=98=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../flash/climbing/solution/application/SolutionService.java | 1 + .../climbing/solution/application/dto/SolutionsResponseDto.java | 1 + .../dto/SolutionResponseDto.java | 2 +- .../flash/climbing/solution/ui/SolutionCommentController.java | 2 +- 4 files changed, 4 insertions(+), 2 deletions(-) rename src/main/java/com/first/flash/climbing/solution/{application => infrastructure}/dto/SolutionResponseDto.java (94%) diff --git a/src/main/java/com/first/flash/climbing/solution/application/SolutionService.java b/src/main/java/com/first/flash/climbing/solution/application/SolutionService.java index c5228c9f..b4412e7b 100644 --- a/src/main/java/com/first/flash/climbing/solution/application/SolutionService.java +++ b/src/main/java/com/first/flash/climbing/solution/application/SolutionService.java @@ -15,6 +15,7 @@ import com.first.flash.climbing.solution.exception.exceptions.SolutionNotFoundException; import com.first.flash.climbing.solution.infrastructure.dto.DetailSolutionDto; import com.first.flash.climbing.solution.infrastructure.dto.MySolutionDto; +import com.first.flash.climbing.solution.infrastructure.dto.SolutionResponseDto; import com.first.flash.climbing.solution.infrastructure.paging.SolutionCursor; import com.first.flash.global.event.Events; import com.first.flash.global.util.AuthUtil; diff --git a/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionsResponseDto.java b/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionsResponseDto.java index 70bab455..9c5da937 100644 --- a/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionsResponseDto.java +++ b/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionsResponseDto.java @@ -1,5 +1,6 @@ package com.first.flash.climbing.solution.application.dto; +import com.first.flash.climbing.solution.infrastructure.dto.SolutionResponseDto; import java.util.List; public record SolutionsResponseDto(List solutions, diff --git a/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionResponseDto.java b/src/main/java/com/first/flash/climbing/solution/infrastructure/dto/SolutionResponseDto.java similarity index 94% rename from src/main/java/com/first/flash/climbing/solution/application/dto/SolutionResponseDto.java rename to src/main/java/com/first/flash/climbing/solution/infrastructure/dto/SolutionResponseDto.java index cfebd4af..e148f750 100644 --- a/src/main/java/com/first/flash/climbing/solution/application/dto/SolutionResponseDto.java +++ b/src/main/java/com/first/flash/climbing/solution/infrastructure/dto/SolutionResponseDto.java @@ -1,4 +1,4 @@ -package com.first.flash.climbing.solution.application.dto; +package com.first.flash.climbing.solution.infrastructure.dto; import com.first.flash.climbing.solution.domain.Solution; import com.first.flash.climbing.solution.domain.vo.SolutionDetail; diff --git a/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java b/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java index 8300e306..253b40f0 100644 --- a/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java +++ b/src/main/java/com/first/flash/climbing/solution/ui/SolutionCommentController.java @@ -6,7 +6,7 @@ import com.first.flash.climbing.solution.application.dto.SolutionCommentResponseDto; import com.first.flash.climbing.solution.application.dto.SolutionCommentUpdateRequestDto; import com.first.flash.climbing.solution.application.dto.SolutionCommentsResponseDto; -import com.first.flash.climbing.solution.application.dto.SolutionResponseDto; +import com.first.flash.climbing.solution.infrastructure.dto.SolutionResponseDto; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.ExampleObject; From ce9d2a5a02aae4eaabb93e201d318c1ef8ba41ac Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Fri, 11 Oct 2024 15:58:29 +0900 Subject: [PATCH 33/38] =?UTF-8?q?FLASH-293=20feat:=20=EC=9D=BD=EA=B8=B0=20?= =?UTF-8?q?=EC=9E=91=EC=97=85=EC=97=90=20=EB=8C=80=ED=95=9C=20=EC=9D=91?= =?UTF-8?q?=EB=8B=B5=EB=93=A4=20=EB=AA=A8=EB=91=90=20=EB=8C=93=EA=B8=80=20?= =?UTF-8?q?=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../infrastructure/dto/DetailSolutionDto.java | 2 +- .../infrastructure/dto/MySolutionDto.java | 2 +- .../dto/SolutionResponseDto.java | 18 +----------------- 3 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/first/flash/climbing/solution/infrastructure/dto/DetailSolutionDto.java b/src/main/java/com/first/flash/climbing/solution/infrastructure/dto/DetailSolutionDto.java index d2d898ce..0a26ae4c 100644 --- a/src/main/java/com/first/flash/climbing/solution/infrastructure/dto/DetailSolutionDto.java +++ b/src/main/java/com/first/flash/climbing/solution/infrastructure/dto/DetailSolutionDto.java @@ -4,7 +4,7 @@ import java.time.LocalDateTime; public record DetailSolutionDto(Long solutionId, String videoUrl, String gymName, String sectorName, - String review, String difficultyName, LocalDate removalDate, + String review, String difficultyName, Long commentsCount, LocalDate removalDate, LocalDate settingDate, LocalDateTime uploadedAt) { } diff --git a/src/main/java/com/first/flash/climbing/solution/infrastructure/dto/MySolutionDto.java b/src/main/java/com/first/flash/climbing/solution/infrastructure/dto/MySolutionDto.java index 74e47dcb..91aed245 100644 --- a/src/main/java/com/first/flash/climbing/solution/infrastructure/dto/MySolutionDto.java +++ b/src/main/java/com/first/flash/climbing/solution/infrastructure/dto/MySolutionDto.java @@ -3,7 +3,7 @@ import java.time.LocalDateTime; public record MySolutionDto(Long solutionId, String gymName, String sectorName, - String difficultyName, String problemImageUrl, + String difficultyName, String problemImageUrl, Long commentsCount, LocalDateTime uploadedAt) { } diff --git a/src/main/java/com/first/flash/climbing/solution/infrastructure/dto/SolutionResponseDto.java b/src/main/java/com/first/flash/climbing/solution/infrastructure/dto/SolutionResponseDto.java index e148f750..f449dd2c 100644 --- a/src/main/java/com/first/flash/climbing/solution/infrastructure/dto/SolutionResponseDto.java +++ b/src/main/java/com/first/flash/climbing/solution/infrastructure/dto/SolutionResponseDto.java @@ -1,25 +1,9 @@ package com.first.flash.climbing.solution.infrastructure.dto; -import com.first.flash.climbing.solution.domain.Solution; -import com.first.flash.climbing.solution.domain.vo.SolutionDetail; -import com.first.flash.climbing.solution.domain.vo.UploaderDetail; -import com.first.flash.global.util.AuthUtil; import java.util.UUID; public record SolutionResponseDto(Long id, String uploader, String review, String instagramId, String videoUrl, UUID uploaderId, Boolean isUploader, - String profileImageUrl) { + String profileImageUrl, Long commentCount) { - public static SolutionResponseDto toDto(final Solution solution) { - SolutionDetail solutionDetail = solution.getSolutionDetail(); - UploaderDetail uploaderDetail = solution.getUploaderDetail(); - - UUID uploaderId = uploaderDetail.getUploaderId(); - Boolean isUploader = AuthUtil.isSameId(uploaderId); - - return new SolutionResponseDto(solution.getId(), uploaderDetail.getUploader(), - solutionDetail.getReview(), uploaderDetail.getInstagramId(), - solutionDetail.getVideoUrl(), uploaderDetail.getUploaderId(), isUploader, - uploaderDetail.getProfileImageUrl()); - } } From d787bc05399f598b38a5fb9f6d7c67075dea5836 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Fri, 11 Oct 2024 15:59:22 +0900 Subject: [PATCH 34/38] =?UTF-8?q?FLASH-293=20feat:=20NPE=20=EB=B0=A9?= =?UTF-8?q?=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/first/flash/climbing/solution/domain/Solution.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/first/flash/climbing/solution/domain/Solution.java b/src/main/java/com/first/flash/climbing/solution/domain/Solution.java index 2f3245c4..b567dea2 100644 --- a/src/main/java/com/first/flash/climbing/solution/domain/Solution.java +++ b/src/main/java/com/first/flash/climbing/solution/domain/Solution.java @@ -10,6 +10,7 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.OneToMany; +import java.util.ArrayList; import java.util.List; import java.util.UUID; import lombok.AllArgsConstructor; @@ -36,7 +37,7 @@ public class Solution extends BaseEntity { private Long optionalWeight; @OneToMany(mappedBy = "solution", cascade = CascadeType.ALL, orphanRemoval = true) @ToString.Exclude - private List comments; + private List comments = new ArrayList<>(); protected Solution(final String uploader, final String review, final String instagramId, final String videoUrl, final UUID problemId, final UUID uploaderId, From d21db9d6bb6b58a445416e193660f046ec833ff2 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Fri, 11 Oct 2024 16:00:29 +0900 Subject: [PATCH 35/38] =?UTF-8?q?FLASH-293=20feat:=20=EC=A0=80=EC=9E=A5,?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=20=ED=9B=84=20SolutionWriteResponseDto?= =?UTF-8?q?=EB=A5=BC=20=EB=B0=98=ED=99=98=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solution/application/SolutionSaveService.java | 10 +++++----- .../climbing/solution/application/SolutionService.java | 7 +++---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/first/flash/climbing/solution/application/SolutionSaveService.java b/src/main/java/com/first/flash/climbing/solution/application/SolutionSaveService.java index 341e5cee..db69e6c1 100644 --- a/src/main/java/com/first/flash/climbing/solution/application/SolutionSaveService.java +++ b/src/main/java/com/first/flash/climbing/solution/application/SolutionSaveService.java @@ -2,7 +2,7 @@ import com.first.flash.account.member.application.MemberService; import com.first.flash.account.member.domain.Member; -import com.first.flash.climbing.solution.application.dto.SolutionResponseDto; +import com.first.flash.climbing.solution.application.dto.SolutionWriteResponseDto; import com.first.flash.climbing.solution.application.dto.UnregisteredMemberSolutionCreateRequest; import com.first.flash.climbing.solution.domain.Solution; import com.first.flash.climbing.solution.domain.SolutionRepository; @@ -24,7 +24,7 @@ public class SolutionSaveService { private final SolutionRepository solutionRepository; @Transactional - public SolutionResponseDto saveSolution(final UUID problemId, + public SolutionWriteResponseDto saveSolution(final UUID problemId, final SolutionCreateRequestDto createRequestDto) { UUID id = AuthUtil.getId(); Member member = memberService.findById(id); @@ -34,7 +34,7 @@ public SolutionResponseDto saveSolution(final UUID problemId, member.getProfileImageUrl()); Solution savedSolution = solutionRepository.save(solution); Events.raise(SolutionSavedEvent.of(savedSolution.getProblemId())); - return SolutionResponseDto.toDto(savedSolution); + return SolutionWriteResponseDto.toDto(savedSolution); } @Transactional @@ -44,7 +44,7 @@ public void updateUploaderInfo(final UUID uploaderId, final String nickName, } @Transactional - public SolutionResponseDto saveUnregisteredMemberSolution(final UUID problemId, + public SolutionWriteResponseDto saveUnregisteredMemberSolution(final UUID problemId, final UnregisteredMemberSolutionCreateRequest requestDto) { UUID id = AuthUtil.getId(); Member member = memberService.findById(id); @@ -54,6 +54,6 @@ public SolutionResponseDto saveUnregisteredMemberSolution(final UUID problemId, requestDto.profileImageUrl()); Solution savedSolution = solutionRepository.save(solution); Events.raise(SolutionSavedEvent.of(savedSolution.getProblemId())); - return SolutionResponseDto.toDto(savedSolution); + return SolutionWriteResponseDto.toDto(savedSolution); } } diff --git a/src/main/java/com/first/flash/climbing/solution/application/SolutionService.java b/src/main/java/com/first/flash/climbing/solution/application/SolutionService.java index b4412e7b..096ddb8c 100644 --- a/src/main/java/com/first/flash/climbing/solution/application/SolutionService.java +++ b/src/main/java/com/first/flash/climbing/solution/application/SolutionService.java @@ -3,9 +3,8 @@ import com.first.flash.account.member.application.BlockService; import com.first.flash.climbing.gym.domian.ClimbingGymIdConfirmRequestedEvent; import com.first.flash.climbing.problem.domain.ProblemIdConfirmRequestedEvent; -import com.first.flash.climbing.solution.application.dto.MySolutionsResponseDto; -import com.first.flash.climbing.solution.application.dto.SolutionResponseDto; import com.first.flash.climbing.solution.application.dto.SolutionUpdateRequestDto; +import com.first.flash.climbing.solution.application.dto.SolutionWriteResponseDto; import com.first.flash.climbing.solution.application.dto.SolutionsPageResponseDto; import com.first.flash.climbing.solution.application.dto.SolutionsResponseDto; import com.first.flash.climbing.solution.domain.Solution; @@ -69,7 +68,7 @@ public SolutionsPageResponseDto findMySolutions(final String cursor, final int s } @Transactional - public SolutionResponseDto updateContent(final Long id, + public SolutionWriteResponseDto updateContent(final Long id, final SolutionUpdateRequestDto requestDto) { Solution solution = solutionRepository.findById(id) @@ -80,7 +79,7 @@ public SolutionResponseDto updateContent(final Long id, solution.updateContentInfo(requestDto.review(), requestDto.videoUrl()); - return SolutionResponseDto.toDto(solution); + return SolutionWriteResponseDto.toDto(solution); } @Transactional From 457bb9570482aeaa14fa7a58e714d5915acc45c5 Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Fri, 11 Oct 2024 16:01:15 +0900 Subject: [PATCH 36/38] =?UTF-8?q?FLASH-293=20feat:=20solution=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20=EC=9D=91=EB=8B=B5=20dto=EB=A5=BC=20=EB=B0=98?= =?UTF-8?q?=ED=99=98=ED=95=98=EB=8F=84=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 --- .../flash/climbing/solution/domain/SolutionRepository.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/first/flash/climbing/solution/domain/SolutionRepository.java b/src/main/java/com/first/flash/climbing/solution/domain/SolutionRepository.java index 5c622cb8..f610fc6a 100644 --- a/src/main/java/com/first/flash/climbing/solution/domain/SolutionRepository.java +++ b/src/main/java/com/first/flash/climbing/solution/domain/SolutionRepository.java @@ -2,6 +2,7 @@ import com.first.flash.climbing.solution.infrastructure.dto.DetailSolutionDto; import com.first.flash.climbing.solution.infrastructure.dto.MySolutionDto; +import com.first.flash.climbing.solution.infrastructure.dto.SolutionResponseDto; import com.first.flash.climbing.solution.infrastructure.paging.SolutionCursor; import java.util.List; import java.util.Optional; @@ -13,7 +14,8 @@ public interface SolutionRepository { Optional findById(final Long id); - List findAllByProblemId(final UUID problemId, final List blockedMembers); + List findAllByProblemId(final UUID problemId, final UUID memberId, + final List blockedMembers); void deleteById(final Long id); From f7aeb1e95522001528269504b7ad74cb3a0487cd Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Fri, 11 Oct 2024 16:02:49 +0900 Subject: [PATCH 37/38] =?UTF-8?q?FLASH-293=20feat:=20=EB=B3=B8=EC=9D=B8?= =?UTF-8?q?=EC=9D=98=20=ED=95=B4=EC=84=A4=EC=9D=B8=EC=A7=80=20=ED=8C=90?= =?UTF-8?q?=EB=8B=A8=ED=95=98=EB=8A=94=20=EC=9E=91=EC=97=85=EC=9D=84=20DB?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EA=B0=80=EC=A0=B8=EC=98=AC=20=EB=95=8C?= =?UTF-8?q?=EB=B6=80=ED=84=B0=20=EC=A7=84=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solution/application/SolutionService.java | 5 +---- .../infrastructure/SolutionRepositoryImpl.java | 13 ++++++------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/first/flash/climbing/solution/application/SolutionService.java b/src/main/java/com/first/flash/climbing/solution/application/SolutionService.java index 096ddb8c..9af8b87c 100644 --- a/src/main/java/com/first/flash/climbing/solution/application/SolutionService.java +++ b/src/main/java/com/first/flash/climbing/solution/application/SolutionService.java @@ -46,10 +46,7 @@ public SolutionsResponseDto findAllSolutionsByProblemId(final UUID problemId) { Events.raise(ProblemIdConfirmRequestedEvent.of(problemId)); List blockedMembers = blockService.findBlockedMembers(); List solutions = solutionRepository.findAllByProblemId(problemId, - blockedMembers) - .stream() - .map(SolutionResponseDto::toDto) - .toList(); + AuthUtil.getId(), blockedMembers); return SolutionsResponseDto.of(solutions); } diff --git a/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionRepositoryImpl.java b/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionRepositoryImpl.java index c1ee5993..9bf83090 100644 --- a/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionRepositoryImpl.java +++ b/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionRepositoryImpl.java @@ -4,6 +4,7 @@ import com.first.flash.climbing.solution.domain.SolutionRepository; import com.first.flash.climbing.solution.infrastructure.dto.DetailSolutionDto; import com.first.flash.climbing.solution.infrastructure.dto.MySolutionDto; +import com.first.flash.climbing.solution.infrastructure.dto.SolutionResponseDto; import com.first.flash.climbing.solution.infrastructure.paging.SolutionCursor; import java.util.List; import java.util.Optional; @@ -29,13 +30,10 @@ public Optional findById(final Long id) { } @Override - public List findAllByProblemId(final UUID problemId, - final List blockedMembers) { - if (blockedMembers.isEmpty()) { - return solutionJpaRepository.findByProblemId(problemId); - } + public List findAllByProblemId(final UUID problemId, + final UUID memberId, final List blockedMembers) { return solutionQueryDslRepository.findAllExcludedBlockedMembers( - problemId, blockedMembers); + problemId, memberId, blockedMembers); } @Override @@ -61,7 +59,8 @@ public void deleteByUploaderId(final UUID memberId) { } @Override - public List findMySolutions(final UUID myId, final SolutionCursor prevSolutionCursor, + public List findMySolutions(final UUID myId, + final SolutionCursor prevSolutionCursor, final int size, final Long gymId, final List difficulty) { return solutionQueryDslRepository.findByUploaderId(myId, prevSolutionCursor, size, gymId, difficulty); From 4b2ab1f7ff059c721996f75272ef352cd792610e Mon Sep 17 00:00:00 2001 From: WonyuChoi Date: Fri, 11 Oct 2024 16:03:25 +0900 Subject: [PATCH 38/38] =?UTF-8?q?FLASH-293=20feat:=20solution=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=20dto=EC=97=90=20comment=20=EA=B0=9C=EC=88=98=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SolutionQueryDslRepository.java | 47 ++++++++++++++----- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionQueryDslRepository.java b/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionQueryDslRepository.java index 02587a31..ec27abb5 100644 --- a/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionQueryDslRepository.java +++ b/src/main/java/com/first/flash/climbing/solution/infrastructure/SolutionQueryDslRepository.java @@ -2,12 +2,12 @@ import static com.first.flash.climbing.problem.domain.QQueryProblem.queryProblem; import static com.first.flash.climbing.solution.domain.QSolution.solution; +import static com.first.flash.climbing.solution.domain.QSolutionComment.solutionComment; -import com.first.flash.climbing.solution.domain.Solution; import com.first.flash.climbing.solution.infrastructure.dto.DetailSolutionDto; import com.first.flash.climbing.solution.infrastructure.dto.MySolutionDto; +import com.first.flash.climbing.solution.infrastructure.dto.SolutionResponseDto; import com.first.flash.climbing.solution.infrastructure.paging.SolutionCursor; -import com.querydsl.core.types.Predicate; import com.querydsl.core.types.Projections; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.impl.JPAQueryFactory; @@ -24,12 +24,21 @@ public class SolutionQueryDslRepository { private final JPAQueryFactory jpaQueryFactory; - public List findAllExcludedBlockedMembers(final UUID problemId, - final List memberIds) { - return jpaQueryFactory.selectFrom(solution) + public List findAllExcludedBlockedMembers(final UUID problemId, + final UUID memberId, final List memberIds) { + return jpaQueryFactory.select(Projections.constructor(SolutionResponseDto.class, + solution.id, solution.uploaderDetail.uploader, solution.solutionDetail.review, + solution.uploaderDetail.instagramId, solution.solutionDetail.videoUrl, + solution.uploaderDetail.uploaderId, solution.uploaderDetail.uploaderId.eq(memberId), + solution.uploaderDetail.profileImageUrl, solutionComment.count() + )) + .from(solution) + .leftJoin(solutionComment) + .on(solution.id.eq(solutionComment.solution.id)) .where(solution.problemId.eq(problemId) - .and(solution.uploaderDetail.uploaderId - .notIn(memberIds))).fetch(); + .and(notInBlockedMembers(memberIds))) + .groupBy(solution.id) + .fetch(); } public List findByUploaderId(final UUID uploaderId, @@ -37,15 +46,18 @@ public List findByUploaderId(final UUID uploaderId, final List difficulty) { return jpaQueryFactory.select(Projections.constructor(MySolutionDto.class, solution.id, queryProblem.gymName, queryProblem.sectorName, - queryProblem.difficultyName, queryProblem.imageUrl, solution.createdAt + queryProblem.difficultyName, queryProblem.imageUrl, solutionComment.count(), + solution.createdAt )) .from(solution) .innerJoin(queryProblem) .on(solution.problemId.eq(queryProblem.id)) - .fetchJoin() + .leftJoin(solutionComment) + .on(solution.id.eq(solutionComment.solution.id)) .where(solution.uploaderDetail.uploaderId.eq(uploaderId), inGym(gymId), inDifficulties(difficulty), cursorCondition(prevSolutionCursor)) + .groupBy(solution.id) .orderBy(solution.createdAt.desc()) .limit(size) .fetch(); @@ -65,17 +77,19 @@ public DetailSolutionDto findDetailSolutionById(final Long solutionId) { return jpaQueryFactory.select(Projections.constructor(DetailSolutionDto.class, solution.id, solution.solutionDetail.videoUrl, queryProblem.gymName, queryProblem.sectorName, solution.solutionDetail.review, queryProblem.difficultyName, - queryProblem.removalDate, queryProblem.settingDate, solution.createdAt - )) + solutionComment.count(), queryProblem.removalDate, queryProblem.settingDate, + solution.createdAt)) .from(solution) .innerJoin(queryProblem) .on(solution.problemId.eq(queryProblem.id)) + .leftJoin(solutionComment) + .on(solution.id.eq(solutionComment.solution.id)) .where(solution.id.eq(solutionId)) - .fetchJoin() + .groupBy(solution.id) .fetchOne(); } - private Predicate cursorCondition(final SolutionCursor prevSolutionCursor) { + private BooleanExpression cursorCondition(final SolutionCursor prevSolutionCursor) { if (Objects.isNull(prevSolutionCursor) || Objects.isNull(prevSolutionCursor.cursorValue())) { return null; @@ -96,4 +110,11 @@ private BooleanExpression inDifficulties(final List difficulty) { } return queryProblem.difficultyName.in(difficulty); } + + private BooleanExpression notInBlockedMembers(final List memberIds) { + if (memberIds.isEmpty()) { + return null; + } + return solution.uploaderDetail.uploaderId.notIn(memberIds); + } }