From ae1f21d8e35d29879f799d735d9b879404c3c1d6 Mon Sep 17 00:00:00 2001 From: dungbik Date: Fri, 23 Jan 2026 18:39:44 +0900 Subject: [PATCH 1/2] =?UTF-8?q?Feat:=20=EC=B9=B4=EB=93=9C=EC=85=8B=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EB=B0=8F=20=EC=88=98=EC=A0=95=EC=8B=9C=20?= =?UTF-8?q?=EB=A7=A4=EB=8B=88=EC=A0=80=20=EC=84=A4=EC=A0=95=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../docs/GroupCardSetControllerDocs.java | 10 +++ .../flipnote/cardset/entity/CardSet.java | 15 +++- .../cardset/model/CardSetUpdateRequest.java | 6 +- .../cardset/model/CreateCardSetRequest.java | 6 +- .../repository/CardSetManagerRepository.java | 8 ++ .../cardset/service/CardSetManagerWriter.java | 83 +++++++++++++++++++ .../cardset/service/CardSetService.java | 13 ++- 7 files changed, 127 insertions(+), 14 deletions(-) create mode 100644 src/main/java/project/flipnote/cardset/service/CardSetManagerWriter.java diff --git a/src/main/java/project/flipnote/cardset/controller/docs/GroupCardSetControllerDocs.java b/src/main/java/project/flipnote/cardset/controller/docs/GroupCardSetControllerDocs.java index 0b450cc4..5919b406 100644 --- a/src/main/java/project/flipnote/cardset/controller/docs/GroupCardSetControllerDocs.java +++ b/src/main/java/project/flipnote/cardset/controller/docs/GroupCardSetControllerDocs.java @@ -6,9 +6,13 @@ import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; import project.flipnote.cardset.model.CardSetDetailResponse; +import project.flipnote.cardset.model.CardSetSearchRequest; +import project.flipnote.cardset.model.CardSetSummaryResponse; import project.flipnote.cardset.model.CardSetUpdateRequest; import project.flipnote.cardset.model.CreateCardSetRequest; import project.flipnote.cardset.model.CreateCardSetResponse; +import project.flipnote.common.model.response.IdResponse; +import project.flipnote.common.model.response.PagingResponse; import project.flipnote.common.security.dto.AuthPrinciple; @Tag(name = "CardSet", description = "CardSet API") @@ -29,4 +33,10 @@ ResponseEntity updateCardSet( CardSetUpdateRequest req, AuthPrinciple authPrinciple ); + + @Operation(summary = "그룹별 카드셋 조회", security = {@SecurityRequirement(name = "access-token")}) + ResponseEntity> getCardSets(Long groupId, CardSetSearchRequest req); + + @Operation(summary = "카드셋 삭제", security = {@SecurityRequirement(name = "access-token")}) + ResponseEntity deleteCardSet(Long groupId, Long cardSetId, AuthPrinciple authPrinciple); } diff --git a/src/main/java/project/flipnote/cardset/entity/CardSet.java b/src/main/java/project/flipnote/cardset/entity/CardSet.java index d147b9b0..eaa7c605 100644 --- a/src/main/java/project/flipnote/cardset/entity/CardSet.java +++ b/src/main/java/project/flipnote/cardset/entity/CardSet.java @@ -32,6 +32,9 @@ public class CardSet extends BaseEntity { @Column(nullable = false, length = 50) private String name; + @Column(nullable = false) + private Long author; + @ManyToOne @JoinColumn(name = "group_id", nullable = false) private Group group; @@ -48,9 +51,17 @@ public class CardSet extends BaseEntity { private String imageUrl; @Builder - private CardSet(String name, Group group, Boolean publicVisible, Category category, String hashtag, - String imageUrl) { + private CardSet( + String name, + Long author, + Group group, + Boolean publicVisible, + Category category, + String hashtag, + String imageUrl + ) { this.name = name; + this.author = author; this.group = group; this.publicVisible = publicVisible; this.category = category; diff --git a/src/main/java/project/flipnote/cardset/model/CardSetUpdateRequest.java b/src/main/java/project/flipnote/cardset/model/CardSetUpdateRequest.java index c2b3d36b..cedb901a 100644 --- a/src/main/java/project/flipnote/cardset/model/CardSetUpdateRequest.java +++ b/src/main/java/project/flipnote/cardset/model/CardSetUpdateRequest.java @@ -1,8 +1,7 @@ package project.flipnote.cardset.model; import java.util.List; - -import org.hibernate.validator.constraints.URL; +import java.util.Set; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; @@ -25,6 +24,9 @@ public record CardSetUpdateRequest( @NotNull List hashtag, + @Size(min = 1) + Set managers, + Long imageRefId ) { diff --git a/src/main/java/project/flipnote/cardset/model/CreateCardSetRequest.java b/src/main/java/project/flipnote/cardset/model/CreateCardSetRequest.java index 6eab3bcf..899a20d7 100644 --- a/src/main/java/project/flipnote/cardset/model/CreateCardSetRequest.java +++ b/src/main/java/project/flipnote/cardset/model/CreateCardSetRequest.java @@ -1,8 +1,7 @@ package project.flipnote.cardset.model; import java.util.List; - -import org.hibernate.validator.constraints.URL; +import java.util.Set; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; @@ -24,6 +23,9 @@ public record CreateCardSetRequest( @NotNull List hashtag, + @Size(min = 1) + Set managers, + Long imageRefId ) { } diff --git a/src/main/java/project/flipnote/cardset/repository/CardSetManagerRepository.java b/src/main/java/project/flipnote/cardset/repository/CardSetManagerRepository.java index ea16c5b5..2b537eb8 100644 --- a/src/main/java/project/flipnote/cardset/repository/CardSetManagerRepository.java +++ b/src/main/java/project/flipnote/cardset/repository/CardSetManagerRepository.java @@ -1,6 +1,9 @@ package project.flipnote.cardset.repository; +import java.util.Set; + import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; import project.flipnote.cardset.entity.CardSetManager; @@ -11,4 +14,9 @@ public interface CardSetManagerRepository extends JpaRepository findUserIdsByCardSetId(Long cardSetId); + + int deleteByCardSet_IdAndUser_IdIn(Long cardSetId, Set userIds); } diff --git a/src/main/java/project/flipnote/cardset/service/CardSetManagerWriter.java b/src/main/java/project/flipnote/cardset/service/CardSetManagerWriter.java new file mode 100644 index 00000000..fac2440f --- /dev/null +++ b/src/main/java/project/flipnote/cardset/service/CardSetManagerWriter.java @@ -0,0 +1,83 @@ +package project.flipnote.cardset.service; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.springframework.stereotype.Service; + +import lombok.RequiredArgsConstructor; +import project.flipnote.cardset.entity.CardSet; +import project.flipnote.cardset.entity.CardSetManager; +import project.flipnote.cardset.repository.CardSetManagerRepository; +import project.flipnote.user.repository.UserProfileRepository; + +@RequiredArgsConstructor +@Service +public class CardSetManagerWriter { + + private final CardSetManagerRepository cardSetManagerRepository; + private final UserProfileRepository userProfileRepository; + + /** + * 카드셋에 매니저들을 할당 + * 생성자는 항상 매니저로 포함됨 + * + * @param cardSet 매니저를 할당할 카드셋 + * @param managerIds 요청된 매니저 ID 목록 + * @author 윤정환 + */ + public void assignManagers(CardSet cardSet, Set managerIds) { + Set finalManagerIds = includeAuthor(cardSet.getAuthor(), managerIds); + + List managers = finalManagerIds.stream() + .map(id -> CardSetManager.builder() + .cardSet(cardSet) + .user(userProfileRepository.getReferenceById(id)) + .build()) + .toList(); + + cardSetManagerRepository.saveAll(managers); + } + + /** + * 카드셋의 매니저를 수정 + * 차집합을 이용해 삭제/추가할 매니저만 처리 + * + * @param cardSet 매니저를 수정할 카드셋 + * @param newManagerIds 새로운 매니저 ID 목록 + * @author 윤정환 + */ + public void updateManagers(CardSet cardSet, Set newManagerIds) { + Set currentManagerIds = cardSetManagerRepository.findUserIdsByCardSetId(cardSet.getId()); + + Set toDelete = difference(currentManagerIds, newManagerIds); + Set toAdd = difference(newManagerIds, currentManagerIds); + + if (!toDelete.isEmpty()) { + cardSetManagerRepository.deleteByCardSet_IdAndUser_IdIn(cardSet.getId(), toDelete); + } + + if (!toAdd.isEmpty()) { + List managers = toAdd.stream() + .map(id -> CardSetManager.builder() + .cardSet(cardSet) + .user(userProfileRepository.getReferenceById(id)) + .build()) + .toList(); + cardSetManagerRepository.saveAll(managers); + } + } + + private Set includeAuthor(Long authorId, Set managerIds) { + Set result = new HashSet<>(managerIds); + result.add(authorId); + return result; + } + + private Set difference(Set a, Set b) { + Set result = new HashSet<>(a); + result.removeAll(b); + return result; + } +} diff --git a/src/main/java/project/flipnote/cardset/service/CardSetService.java b/src/main/java/project/flipnote/cardset/service/CardSetService.java index 6df1e271..9e2ef4b6 100644 --- a/src/main/java/project/flipnote/cardset/service/CardSetService.java +++ b/src/main/java/project/flipnote/cardset/service/CardSetService.java @@ -14,7 +14,6 @@ import project.flipnote.bookmark.service.BookmarkReader; import project.flipnote.bookmark.service.BookmarkWriter; import project.flipnote.cardset.entity.CardSet; -import project.flipnote.cardset.entity.CardSetManager; import project.flipnote.cardset.entity.CardSetMetadata; import project.flipnote.cardset.exception.CardSetErrorCode; import project.flipnote.cardset.model.CardSetDetailResponse; @@ -64,6 +63,7 @@ public class CardSetService { private final GroupRepository groupRepository; private final GroupMemberRepository groupMemberRepository; private final CardSetManagerRepository cardSetManagerRepository; + private final CardSetManagerWriter cardSetManagerWriter; private final CardSetPolicyService cardSetPolicyService; private final CardSetMetadataRepository cardSetMetadataRepository; private final ImageService imageService; @@ -121,6 +121,7 @@ public CreateCardSetResponse createCardSet(Long groupId, AuthPrinciple authPrinc CardSet cardSet = CardSet.builder() .name(req.name()) + .author(user.getId()) .group(group) .publicVisible(req.publicVisible()) .category(req.category()) @@ -140,13 +141,7 @@ public CreateCardSetResponse createCardSet(Long groupId, AuthPrinciple authPrinc .build(); cardSetMetadataRepository.save(metadata); - //카드셋 매니저도 저장 - CardSetManager cardSetManager = CardSetManager.builder() - .user(user) - .cardSet(cardSet) - .build(); - - cardSetManagerRepository.save(cardSetManager); + cardSetManagerWriter.assignManagers(cardSet, req.managers()); return CreateCardSetResponse.from(cardSet.getId()); } @@ -216,6 +211,8 @@ public CardSetDetailResponse updateCardSet(Long userId, Long groupId, Long cardS cardSetRepository.saveAndFlush(cardSet); + cardSetManagerWriter.updateManagers(cardSet, req.managers()); + boolean liked = likeReader.isLiked(userId, LikeTargetType.CARD_SET, cardSetId); boolean bookmarked = bookmarkReader.isBookmarked(userId, BookmarkTargetType.CARD_SET, cardSetId); From 768157850257cf9f78c7822f7d7db8c741c6cf58 Mon Sep 17 00:00:00 2001 From: dungbik Date: Fri, 23 Jan 2026 18:46:08 +0900 Subject: [PATCH 2/2] =?UTF-8?q?Feat:=20=EC=B9=B4=EB=93=9C=EC=85=8B=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EB=B0=8F=20=EC=88=98=EC=A0=95=EC=8B=9C=20?= =?UTF-8?q?=EB=A7=A4=EB=8B=88=EC=A0=80=20=EC=84=A4=EC=A0=95=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../project/flipnote/cardset/model/CardSetUpdateRequest.java | 3 ++- .../project/flipnote/cardset/model/CreateCardSetRequest.java | 3 ++- .../project/flipnote/cardset/service/CardSetManagerWriter.java | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/project/flipnote/cardset/model/CardSetUpdateRequest.java b/src/main/java/project/flipnote/cardset/model/CardSetUpdateRequest.java index cedb901a..f1fb833a 100644 --- a/src/main/java/project/flipnote/cardset/model/CardSetUpdateRequest.java +++ b/src/main/java/project/flipnote/cardset/model/CardSetUpdateRequest.java @@ -5,6 +5,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import project.flipnote.group.entity.Category; @@ -24,7 +25,7 @@ public record CardSetUpdateRequest( @NotNull List hashtag, - @Size(min = 1) + @NotEmpty @Size(min = 1) Set managers, Long imageRefId diff --git a/src/main/java/project/flipnote/cardset/model/CreateCardSetRequest.java b/src/main/java/project/flipnote/cardset/model/CreateCardSetRequest.java index 899a20d7..e7dec7c2 100644 --- a/src/main/java/project/flipnote/cardset/model/CreateCardSetRequest.java +++ b/src/main/java/project/flipnote/cardset/model/CreateCardSetRequest.java @@ -4,6 +4,7 @@ import java.util.Set; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import project.flipnote.group.entity.Category; @@ -23,7 +24,7 @@ public record CreateCardSetRequest( @NotNull List hashtag, - @Size(min = 1) + @NotEmpty @Size(min = 1) Set managers, Long imageRefId diff --git a/src/main/java/project/flipnote/cardset/service/CardSetManagerWriter.java b/src/main/java/project/flipnote/cardset/service/CardSetManagerWriter.java index fac2440f..9ed431ea 100644 --- a/src/main/java/project/flipnote/cardset/service/CardSetManagerWriter.java +++ b/src/main/java/project/flipnote/cardset/service/CardSetManagerWriter.java @@ -21,7 +21,7 @@ public class CardSetManagerWriter { /** * 카드셋에 매니저들을 할당 - * 생성자는 항상 매니저로 포함됨 + * 카드셋 생성시 생성자는 항상 매니저로 포함됨 * * @param cardSet 매니저를 할당할 카드셋 * @param managerIds 요청된 매니저 ID 목록