From e2ac37b0e53d239a0f601c565238118138128a25 Mon Sep 17 00:00:00 2001 From: dungbik Date: Thu, 4 Dec 2025 17:42:31 +0900 Subject: [PATCH 1/4] =?UTF-8?q?Feat:=20=EC=B9=B4=EB=93=9C=EC=85=8B=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/BookmarkRepository.java | 2 + .../bookmark/service/BookmarkWriter.java | 24 ++++++++++ .../controller/GroupCardSetController.java | 13 ++++++ .../cardset/entity/CardSetContent.java | 38 ++++++++++++++++ .../cardset/entity/CardSetIncremental.java | 44 +++++++++++++++++++ .../repository/CardSetContentRepository.java | 9 ++++ .../CardSetIncrementalRepository.java | 9 ++++ .../repository/CardSetManagerRepository.java | 2 + .../cardset/service/CardSetService.java | 42 +++++++++++++++++- .../like/repository/LikeRepository.java | 2 + .../flipnote/like/service/LikeWriter.java | 24 ++++++++++ 11 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 src/main/java/project/flipnote/bookmark/service/BookmarkWriter.java create mode 100644 src/main/java/project/flipnote/cardset/entity/CardSetContent.java create mode 100644 src/main/java/project/flipnote/cardset/entity/CardSetIncremental.java create mode 100644 src/main/java/project/flipnote/cardset/repository/CardSetContentRepository.java create mode 100644 src/main/java/project/flipnote/cardset/repository/CardSetIncrementalRepository.java create mode 100644 src/main/java/project/flipnote/like/service/LikeWriter.java diff --git a/src/main/java/project/flipnote/bookmark/repository/BookmarkRepository.java b/src/main/java/project/flipnote/bookmark/repository/BookmarkRepository.java index 265bb967..bad19d70 100644 --- a/src/main/java/project/flipnote/bookmark/repository/BookmarkRepository.java +++ b/src/main/java/project/flipnote/bookmark/repository/BookmarkRepository.java @@ -21,4 +21,6 @@ public interface BookmarkRepository extends JpaRepository { List findAllByTargetTypeAndUserIdAndTargetIdIn( BookmarkTargetType targetType, Long userId, Set targetIds ); + + int deleteByTargetTypeAndTargetId(BookmarkTargetType targetType, Long targetId); } diff --git a/src/main/java/project/flipnote/bookmark/service/BookmarkWriter.java b/src/main/java/project/flipnote/bookmark/service/BookmarkWriter.java new file mode 100644 index 00000000..37419435 --- /dev/null +++ b/src/main/java/project/flipnote/bookmark/service/BookmarkWriter.java @@ -0,0 +1,24 @@ +package project.flipnote.bookmark.service; + +import org.springframework.stereotype.Service; + +import lombok.RequiredArgsConstructor; +import project.flipnote.bookmark.entity.BookmarkTargetType; +import project.flipnote.bookmark.repository.BookmarkRepository; + +@Service +@RequiredArgsConstructor +public class BookmarkWriter { + private final BookmarkRepository bookmarkRepository; + + /** + * 즐겨찾기를 삭제합니다. + * + * @param targetType 즐겨찾기 삭제할 대상의 타입 + * @param targetId 즐겨찾기 삭제할 대상의 ID + * @author 윤정환 + */ + public void delete(BookmarkTargetType targetType, Long targetId) { + return bookmarkRepository.deleteByTar(targetType, targetId); + } +} diff --git a/src/main/java/project/flipnote/cardset/controller/GroupCardSetController.java b/src/main/java/project/flipnote/cardset/controller/GroupCardSetController.java index 2af768d7..6925b11d 100644 --- a/src/main/java/project/flipnote/cardset/controller/GroupCardSetController.java +++ b/src/main/java/project/flipnote/cardset/controller/GroupCardSetController.java @@ -3,6 +3,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; @@ -22,6 +23,7 @@ import project.flipnote.cardset.model.CreateCardSetRequest; import project.flipnote.cardset.model.CreateCardSetResponse; import project.flipnote.cardset.service.CardSetService; +import project.flipnote.common.model.response.IdResponse; import project.flipnote.common.model.response.PagingResponse; import project.flipnote.common.security.dto.AuthPrinciple; @@ -75,4 +77,15 @@ public ResponseEntity> getCardSets( return ResponseEntity.ok(res); } + + @DeleteMapping("/{cardSetId}") + public ResponseEntity deleteCardSet( + @PathVariable("groupId") Long groupId, + @PathVariable("cardSetId") Long cardSetId, + @AuthenticationPrincipal AuthPrinciple authPrinciple + ) { + IdResponse res = cardSetService.deleteCardSet(authPrinciple.userId(), groupId, cardSetId); + + return ResponseEntity.ok(res); + } } diff --git a/src/main/java/project/flipnote/cardset/entity/CardSetContent.java b/src/main/java/project/flipnote/cardset/entity/CardSetContent.java new file mode 100644 index 00000000..b2674f29 --- /dev/null +++ b/src/main/java/project/flipnote/cardset/entity/CardSetContent.java @@ -0,0 +1,38 @@ +package project.flipnote.cardset.entity; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Lob; +import jakarta.persistence.Table; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import project.flipnote.common.entity.BaseEntity; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table(name = "cardset_contents") +@Entity +public class CardSetContent extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "cardset_id", nullable = false) + private Long cardSetId; + + @Lob + @Column(nullable = false) + private String content; + + @Builder + private CardSetContent(Long cardSetId, String content) { + this.cardSetId = cardSetId; + this.content = content; + } +} diff --git a/src/main/java/project/flipnote/cardset/entity/CardSetIncremental.java b/src/main/java/project/flipnote/cardset/entity/CardSetIncremental.java new file mode 100644 index 00000000..957a5a12 --- /dev/null +++ b/src/main/java/project/flipnote/cardset/entity/CardSetIncremental.java @@ -0,0 +1,44 @@ +package project.flipnote.cardset.entity; + +import org.hibernate.annotations.ColumnDefault; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Lob; +import jakarta.persistence.Table; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import project.flipnote.common.entity.BaseEntity; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Table(name = "cardset_contents") +@Entity +public class CardSetIncremental extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "cardset_id", nullable = false) + private Long cardSetId; + + @Lob + @Column(name = "incremental_value", nullable = false) + private byte[] incrementalValue; + + @Column(name = "is_flushed") + private boolean flushed; + + @Builder + private CardSetIncremental(Long cardSetId, byte[] incrementalValue, boolean flushed) { + this.cardSetId = cardSetId; + this.incrementalValue = incrementalValue; + this.flushed = flushed; + } +} diff --git a/src/main/java/project/flipnote/cardset/repository/CardSetContentRepository.java b/src/main/java/project/flipnote/cardset/repository/CardSetContentRepository.java new file mode 100644 index 00000000..6acc2a54 --- /dev/null +++ b/src/main/java/project/flipnote/cardset/repository/CardSetContentRepository.java @@ -0,0 +1,9 @@ +package project.flipnote.cardset.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import project.flipnote.cardset.entity.CardSetContent; + +public interface CardSetContentRepository extends JpaRepository { + void deleteByCardSetId(Long cardSetId); +} diff --git a/src/main/java/project/flipnote/cardset/repository/CardSetIncrementalRepository.java b/src/main/java/project/flipnote/cardset/repository/CardSetIncrementalRepository.java new file mode 100644 index 00000000..30644655 --- /dev/null +++ b/src/main/java/project/flipnote/cardset/repository/CardSetIncrementalRepository.java @@ -0,0 +1,9 @@ +package project.flipnote.cardset.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import project.flipnote.cardset.entity.CardSetIncremental; + +public interface CardSetIncrementalRepository extends JpaRepository { + void deleteByCardSetId(Long cardSetId); +} diff --git a/src/main/java/project/flipnote/cardset/repository/CardSetManagerRepository.java b/src/main/java/project/flipnote/cardset/repository/CardSetManagerRepository.java index 02367726..ea16c5b5 100644 --- a/src/main/java/project/flipnote/cardset/repository/CardSetManagerRepository.java +++ b/src/main/java/project/flipnote/cardset/repository/CardSetManagerRepository.java @@ -9,4 +9,6 @@ public interface CardSetManagerRepository extends JpaRepository { boolean existsByUser_IdAndCardSet_Id(Long userId, Long cardSetId); + + int deleteByCardSet_Id(Long cardSetId); } diff --git a/src/main/java/project/flipnote/cardset/service/CardSetService.java b/src/main/java/project/flipnote/cardset/service/CardSetService.java index 67cff14f..256a1e74 100644 --- a/src/main/java/project/flipnote/cardset/service/CardSetService.java +++ b/src/main/java/project/flipnote/cardset/service/CardSetService.java @@ -12,7 +12,7 @@ import lombok.extern.slf4j.Slf4j; import project.flipnote.bookmark.entity.BookmarkTargetType; import project.flipnote.bookmark.service.BookmarkReader; -import project.flipnote.bookmark.service.BookmarkService; +import project.flipnote.bookmark.service.BookmarkWriter; import project.flipnote.cardset.entity.CardSet; import project.flipnote.cardset.entity.CardSetManager; import project.flipnote.cardset.entity.CardSetMetadata; @@ -25,10 +25,13 @@ import project.flipnote.cardset.model.CardSetUpdateRequest; import project.flipnote.cardset.model.CreateCardSetRequest; import project.flipnote.cardset.model.CreateCardSetResponse; +import project.flipnote.cardset.repository.CardSetContentRepository; +import project.flipnote.cardset.repository.CardSetIncrementalRepository; import project.flipnote.cardset.repository.CardSetManagerRepository; import project.flipnote.cardset.repository.CardSetMetadataRepository; import project.flipnote.cardset.repository.CardSetRepository; import project.flipnote.common.exception.BizException; +import project.flipnote.common.model.response.IdResponse; import project.flipnote.common.model.response.PagingResponse; import project.flipnote.common.security.dto.AuthPrinciple; import project.flipnote.group.entity.Category; @@ -44,6 +47,7 @@ import project.flipnote.image.service.ImageService; import project.flipnote.like.entity.LikeTargetType; import project.flipnote.like.service.LikeReader; +import project.flipnote.like.service.LikeWriter; import project.flipnote.user.entity.UserProfile; import project.flipnote.user.entity.UserStatus; import project.flipnote.user.exception.UserErrorCode; @@ -67,6 +71,10 @@ public class CardSetService { private final GroupService groupService; private final LikeReader likeReader; private final BookmarkReader bookmarkReader; + private final LikeWriter likeWriter; + private final BookmarkWriter bookmarkWriter; + private final CardSetContentRepository cardSetContentRepository; + private final CardSetIncrementalRepository cardSetIncrementalRepository; @Value("${image.default.cardSet}") private String defaultCardSetImage; @@ -357,4 +365,36 @@ public PagingResponse getCardSets(long groupId, CardSetS return PagingResponse.from(res); } + + @Transactional + public IdResponse deleteCardSet(Long userId, Long groupId, Long cardSetId) { + CardSet cardSet = cardSetPolicyService.findByIdAndGroupIdOrThrow(groupId, cardSetId); + + cardSetPolicyService.validateCardSetEditable(userId, cardSetId); + + // 카드셋 관리자 + cardSetManagerRepository.deleteByCardSet_Id(cardSetId); + + // 카드셋 내용 + cardSetContentRepository.deleteByCardSetId(cardSetId); + + // 카드셋 증분값 + cardSetIncrementalRepository.deleteByCardSetId(cardSetId); + + // 카드셋 스냅샷 + + // 카드셋 메타데이터 + cardSetMetadataRepository.deleteById(cardSetId); + + // 카드셋 + cardSetRepository.delete(cardSet); + + // 좋아요 + likeWriter.delete(LikeTargetType.CARD_SET, cardSetId); + + // 즐겨찾기 + bookmarkWriter.delete(BookmarkTargetType.CARD_SET, cardSetId); + + return IdResponse.from(cardSetId); + } } diff --git a/src/main/java/project/flipnote/like/repository/LikeRepository.java b/src/main/java/project/flipnote/like/repository/LikeRepository.java index df312762..bc61ca5b 100644 --- a/src/main/java/project/flipnote/like/repository/LikeRepository.java +++ b/src/main/java/project/flipnote/like/repository/LikeRepository.java @@ -15,4 +15,6 @@ public interface LikeRepository extends JpaRepository { Optional findByTargetTypeAndTargetIdAndUserId(LikeTargetType targetType, Long targetId, Long userId); Page findByTargetTypeAndUserId(LikeTargetType targetType, Long userId, Pageable pageable); + + int deleteByTargetTypeAndTargetId(LikeTargetType targetType, Long targetId); } diff --git a/src/main/java/project/flipnote/like/service/LikeWriter.java b/src/main/java/project/flipnote/like/service/LikeWriter.java new file mode 100644 index 00000000..d50b27a6 --- /dev/null +++ b/src/main/java/project/flipnote/like/service/LikeWriter.java @@ -0,0 +1,24 @@ +package project.flipnote.like.service; + +import org.springframework.stereotype.Service; + +import lombok.RequiredArgsConstructor; +import project.flipnote.like.entity.LikeTargetType; +import project.flipnote.like.repository.LikeRepository; + +@RequiredArgsConstructor +@Service +public class LikeWriter { + private final LikeRepository likeRepository; + + /** + * 좋아요를 삭제합니다. + * + * @param targetType 좋아요 삭제 대상의 타입 + * @param targetId 좋아요 삭제 대상의 ID + * @author 윤정환 + */ + public void delete(LikeTargetType targetType, Long targetId) { + likeRepository.deleteByTargetTypeAndTargetId(targetType, targetId); + } +} From 55b675a7664abdbc555e62cdbe1d989bec1fb136 Mon Sep 17 00:00:00 2001 From: dungbik Date: Thu, 4 Dec 2025 17:42:53 +0900 Subject: [PATCH 2/4] =?UTF-8?q?Feat:=20=EC=B9=B4=EB=93=9C=EC=85=8B=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/project/flipnote/bookmark/service/BookmarkWriter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/project/flipnote/bookmark/service/BookmarkWriter.java b/src/main/java/project/flipnote/bookmark/service/BookmarkWriter.java index 37419435..c0bcd978 100644 --- a/src/main/java/project/flipnote/bookmark/service/BookmarkWriter.java +++ b/src/main/java/project/flipnote/bookmark/service/BookmarkWriter.java @@ -19,6 +19,6 @@ public class BookmarkWriter { * @author 윤정환 */ public void delete(BookmarkTargetType targetType, Long targetId) { - return bookmarkRepository.deleteByTar(targetType, targetId); + bookmarkRepository.deleteByTargetTypeAndTargetId(targetType, targetId); } } From 64873ae02ac2f228a87ee427885b83cf3c03c412 Mon Sep 17 00:00:00 2001 From: dungbik Date: Thu, 4 Dec 2025 17:50:52 +0900 Subject: [PATCH 3/4] =?UTF-8?q?Fix:=20=EC=8B=A4=EC=88=98=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 --- .../project/flipnote/cardset/entity/CardSetIncremental.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/project/flipnote/cardset/entity/CardSetIncremental.java b/src/main/java/project/flipnote/cardset/entity/CardSetIncremental.java index 957a5a12..0a7586d4 100644 --- a/src/main/java/project/flipnote/cardset/entity/CardSetIncremental.java +++ b/src/main/java/project/flipnote/cardset/entity/CardSetIncremental.java @@ -1,7 +1,5 @@ package project.flipnote.cardset.entity; -import org.hibernate.annotations.ColumnDefault; - import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.GeneratedValue; @@ -17,7 +15,7 @@ @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) -@Table(name = "cardset_contents") +@Table(name = "cardset_incrementals") @Entity public class CardSetIncremental extends BaseEntity { From 7b6fbbc8ff9f03dc0bb0e83fb9752ba98648fd24 Mon Sep 17 00:00:00 2001 From: dungbik Date: Thu, 4 Dec 2025 17:52:55 +0900 Subject: [PATCH 4/4] =?UTF-8?q?Feat:=20=EC=B9=B4=EB=93=9C=EC=85=8B=20?= =?UTF-8?q?=EC=82=AD=EC=A0=9C=EC=8B=9C=20=EC=9D=B4=EB=AF=B8=EC=A7=80?= =?UTF-8?q?=EB=8F=84=20=EC=82=AD=EC=A0=9C=EB=90=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 --- .../java/project/flipnote/cardset/service/CardSetService.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/project/flipnote/cardset/service/CardSetService.java b/src/main/java/project/flipnote/cardset/service/CardSetService.java index 256a1e74..6df1e271 100644 --- a/src/main/java/project/flipnote/cardset/service/CardSetService.java +++ b/src/main/java/project/flipnote/cardset/service/CardSetService.java @@ -386,6 +386,10 @@ public IdResponse deleteCardSet(Long userId, Long groupId, Long cardSetId) { // 카드셋 메타데이터 cardSetMetadataRepository.deleteById(cardSetId); + // 이미지 + imageRefService.findByTypeAndReferenceId(REFERENCE_TYPE, cardSetId) + .ifPresent(imageRef -> imageRefService.deleteByReferenceAndId(REFERENCE_TYPE, imageRef.getId())); + // 카드셋 cardSetRepository.delete(cardSet);