From 6b079ed304ce37aa5754713273fd50d5964ed722 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=92=E1=85=A7=E1=86=AB=E1=84=90=E1=85=A2=20=E1=84=8E?= =?UTF-8?q?=E1=85=AC?= Date: Mon, 13 Oct 2025 16:53:24 +0900 Subject: [PATCH 01/11] =?UTF-8?q?feat:=20=EC=95=A8=EB=B2=94=20=EC=B0=B8?= =?UTF-8?q?=EC=97=AC=20=EC=9D=B4=EB=A0=A5=20=EC=97=94=ED=8B=B0=ED=8B=B0=20?= =?UTF-8?q?=EB=B0=8F=20=ED=85=8C=EC=9D=B4=EB=B8=94=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity/AlbumParticipationHistory.java | 45 +++++++++++++++++++ .../album/enums/ParticipationAction.java | 7 +++ ...eate_album_participation_history_table.sql | 8 ++++ 3 files changed, 60 insertions(+) create mode 100644 cherrypic-domain/src/main/java/org/cherrypic/album/entity/AlbumParticipationHistory.java create mode 100644 cherrypic-domain/src/main/java/org/cherrypic/album/enums/ParticipationAction.java create mode 100644 cherrypic-domain/src/main/resources/db/migration/V5__create_album_participation_history_table.sql diff --git a/cherrypic-domain/src/main/java/org/cherrypic/album/entity/AlbumParticipationHistory.java b/cherrypic-domain/src/main/java/org/cherrypic/album/entity/AlbumParticipationHistory.java new file mode 100644 index 00000000..c572b8b6 --- /dev/null +++ b/cherrypic-domain/src/main/java/org/cherrypic/album/entity/AlbumParticipationHistory.java @@ -0,0 +1,45 @@ +package org.cherrypic.album.entity; + +import jakarta.persistence.*; +import jakarta.validation.constraints.NotNull; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.cherrypic.album.enums.ParticipationAction; +import org.cherrypic.common.model.BaseTimeEntity; + +@Getter +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class AlbumParticipationHistory extends BaseTimeEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NotNull private Long memberId; + + @NotNull private String albumTitleSnapshot; + + @NotNull + @Enumerated(EnumType.STRING) + ParticipationAction action; + + @Builder(access = AccessLevel.PRIVATE) + private AlbumParticipationHistory( + Long memberId, String albumTitleSnapshot, ParticipationAction action) { + this.memberId = memberId; + this.albumTitleSnapshot = albumTitleSnapshot; + this.action = action; + } + + public static AlbumParticipationHistory createAlbumParticipationHistory( + Long memberId, String albumTitleSnapshot, ParticipationAction action) { + return AlbumParticipationHistory.builder() + .memberId(memberId) + .albumTitleSnapshot(albumTitleSnapshot) + .action(action) + .build(); + } +} diff --git a/cherrypic-domain/src/main/java/org/cherrypic/album/enums/ParticipationAction.java b/cherrypic-domain/src/main/java/org/cherrypic/album/enums/ParticipationAction.java new file mode 100644 index 00000000..7d5c126d --- /dev/null +++ b/cherrypic-domain/src/main/java/org/cherrypic/album/enums/ParticipationAction.java @@ -0,0 +1,7 @@ +package org.cherrypic.album.enums; + +public enum ParticipationAction { + JOIN, + LEAVE, + KICK +} diff --git a/cherrypic-domain/src/main/resources/db/migration/V5__create_album_participation_history_table.sql b/cherrypic-domain/src/main/resources/db/migration/V5__create_album_participation_history_table.sql new file mode 100644 index 00000000..1a972018 --- /dev/null +++ b/cherrypic-domain/src/main/resources/db/migration/V5__create_album_participation_history_table.sql @@ -0,0 +1,8 @@ +CREATE TABLE album_participation_history ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + member_id BIGINT NOT NULL, + album_title_snapshot VARCHAR(20) NOT NULL, + action VARCHAR(20) NOT NULL CHECK (action IN ('JOIN','LEAVE','KICK')), + created_at DATETIME(6) NOT NULL, + updated_at DATETIME(6) NOT NULL +); From 8c78d285585618f51d79ab8e8de997c84125fbb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=92=E1=85=A7=E1=86=AB=E1=84=90=E1=85=A2=20=E1=84=8E?= =?UTF-8?q?=E1=85=AC?= Date: Mon, 13 Oct 2025 17:56:13 +0900 Subject: [PATCH 02/11] =?UTF-8?q?feat:=20=EC=95=A8=EB=B2=94=20=EC=B0=B8?= =?UTF-8?q?=EC=97=AC,=20=ED=87=B4=EC=9E=A5,=20=EA=B0=95=ED=87=B4=20?= =?UTF-8?q?=EC=8B=9C=20=EC=B0=B8=EC=97=AC=20=EC=9D=B4=EB=A0=A5=20=EA=B8=B0?= =?UTF-8?q?=EB=A1=9D=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 --- .../domain/album/service/AlbumServiceImpl.java | 8 ++++++++ .../participant/service/ParticipantServiceImpl.java | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/album/service/AlbumServiceImpl.java b/cherrypic-api/src/main/java/org/cherrypic/domain/album/service/AlbumServiceImpl.java index 5eda0f35..e24b9c91 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/album/service/AlbumServiceImpl.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/album/service/AlbumServiceImpl.java @@ -5,14 +5,17 @@ import java.util.Objects; import lombok.RequiredArgsConstructor; import org.cherrypic.album.entity.Album; +import org.cherrypic.album.entity.AlbumParticipationHistory; import org.cherrypic.album.entity.InvitationCode; import org.cherrypic.album.enums.AlbumType; import org.cherrypic.domain.album.dto.event.AlbumDeleteNotificationSendEvent; import org.cherrypic.domain.album.dto.event.AlbumImagesDeleteEvent; +import org.cherrypic.album.enums.ParticipationAction; import org.cherrypic.domain.album.dto.request.AlbumCreateRequest; import org.cherrypic.domain.album.dto.request.AlbumUpdateRequest; import org.cherrypic.domain.album.dto.response.*; import org.cherrypic.domain.album.exception.AlbumErrorCode; +import org.cherrypic.domain.album.repository.AlbumParticipationHistoryRepository; import org.cherrypic.domain.album.repository.AlbumRepository; import org.cherrypic.domain.album.repository.InvitationCodeRepository; import org.cherrypic.domain.event.repository.EventImageRepository; @@ -65,6 +68,7 @@ public class AlbumServiceImpl implements AlbumService { private final ImageRepository imageRepository; private final EventImageRepository eventImageRepository; private final NotificationRepository notificationRepository; + private final AlbumParticipationHistoryRepository albumParticipationHistoryRepository; private final ApplicationEventPublisher eventPublisher; @@ -190,6 +194,10 @@ public AlbumJoinResponse joinAlbum(Long albumId, String code) { favoritesRepository.save(Favorites.createFavorites(participant)); + albumParticipationHistoryRepository.save( + AlbumParticipationHistory.createAlbumParticipationHistory( + currentMember.getId(), album.getTitle(), ParticipationAction.JOIN)); + return AlbumJoinResponse.from(participant); } diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/participant/service/ParticipantServiceImpl.java b/cherrypic-api/src/main/java/org/cherrypic/domain/participant/service/ParticipantServiceImpl.java index c4a62470..a05691dc 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/participant/service/ParticipantServiceImpl.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/participant/service/ParticipantServiceImpl.java @@ -4,8 +4,11 @@ import java.util.List; import lombok.RequiredArgsConstructor; import org.cherrypic.album.entity.Album; +import org.cherrypic.album.entity.AlbumParticipationHistory; import org.cherrypic.album.enums.AlbumType; +import org.cherrypic.album.enums.ParticipationAction; import org.cherrypic.domain.album.exception.AlbumErrorCode; +import org.cherrypic.domain.album.repository.AlbumParticipationHistoryRepository; import org.cherrypic.domain.album.repository.AlbumRepository; import org.cherrypic.domain.favorites.repository.FavoritesRepository; import org.cherrypic.domain.notification.repository.NotificationRepository; @@ -40,6 +43,7 @@ public class ParticipantServiceImpl implements ParticipantService { private final SubscriptionRepository subscriptionRepository; private final FavoritesRepository favoritesRepository; private final NotificationRepository notificationRepository; + private final AlbumParticipationHistoryRepository albumParticipationHistoryRepository; @Override public void leaveAlbum(Long albumId) { @@ -57,6 +61,10 @@ public void leaveAlbum(Long albumId) { notificationRepository.deleteByReceiverIdAndAlbumId(currentMember.getId(), albumId); } catch (ObjectOptimisticLockingFailureException ignored) { } + + albumParticipationHistoryRepository.save( + AlbumParticipationHistory.createAlbumParticipationHistory( + currentMember.getId(), album.getTitle(), ParticipationAction.LEAVE)); } @Override @@ -78,6 +86,10 @@ public void kickParticipant(Long albumId, Long participantId) { target.getMember().getId(), album.getId()); } catch (ObjectOptimisticLockingFailureException ignored) { } + + albumParticipationHistoryRepository.save( + AlbumParticipationHistory.createAlbumParticipationHistory( + target.getMember().getId(), album.getTitle(), ParticipationAction.KICK)); } @Override From eaae6dc125839c0ade96297cf651be71ee43f92f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=92=E1=85=A7=E1=86=AB=E1=84=90=E1=85=A2=20=E1=84=8E?= =?UTF-8?q?=E1=85=AC?= Date: Mon, 13 Oct 2025 18:52:24 +0900 Subject: [PATCH 03/11] =?UTF-8?q?feat:=20=EC=95=A8=EB=B2=94=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EC=8B=9C=EC=97=90=EB=8F=84=20=EC=B0=B8=EC=97=AC=20?= =?UTF-8?q?=EC=9D=B4=EB=A0=A5=20=EA=B8=B0=EB=A1=9D=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=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 --- .../org/cherrypic/domain/album/service/AlbumServiceImpl.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/album/service/AlbumServiceImpl.java b/cherrypic-api/src/main/java/org/cherrypic/domain/album/service/AlbumServiceImpl.java index e24b9c91..48a19f2c 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/album/service/AlbumServiceImpl.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/album/service/AlbumServiceImpl.java @@ -109,6 +109,10 @@ public AlbumCreateResponse createAlbum(AlbumCreateRequest request) { Subscription.createSubscription(currentMember, album, payment.getPaidAt())); } + albumParticipationHistoryRepository.save( + AlbumParticipationHistory.createAlbumParticipationHistory( + currentMember.getId(), album.getTitle(), ParticipationAction.JOIN)); + return AlbumCreateResponse.from(album); } From 04367e6879734ba3c5007d766996e5d6638180da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=92=E1=85=A7=E1=86=AB=E1=84=90=E1=85=A2=20=E1=84=8E?= =?UTF-8?q?=E1=85=AC?= Date: Mon, 13 Oct 2025 22:34:12 +0900 Subject: [PATCH 04/11] =?UTF-8?q?feat:=20=EC=95=A8=EB=B2=94=20=EC=B0=B8?= =?UTF-8?q?=EC=97=AC=20=EC=9D=B4=EB=A0=A5=20=EC=A1=B0=ED=9A=8C=20API=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AlbumParticipationHistoryRepository.java | 8 +++ ...mParticipationHistoryRepositoryCustom.java | 10 +++ ...bumParticipationHistoryRepositoryImpl.java | 71 +++++++++++++++++++ .../member/controller/MemberController.java | 23 ++++++ .../ParticipationHistoryResponse.java | 17 +++++ .../ParticipationHistoryQueryService.java | 32 +++++++++ 6 files changed, 161 insertions(+) create mode 100644 cherrypic-api/src/main/java/org/cherrypic/domain/album/repository/AlbumParticipationHistoryRepository.java create mode 100644 cherrypic-api/src/main/java/org/cherrypic/domain/album/repository/AlbumParticipationHistoryRepositoryCustom.java create mode 100644 cherrypic-api/src/main/java/org/cherrypic/domain/album/repository/AlbumParticipationHistoryRepositoryImpl.java create mode 100644 cherrypic-api/src/main/java/org/cherrypic/domain/member/dto/response/ParticipationHistoryResponse.java create mode 100644 cherrypic-api/src/main/java/org/cherrypic/domain/member/service/ParticipationHistoryQueryService.java diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/album/repository/AlbumParticipationHistoryRepository.java b/cherrypic-api/src/main/java/org/cherrypic/domain/album/repository/AlbumParticipationHistoryRepository.java new file mode 100644 index 00000000..6c6a0ea8 --- /dev/null +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/album/repository/AlbumParticipationHistoryRepository.java @@ -0,0 +1,8 @@ +package org.cherrypic.domain.album.repository; + +import org.cherrypic.album.entity.AlbumParticipationHistory; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface AlbumParticipationHistoryRepository + extends JpaRepository, + AlbumParticipationHistoryRepositoryCustom {} diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/album/repository/AlbumParticipationHistoryRepositoryCustom.java b/cherrypic-api/src/main/java/org/cherrypic/domain/album/repository/AlbumParticipationHistoryRepositoryCustom.java new file mode 100644 index 00000000..5d025b1d --- /dev/null +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/album/repository/AlbumParticipationHistoryRepositoryCustom.java @@ -0,0 +1,10 @@ +package org.cherrypic.domain.album.repository; + +import org.cherrypic.domain.member.dto.response.ParticipationHistoryResponse; +import org.cherrypic.global.pagination.SortDirection; +import org.springframework.data.domain.Slice; + +public interface AlbumParticipationHistoryRepositoryCustom { + Slice findParticipationHistory( + Long memberId, Long lastHistoryId, int size, SortDirection direction); +} diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/album/repository/AlbumParticipationHistoryRepositoryImpl.java b/cherrypic-api/src/main/java/org/cherrypic/domain/album/repository/AlbumParticipationHistoryRepositoryImpl.java new file mode 100644 index 00000000..e9439b70 --- /dev/null +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/album/repository/AlbumParticipationHistoryRepositoryImpl.java @@ -0,0 +1,71 @@ +package org.cherrypic.domain.album.repository; + +import static org.cherrypic.album.entity.QAlbumParticipationHistory.albumParticipationHistory; + +import com.querydsl.core.types.Projections; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.jpa.impl.JPAQueryFactory; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.cherrypic.domain.member.dto.response.ParticipationHistoryResponse; +import org.cherrypic.global.pagination.SortDirection; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Slice; +import org.springframework.data.domain.SliceImpl; +import org.springframework.stereotype.Repository; + +@Repository +@RequiredArgsConstructor +public class AlbumParticipationHistoryRepositoryImpl + implements AlbumParticipationHistoryRepositoryCustom { + + private final JPAQueryFactory queryFactory; + + @Override + public Slice findParticipationHistory( + Long memberId, Long lastHistoryId, int size, SortDirection direction) { + List results = + queryFactory + .select( + Projections.constructor( + ParticipationHistoryResponse.class, + albumParticipationHistory.id, + albumParticipationHistory.albumTitleSnapshot, + albumParticipationHistory.action, + albumParticipationHistory.createdAt)) + .from(albumParticipationHistory) + .where( + albumParticipationHistory.memberId.eq(memberId), + lastHistoryIdCondition(lastHistoryId, direction)) + .orderBy( + direction == SortDirection.DESC + ? albumParticipationHistory.id.desc() + : albumParticipationHistory.id.asc()) + .limit(size + 1) + .fetch(); + + return checkLastPage(size, results); + } + + private BooleanExpression lastHistoryIdCondition(Long historyId, SortDirection direction) { + if (historyId == null) { + return null; + } + + return direction == SortDirection.DESC + ? albumParticipationHistory.id.lt(historyId) + : albumParticipationHistory.id.gt(historyId); + } + + private Slice checkLastPage( + int pageSize, List results) { + boolean hasNext = false; + + if (results.size() > pageSize) { + hasNext = true; + results.remove(pageSize); + } + + return new SliceImpl<>(results, PageRequest.of(0, pageSize), hasNext); + } +} diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/member/controller/MemberController.java b/cherrypic-api/src/main/java/org/cherrypic/domain/member/controller/MemberController.java index 37030307..f287c555 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/member/controller/MemberController.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/member/controller/MemberController.java @@ -1,6 +1,7 @@ package org.cherrypic.domain.member.controller; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; @@ -9,17 +10,25 @@ import org.cherrypic.domain.member.dto.response.LocalImageDeletionToggleResponse; import org.cherrypic.domain.member.dto.response.MemberInfoResponse; import org.cherrypic.domain.member.dto.response.MemberProfileUpdateResponse; +import org.cherrypic.domain.member.dto.response.ParticipationHistoryResponse; import org.cherrypic.domain.member.service.MemberService; +import org.cherrypic.domain.member.service.ParticipationHistoryQueryService; +import org.cherrypic.global.annotation.PageSize; +import org.cherrypic.global.pagination.SliceResponse; +import org.cherrypic.global.pagination.SortDirection; import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/members") @RequiredArgsConstructor @Tag(name = "1-2. 회원 API", description = "회원 관련 API입니다.") +@Validated public class MemberController { private final MemberService memberService; + private final ParticipationHistoryQueryService participationHistoryQueryService; @GetMapping("/me") @Operation(summary = "회원 정보 조회", description = "로그인한 회원 정보를 조회합니다.") @@ -40,6 +49,20 @@ public LocalImageDeletionToggleResponse localImageDeletionToggle() { return memberService.toggleLocalImageDeletion(); } + @GetMapping("/me/participation-history") + @Operation(summary = "회원의 앨범 참여 이력 조회", description = "사용자가 입장/퇴장/강퇴된 앨범 이력을 조회합니다.") + public SliceResponse participationHistoryGet( + @Parameter(description = "이전 페이지의 마지막 앨범 참여 이력 ID (첫 요청 시 생략)") + @RequestParam(required = false) + Long lastHistoryId, + @Parameter(description = "페이지당 조회할 참여 이력 수") @RequestParam @PageSize Integer size, + @Parameter(description = "정렬 방향 (ASC: 오래된순, DESC: 최신순)") + @RequestParam(defaultValue = "DESC") + SortDirection direction) { + return participationHistoryQueryService.getParticipationHistory( + lastHistoryId, size, direction); + } + @PostMapping("/fcm-tokens") @Operation( summary = "FCM 토큰 저장", diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/member/dto/response/ParticipationHistoryResponse.java b/cherrypic-api/src/main/java/org/cherrypic/domain/member/dto/response/ParticipationHistoryResponse.java new file mode 100644 index 00000000..d9d2c70f --- /dev/null +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/member/dto/response/ParticipationHistoryResponse.java @@ -0,0 +1,17 @@ +package org.cherrypic.domain.member.dto.response; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import java.time.LocalDateTime; +import org.cherrypic.album.enums.ParticipationAction; + +public record ParticipationHistoryResponse( + @Schema(description = "앨범 참여 이력 ID", example = "1") Long historyId, + @Schema(description = "앨범 이름 스냅샷 (액션 발생 직전 이름 기준)", example = "가족여행") String albumTitle, + @Schema(description = "액션 타입", example = "JOIN") ParticipationAction action, + @JsonFormat( + shape = JsonFormat.Shape.STRING, + pattern = "yyyy-MM-dd", + timezone = "Asia/Seoul") + @Schema(description = "액션 발생일", example = "2025-08-01") + LocalDateTime eventTime) {} diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/member/service/ParticipationHistoryQueryService.java b/cherrypic-api/src/main/java/org/cherrypic/domain/member/service/ParticipationHistoryQueryService.java new file mode 100644 index 00000000..988a493a --- /dev/null +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/member/service/ParticipationHistoryQueryService.java @@ -0,0 +1,32 @@ +package org.cherrypic.domain.member.service; + +import lombok.RequiredArgsConstructor; +import org.cherrypic.domain.album.repository.AlbumParticipationHistoryRepository; +import org.cherrypic.domain.member.dto.response.ParticipationHistoryResponse; +import org.cherrypic.global.pagination.SliceResponse; +import org.cherrypic.global.pagination.SortDirection; +import org.cherrypic.global.util.MemberUtil; +import org.cherrypic.member.entity.Member; +import org.springframework.data.domain.Slice; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class ParticipationHistoryQueryService { + + private final MemberUtil memberUtil; + private final AlbumParticipationHistoryRepository albumParticipationHistoryRepository; + + public SliceResponse getParticipationHistory( + Long lastHistoryId, int size, SortDirection direction) { + final Member currentMember = memberUtil.getCurrentMember(); + + Slice results = + albumParticipationHistoryRepository.findParticipationHistory( + currentMember.getId(), lastHistoryId, size, direction); + + return SliceResponse.from(results); + } +} From de2cf913497c780ba9e2c104c7c768cec93f10dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=92=E1=85=A7=E1=86=AB=E1=84=90=E1=85=A2=20=E1=84=8E?= =?UTF-8?q?=E1=85=AC?= Date: Mon, 13 Oct 2025 23:26:34 +0900 Subject: [PATCH 05/11] =?UTF-8?q?test:=20=EC=95=A8=EB=B2=94=20=EC=B0=B8?= =?UTF-8?q?=EC=97=AC=20=EC=9D=B4=EB=A0=A5=20=EC=A1=B0=ED=9A=8C=20=ED=86=B5?= =?UTF-8?q?=ED=95=A9=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ParticipationHistoryQueryServiceTest.java | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 cherrypic-api/src/test/java/org/cherrypic/member/service/ParticipationHistoryQueryServiceTest.java diff --git a/cherrypic-api/src/test/java/org/cherrypic/member/service/ParticipationHistoryQueryServiceTest.java b/cherrypic-api/src/test/java/org/cherrypic/member/service/ParticipationHistoryQueryServiceTest.java new file mode 100644 index 00000000..6404e864 --- /dev/null +++ b/cherrypic-api/src/test/java/org/cherrypic/member/service/ParticipationHistoryQueryServiceTest.java @@ -0,0 +1,114 @@ +package org.cherrypic.member.service; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.BDDMockito.given; + +import java.util.List; +import org.cherrypic.IntegrationTest; +import org.cherrypic.album.entity.AlbumParticipationHistory; +import org.cherrypic.album.enums.ParticipationAction; +import org.cherrypic.domain.album.repository.AlbumParticipationHistoryRepository; +import org.cherrypic.domain.member.dto.response.ParticipationHistoryResponse; +import org.cherrypic.domain.member.repository.MemberRepository; +import org.cherrypic.domain.member.service.ParticipationHistoryQueryService; +import org.cherrypic.global.pagination.SliceResponse; +import org.cherrypic.global.pagination.SortDirection; +import org.cherrypic.global.util.MemberUtil; +import org.cherrypic.member.entity.Member; +import org.cherrypic.member.entity.OauthInfo; +import org.junit.jupiter.api.*; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.bean.override.mockito.MockitoBean; + +class ParticipationHistoryQueryServiceTest extends IntegrationTest { + + @Autowired private ParticipationHistoryQueryService participationHistoryQueryService; + @Autowired private MemberRepository memberRepository; + @Autowired private AlbumParticipationHistoryRepository albumParticipationHistoryRepository; + + @MockitoBean private MemberUtil memberUtil; + + @Nested + class 앨범의_참여_이력을_조회할_때 { + + @BeforeEach + void setUp() { + Member member = + Member.createMember( + OauthInfo.createOauthInfo("testOauthId", "testOauthProvider"), + "testNickname", + "testProfileImageUrl"); + memberRepository.save(member); + given(memberUtil.getCurrentMember()).willReturn(member); + + AlbumParticipationHistory participationHistory1 = + AlbumParticipationHistory.createAlbumParticipationHistory( + member.getId(), "testTitle1", ParticipationAction.JOIN); + AlbumParticipationHistory participationHistory2 = + AlbumParticipationHistory.createAlbumParticipationHistory( + member.getId(), "testTitle2", ParticipationAction.LEAVE); + AlbumParticipationHistory participationHistory3 = + AlbumParticipationHistory.createAlbumParticipationHistory( + member.getId(), "testTitle3", ParticipationAction.KICK); + + albumParticipationHistoryRepository.saveAll( + List.of(participationHistory1, participationHistory2, participationHistory3)); + } + + @Test + void 정렬_조건이_ASC이면_historyId를_오름차순으로_조회한다() { + // when + SliceResponse response = + participationHistoryQueryService.getParticipationHistory( + null, 3, SortDirection.ASC); + + // then + Assertions.assertAll( + () -> + assertThat(response.content()) + .extracting("historyId") + .containsExactly(1L, 2L, 3L), + () -> assertThat(response.isLast()).isTrue()); + } + + @Test + void 정렬_조건이_DESC이면_historyId를_내림차순으로_조회한다() { + // when + SliceResponse response = + participationHistoryQueryService.getParticipationHistory( + null, 3, SortDirection.DESC); + + // then + Assertions.assertAll( + () -> + assertThat(response.content()) + .extracting("historyId") + .containsExactly(3L, 2L, 1L), + () -> assertThat(response.isLast()).isTrue()); + } + + @Test + void 마지막_페이지인_경우_isLast를_true로_반환한다() { + SliceResponse response = + participationHistoryQueryService.getParticipationHistory( + null, 3, SortDirection.DESC); + + // then + Assertions.assertAll( + () -> assertThat(response.content().size()).isEqualTo(3), + () -> assertThat(response.isLast()).isTrue()); + } + + @Test + void 마지막_페이지가_아닌_경우_isLast를_false로_반환한다() { + SliceResponse response = + participationHistoryQueryService.getParticipationHistory( + null, 1, SortDirection.DESC); + + // then + Assertions.assertAll( + () -> assertThat(response.content().size()).isEqualTo(1), + () -> assertThat(response.isLast()).isFalse()); + } + } +} From fe59c84a168b07983506566cbac489b81f542352 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=92=E1=85=A7=E1=86=AB=E1=84=90=E1=85=A2=20=E1=84=8E?= =?UTF-8?q?=E1=85=AC?= Date: Mon, 13 Oct 2025 23:46:11 +0900 Subject: [PATCH 06/11] =?UTF-8?q?test:=20=EC=95=A8=EB=B2=94=20=EC=B0=B8?= =?UTF-8?q?=EC=97=AC=20=EC=9D=B4=EB=A0=A5=20=EC=A1=B0=ED=9A=8C=20=EB=8B=A8?= =?UTF-8?q?=EC=9C=84=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/MemberControllerTest.java | 230 ++++++++++++++++-- 1 file changed, 207 insertions(+), 23 deletions(-) diff --git a/cherrypic-api/src/test/java/org/cherrypic/member/controller/MemberControllerTest.java b/cherrypic-api/src/test/java/org/cherrypic/member/controller/MemberControllerTest.java index dda65a23..fc652179 100644 --- a/cherrypic-api/src/test/java/org/cherrypic/member/controller/MemberControllerTest.java +++ b/cherrypic-api/src/test/java/org/cherrypic/member/controller/MemberControllerTest.java @@ -6,13 +6,20 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import com.fasterxml.jackson.databind.ObjectMapper; +import java.time.LocalDateTime; +import java.util.List; +import org.cherrypic.album.enums.ParticipationAction; import org.cherrypic.domain.member.controller.MemberController; import org.cherrypic.domain.member.dto.request.FcmTokenSaveRequest; import org.cherrypic.domain.member.dto.request.MemberProfileUpdateRequest; import org.cherrypic.domain.member.dto.response.LocalImageDeletionToggleResponse; import org.cherrypic.domain.member.dto.response.MemberInfoResponse; import org.cherrypic.domain.member.dto.response.MemberProfileUpdateResponse; +import org.cherrypic.domain.member.dto.response.ParticipationHistoryResponse; import org.cherrypic.domain.member.service.MemberService; +import org.cherrypic.domain.member.service.ParticipationHistoryQueryService; +import org.cherrypic.global.pagination.SliceResponse; +import org.cherrypic.global.pagination.SortDirection; import org.cherrypic.member.enums.MemberRole; import org.cherrypic.member.enums.MemberStatus; import org.junit.jupiter.api.Nested; @@ -38,6 +45,7 @@ class MemberControllerTest { @Autowired private ObjectMapper objectMapper; @MockitoBean private MemberService memberService; + @MockitoBean private ParticipationHistoryQueryService participationHistoryQueryService; @Nested class 회원_정보_조회_요청_시 { @@ -161,6 +169,205 @@ class 회원_프로필_수정_요청_시 { } } + @Nested + class 로컬_이미지_삭제_허용_여부_변경_요청_시 { + + @Test + void 유효한_요청이면_로컬_이미지_삭제_허용_여부를_변경한다() throws Exception { + // given + LocalImageDeletionToggleResponse response = new LocalImageDeletionToggleResponse(true); + + given(memberService.toggleLocalImageDeletion()).willReturn(response); + + // when & then + ResultActions perform = + mockMvc.perform( + patch("/members/me/local-image-deletion") + .contentType(MediaType.APPLICATION_JSON)); + + perform.andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(true)) + .andExpect(jsonPath("$.status").value(200)) + .andExpect(jsonPath("$.data.localImageDeletion").value(true)); + } + } + + @Nested + class 앨범의_참여_이력_조회_요청_시 { + + @Test + void 정렬_조건이_ASC이면_historyId를_오름차순으로_응답한다() throws Exception { + // given + List responses = + List.of( + new ParticipationHistoryResponse( + 1L, + "testTitle1", + ParticipationAction.JOIN, + LocalDateTime.of(2025, 8, 1, 0, 0)), + new ParticipationHistoryResponse( + 2L, + "testTitle2", + ParticipationAction.LEAVE, + LocalDateTime.of(2025, 8, 2, 0, 0)), + new ParticipationHistoryResponse( + 3L, + "testTitle3", + ParticipationAction.KICK, + LocalDateTime.of(2025, 8, 3, 0, 0))); + + given( + participationHistoryQueryService.getParticipationHistory( + null, 3, SortDirection.ASC)) + .willReturn(new SliceResponse<>(responses, true)); + + // when & then + ResultActions perform = + mockMvc.perform( + get("/members/me/participation-history") + .param("size", "3") + .param("direction", "ASC")); + + perform.andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(true)) + .andExpect(jsonPath("$.status").value(HttpStatus.OK.value())) + .andExpect(jsonPath("$.data.content[0].historyId").value(1)) + .andExpect(jsonPath("$.data.content[1].historyId").value(2)) + .andExpect(jsonPath("$.data.content[2].historyId").value(3)) + .andExpect(jsonPath("$.data.isLast").value(true)); + } + + @Test + void 정렬_조건이_DESC이면_historyId를_내림차순으로_응답한다() throws Exception { + // given + List responses = + List.of( + new ParticipationHistoryResponse( + 3L, + "testTitle3", + ParticipationAction.KICK, + LocalDateTime.of(2025, 8, 3, 0, 0)), + new ParticipationHistoryResponse( + 2L, + "testTitle2", + ParticipationAction.LEAVE, + LocalDateTime.of(2025, 8, 2, 0, 0)), + new ParticipationHistoryResponse( + 1L, + "testTitle1", + ParticipationAction.JOIN, + LocalDateTime.of(2025, 8, 1, 0, 0))); + + given( + participationHistoryQueryService.getParticipationHistory( + null, 3, SortDirection.DESC)) + .willReturn(new SliceResponse<>(responses, true)); + + // when & then + ResultActions perform = + mockMvc.perform(get("/members/me/participation-history").param("size", "3")); + + perform.andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(true)) + .andExpect(jsonPath("$.status").value(HttpStatus.OK.value())) + .andExpect(jsonPath("$.data.content[0].historyId").value(3)) + .andExpect(jsonPath("$.data.content[1].historyId").value(2)) + .andExpect(jsonPath("$.data.content[2].historyId").value(1)) + .andExpect(jsonPath("$.data.isLast").value(true)); + } + + @Test + void 마지막_페이지인_경우_isLast를_true로_응답한다() throws Exception { + // given + List responses = + List.of( + new ParticipationHistoryResponse( + 1L, + "testTitle1", + ParticipationAction.JOIN, + LocalDateTime.of(2025, 8, 1, 0, 0))); + + given( + participationHistoryQueryService.getParticipationHistory( + null, 1, SortDirection.DESC)) + .willReturn(new SliceResponse<>(responses, true)); + + // when & then + ResultActions perform = + mockMvc.perform(get("/members/me/participation-history").param("size", "1")); + + perform.andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(true)) + .andExpect(jsonPath("$.status").value(HttpStatus.OK.value())) + .andExpect(jsonPath("$.data.content[0].historyId").value(1)) + .andExpect(jsonPath("$.data.isLast").value(true)); + } + + @Test + void 마지막_페이지가_아닌_경우_isLast를_false로_응답한다() throws Exception { + // given + List responses = + List.of( + new ParticipationHistoryResponse( + 2L, + "testTitle2", + ParticipationAction.LEAVE, + LocalDateTime.of(2025, 8, 2, 0, 0)), + new ParticipationHistoryResponse( + 1L, + "testTitle1", + ParticipationAction.JOIN, + LocalDateTime.of(2025, 8, 1, 0, 0))); + + given( + participationHistoryQueryService.getParticipationHistory( + null, 1, SortDirection.DESC)) + .willReturn(new SliceResponse<>(responses, false)); + + // when & then + ResultActions perform = + mockMvc.perform(get("/members/me/participation-history").param("size", "1")); + + perform.andExpect(status().isOk()) + .andExpect(jsonPath("$.success").value(true)) + .andExpect(jsonPath("$.status").value(HttpStatus.OK.value())) + .andExpect(jsonPath("$.data.content[0].historyId").value(2)) + .andExpect(jsonPath("$.data.isLast").value(false)); + } + + @ParameterizedTest + @ValueSource(strings = {"-1", "-999", "0"}) + void 페이지_크기를_0_이하로_설정하면_예외가_발생한다(String pageSize) throws Exception { + // when & then + ResultActions perform = + mockMvc.perform( + get("/members/me/participation-history").param("size", pageSize)); + + perform.andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.success").value(false)) + .andExpect(jsonPath("$.status").value(HttpStatus.BAD_REQUEST.value())) + .andExpect(jsonPath("$.data.code").value("ConstraintViolationException")) + .andExpect(jsonPath("$.data.message").value("페이지 크기는 0보다 큰 값만 가능합니다.")); + } + + @ParameterizedTest + @ValueSource(strings = {"ASCC", "DESCC", "OLDEST", "NEWEST"}) + void 존재하지_않는_정렬_기준을_입력한_경우_예외가_발생한다(String sort) throws Exception { + // when & then + ResultActions perform = + mockMvc.perform( + get("/members/me/participation-history") + .param("size", "2") + .param("direction", sort)); + + perform.andExpect(status().isBadRequest()) + .andExpect(jsonPath("$.success").value(false)) + .andExpect(jsonPath("$.status").value(HttpStatus.BAD_REQUEST.value())) + .andExpect(jsonPath("$.data.code").value("METHOD_ARGUMENT_TYPE_MISMATCH")) + .andExpect(jsonPath("$.data.message").value("요청한 값의 타입이 잘못되어 처리할 수 없습니다.")); + } + } + @Nested class FCM_토큰_저장_요청_시 { @@ -205,27 +412,4 @@ class FCM_토큰_저장_요청_시 { .andExpect(jsonPath("$.data.message").value("FCM Token은 비워둘 수 없습니다.")); } } - - @Nested - class 로컬_이미지_삭제_허용_여부_변경_요청_시 { - - @Test - void 유효한_요청이면_로컬_이미지_삭제_허용_여부를_변경한다() throws Exception { - // given - LocalImageDeletionToggleResponse response = new LocalImageDeletionToggleResponse(true); - - given(memberService.toggleLocalImageDeletion()).willReturn(response); - - // when & then - ResultActions perform = - mockMvc.perform( - patch("/members/me/local-image-deletion") - .contentType(MediaType.APPLICATION_JSON)); - - perform.andExpect(status().isOk()) - .andExpect(jsonPath("$.success").value(true)) - .andExpect(jsonPath("$.status").value(200)) - .andExpect(jsonPath("$.data.localImageDeletion").value(true)); - } - } } From d1286f7b3884fbe5e16410676ff69664d30bed97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=92=E1=85=A7=E1=86=AB=E1=84=90=E1=85=A2=20=E1=84=8E?= =?UTF-8?q?=E1=85=AC?= Date: Tue, 14 Oct 2025 23:13:50 +0900 Subject: [PATCH 07/11] =?UTF-8?q?feat:=20=EC=95=A8=EB=B2=94=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EC=8B=9C=20DELETED=20=EC=B0=B8=EC=97=AC=20?= =?UTF-8?q?=EC=9D=B4=EB=A0=A5=20=EA=B8=B0=EB=A1=9D=20=EB=A1=9C=EC=A7=81=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 --- .../org/cherrypic/domain/album/service/AlbumServiceImpl.java | 4 ++++ .../java/org/cherrypic/album/enums/ParticipationAction.java | 3 ++- .../V5__create_album_participation_history_table.sql | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/album/service/AlbumServiceImpl.java b/cherrypic-api/src/main/java/org/cherrypic/domain/album/service/AlbumServiceImpl.java index 48a19f2c..3d61e3d0 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/album/service/AlbumServiceImpl.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/album/service/AlbumServiceImpl.java @@ -284,6 +284,10 @@ public void deleteAlbum(Long albumId) { paymentRepository.deleteAllByAlbumId(album.getId()); albumRepository.deleteByAlbumId(album.getId()); + + albumParticipationHistoryRepository.save( + AlbumParticipationHistory.createAlbumParticipationHistory( + currentMember.getId(), album.getTitle(), ParticipationAction.DELETED)); } private Album getAlbumById(Long albumId) { diff --git a/cherrypic-domain/src/main/java/org/cherrypic/album/enums/ParticipationAction.java b/cherrypic-domain/src/main/java/org/cherrypic/album/enums/ParticipationAction.java index 7d5c126d..027676d6 100644 --- a/cherrypic-domain/src/main/java/org/cherrypic/album/enums/ParticipationAction.java +++ b/cherrypic-domain/src/main/java/org/cherrypic/album/enums/ParticipationAction.java @@ -3,5 +3,6 @@ public enum ParticipationAction { JOIN, LEAVE, - KICK + KICK, + DELETED } diff --git a/cherrypic-domain/src/main/resources/db/migration/V5__create_album_participation_history_table.sql b/cherrypic-domain/src/main/resources/db/migration/V5__create_album_participation_history_table.sql index 1a972018..02044e77 100644 --- a/cherrypic-domain/src/main/resources/db/migration/V5__create_album_participation_history_table.sql +++ b/cherrypic-domain/src/main/resources/db/migration/V5__create_album_participation_history_table.sql @@ -2,7 +2,7 @@ CREATE TABLE album_participation_history ( id BIGINT AUTO_INCREMENT PRIMARY KEY, member_id BIGINT NOT NULL, album_title_snapshot VARCHAR(20) NOT NULL, - action VARCHAR(20) NOT NULL CHECK (action IN ('JOIN','LEAVE','KICK')), + action VARCHAR(20) NOT NULL CHECK (action IN ('JOIN','LEAVE','KICK','DELETED')), created_at DATETIME(6) NOT NULL, updated_at DATETIME(6) NOT NULL ); From 3bda89ce83243446dab41c4a4bfdc481a8131500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=92=E1=85=A7=E1=86=AB=E1=84=90=E1=85=A2=20=E1=84=8E?= =?UTF-8?q?=E1=85=AC?= Date: Tue, 14 Oct 2025 23:21:45 +0900 Subject: [PATCH 08/11] =?UTF-8?q?refactor:=20action=20=ED=95=84=EB=93=9C?= =?UTF-8?q?=20private=20=EB=88=84=EB=9D=BD=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../org/cherrypic/album/entity/AlbumParticipationHistory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cherrypic-domain/src/main/java/org/cherrypic/album/entity/AlbumParticipationHistory.java b/cherrypic-domain/src/main/java/org/cherrypic/album/entity/AlbumParticipationHistory.java index c572b8b6..b8331eb2 100644 --- a/cherrypic-domain/src/main/java/org/cherrypic/album/entity/AlbumParticipationHistory.java +++ b/cherrypic-domain/src/main/java/org/cherrypic/album/entity/AlbumParticipationHistory.java @@ -24,7 +24,7 @@ public class AlbumParticipationHistory extends BaseTimeEntity { @NotNull @Enumerated(EnumType.STRING) - ParticipationAction action; + private ParticipationAction action; @Builder(access = AccessLevel.PRIVATE) private AlbumParticipationHistory( From 277a21cbe0b8a09112c0afd8c3c398edcad7cb36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=92=E1=85=A7=E1=86=AB=E1=84=90=E1=85=A2=20=E1=84=8E?= =?UTF-8?q?=E1=85=AC?= Date: Tue, 14 Oct 2025 23:29:03 +0900 Subject: [PATCH 09/11] =?UTF-8?q?docs:=20=EC=95=A8=EB=B2=94=20=EC=B0=B8?= =?UTF-8?q?=EC=97=AC=20=EC=9D=B4=EB=A0=A5=20=EC=A1=B0=ED=9A=8C=20API=20?= =?UTF-8?q?=EC=8A=A4=EC=9B=A8=EA=B1=B0=20=EC=84=A4=EB=AA=85=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 --- .../cherrypic/domain/member/controller/MemberController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/member/controller/MemberController.java b/cherrypic-api/src/main/java/org/cherrypic/domain/member/controller/MemberController.java index f287c555..8447f7f4 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/member/controller/MemberController.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/member/controller/MemberController.java @@ -50,7 +50,7 @@ public LocalImageDeletionToggleResponse localImageDeletionToggle() { } @GetMapping("/me/participation-history") - @Operation(summary = "회원의 앨범 참여 이력 조회", description = "사용자가 입장/퇴장/강퇴된 앨범 이력을 조회합니다.") + @Operation(summary = "앨범 참여 이력 조회", description = "사용자가 생성/입장, 삭제, 퇴장, 강퇴된 앨범 이력을 조회합니다.") public SliceResponse participationHistoryGet( @Parameter(description = "이전 페이지의 마지막 앨범 참여 이력 ID (첫 요청 시 생략)") @RequestParam(required = false) From 1923c5382287927566138c17240c0565f6335188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=92=E1=85=A7=E1=86=AB=E1=84=90=E1=85=A2=20=E1=84=8E?= =?UTF-8?q?=E1=85=AC?= Date: Tue, 14 Oct 2025 23:33:48 +0900 Subject: [PATCH 10/11] style: spotless --- .../org/cherrypic/domain/album/service/AlbumServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cherrypic-api/src/main/java/org/cherrypic/domain/album/service/AlbumServiceImpl.java b/cherrypic-api/src/main/java/org/cherrypic/domain/album/service/AlbumServiceImpl.java index 3d61e3d0..993a1837 100644 --- a/cherrypic-api/src/main/java/org/cherrypic/domain/album/service/AlbumServiceImpl.java +++ b/cherrypic-api/src/main/java/org/cherrypic/domain/album/service/AlbumServiceImpl.java @@ -8,9 +8,9 @@ import org.cherrypic.album.entity.AlbumParticipationHistory; import org.cherrypic.album.entity.InvitationCode; import org.cherrypic.album.enums.AlbumType; +import org.cherrypic.album.enums.ParticipationAction; import org.cherrypic.domain.album.dto.event.AlbumDeleteNotificationSendEvent; import org.cherrypic.domain.album.dto.event.AlbumImagesDeleteEvent; -import org.cherrypic.album.enums.ParticipationAction; import org.cherrypic.domain.album.dto.request.AlbumCreateRequest; import org.cherrypic.domain.album.dto.request.AlbumUpdateRequest; import org.cherrypic.domain.album.dto.response.*; From c5d693cc84607d816f9e3ed854edae11b8168c34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=92=E1=85=A7=E1=86=AB=E1=84=90=E1=85=A2=20=E1=84=8E?= =?UTF-8?q?=E1=85=AC?= Date: Tue, 14 Oct 2025 23:40:24 +0900 Subject: [PATCH 11/11] =?UTF-8?q?chore:=20SonarQube=20=EC=BB=A4=EB=B2=84?= =?UTF-8?q?=EB=A6=AC=EC=A7=80=20=EC=A0=9C=EC=99=B8=20=EB=8C=80=EC=83=81?= =?UTF-8?q?=EC=97=90=20AlbumParticipationHistory,=20ParticipationAction=20?= =?UTF-8?q?=ED=81=B4=EB=9E=98=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 442ee48e..b90ab79b 100644 --- a/build.gradle +++ b/build.gradle @@ -27,7 +27,8 @@ sonarqube { '**/*Dto*.java, **/*Request*.java, **/*Response*.java, **/*Exception*.java, **/*ErrorCode*.java, **/*Validator*.java,' + '**/*FcmService*.java, **/EventImage.java, **/Notification.java, **/Favorites.java ,**/ImageEventListener.java,' + '**/TempAlbum.java, **/TempAlbumImage.java, **/TempAlbumType.java, **/TempAlbumType.java, **/FileExtension.java,' + - '**/RefundTask.java, **/RefundTaskStatus.java, cherrypic-batch/**, **/StorageUnitConverter.java, **/ImageRepositoryImpl.java' + '**/RefundTask.java, **/RefundTaskStatus.java, cherrypic-batch/**, **/StorageUnitConverter.java, **/ImageRepositoryImpl.java' + + '**/AlbumParticipationHistory.java, **/ParticipationAction.java' property 'sonar.java.coveragePlugin', 'jacoco' } }