diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/command/GroupCommandService.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/command/GroupCommandService.java index 84571407a..423288cd9 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/command/GroupCommandService.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/command/GroupCommandService.java @@ -18,8 +18,8 @@ import site.timecapsulearchive.core.domain.member_group.entity.MemberGroup; import site.timecapsulearchive.core.domain.member_group.exception.MemberGroupNotFoundException; import site.timecapsulearchive.core.domain.member_group.exception.NoGroupAuthorityException; -import site.timecapsulearchive.core.domain.member_group.repository.groupInviteRepository.GroupInviteRepository; -import site.timecapsulearchive.core.domain.member_group.repository.memberGroupRepository.MemberGroupRepository; +import site.timecapsulearchive.core.domain.member_group.repository.group_invite_repository.GroupInviteRepository; +import site.timecapsulearchive.core.domain.member_group.repository.member_group_repository.MemberGroupRepository; import site.timecapsulearchive.core.global.error.ErrorCode; import site.timecapsulearchive.core.infra.queue.manager.SocialNotificationManager; import site.timecapsulearchive.core.infra.s3.manager.S3ObjectManager; diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/api/query/MemberGroupQueryApi.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/api/query/MemberGroupQueryApi.java index fcd1a54eb..9d4efaebc 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/api/query/MemberGroupQueryApi.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/api/query/MemberGroupQueryApi.java @@ -9,15 +9,16 @@ import java.time.ZonedDateTime; import org.springframework.http.ResponseEntity; import site.timecapsulearchive.core.domain.group.data.response.GroupMemberInfosResponse; -import site.timecapsulearchive.core.domain.member_group.data.response.GroupInviteSummaryResponses; +import site.timecapsulearchive.core.domain.member_group.data.response.GroupReceivingInvitesSliceResponse; +import site.timecapsulearchive.core.domain.member_group.data.response.GroupSendingInvitesResponse; import site.timecapsulearchive.core.global.common.response.ApiSpec; public interface MemberGroupQueryApi { @Operation( - summary = "그룹 요청 목록 조회", - description = "사용자애게 그룹 초대 요청이 온 그룹 목록을 조회한다.", + summary = "그룹 요청 받은 목록 조회", + description = "사용자에게 그룹 초대 요청이 온 모든 그룹 목록을 조회한다.", security = {@SecurityRequirement(name = "user_token")}, tags = {"member group"} ) @@ -27,7 +28,7 @@ public interface MemberGroupQueryApi { description = "ok" ) }) - ResponseEntity> findGroupInvites( + ResponseEntity> findGroupReceivingInvites( Long memberId, @Parameter(in = ParameterIn.QUERY, description = "페이지 크기", required = true) @@ -56,4 +57,22 @@ ResponseEntity> findGroupMemberInfos( Long groupId ); + @Operation( + summary = "그룹 요청 보낸 목록 조회", + description = "그룹장이 그룹 별로 그룹 초대 요청을 보낸 사용자 목록을 조회한다. 최대 30개가 반환된다.", + security = {@SecurityRequirement(name = "user_token")}, + tags = {"member group"} + ) + @ApiResponses(value = { + @ApiResponse( + responseCode = "200", + description = "ok" + ) + }) + ResponseEntity> findGroupSendingInvites( + Long memberId, + + @Parameter(in = ParameterIn.PATH, description = "그룹 아이디", required = true) + Long groupId + ); } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/api/query/MemberGroupQueryApiController.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/api/query/MemberGroupQueryApiController.java index a8b1c4325..ba7eb7371 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/api/query/MemberGroupQueryApiController.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/api/query/MemberGroupQueryApiController.java @@ -14,7 +14,9 @@ import site.timecapsulearchive.core.domain.group.data.dto.GroupMemberDto; import site.timecapsulearchive.core.domain.group.data.response.GroupMemberInfosResponse; import site.timecapsulearchive.core.domain.member_group.data.dto.GroupInviteSummaryDto; -import site.timecapsulearchive.core.domain.member_group.data.response.GroupInviteSummaryResponses; +import site.timecapsulearchive.core.domain.member_group.data.dto.GroupSendingInviteMemberDto; +import site.timecapsulearchive.core.domain.member_group.data.response.GroupReceivingInvitesSliceResponse; +import site.timecapsulearchive.core.domain.member_group.data.response.GroupSendingInvitesResponse; import site.timecapsulearchive.core.domain.member_group.service.MemberGroupQueryService; import site.timecapsulearchive.core.global.common.response.ApiSpec; import site.timecapsulearchive.core.global.common.response.SuccessCode; @@ -30,24 +32,24 @@ public class MemberGroupQueryApiController implements MemberGroupQueryApi { @GetMapping( - value = "/invites", + value = "/receiving-invites", produces = {"application/json"} ) @Override - public ResponseEntity> findGroupInvites( + public ResponseEntity> findGroupReceivingInvites( @AuthenticationPrincipal final Long memberId, @RequestParam(defaultValue = "20", value = "size") final int size, @RequestParam(value = "created_at") final ZonedDateTime createdAt ) { - final Slice groupInviteSummaryDtos = memberGroupQueryService.findGroupInvites( + final Slice groupReceivingInvitesSlice = memberGroupQueryService.findGroupReceivingInvitesSlice( memberId, size, createdAt); return ResponseEntity.ok( ApiSpec.success( SuccessCode.SUCCESS, - GroupInviteSummaryResponses.createOf( - groupInviteSummaryDtos.getContent(), - groupInviteSummaryDtos.hasNext(), + GroupReceivingInvitesSliceResponse.createOf( + groupReceivingInvitesSlice.getContent(), + groupReceivingInvitesSlice.hasNext(), s3PreSignedUrlManager::getS3PreSignedUrlForGet ) ) @@ -77,4 +79,23 @@ public ResponseEntity> findGroupMemberInfos( ); } + @GetMapping( + value = "/{group_id}/sending-invites", + produces = {"application/json"} + ) + @Override + public ResponseEntity> findGroupSendingInvites( + @AuthenticationPrincipal final Long memberId, + @PathVariable(value = "group_id") final Long groupId + ) { + List groupSendingInvites = memberGroupQueryService.findGroupSendingInvites( + memberId, groupId); + + return ResponseEntity.ok( + ApiSpec.success( + SuccessCode.SUCCESS, + GroupSendingInvitesResponse.createOf(groupSendingInvites) + ) + ); + } } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/dto/GroupInviteSummaryDto.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/dto/GroupInviteSummaryDto.java index 140f58ec7..a5fb7fb54 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/dto/GroupInviteSummaryDto.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/dto/GroupInviteSummaryDto.java @@ -3,7 +3,7 @@ import java.time.ZonedDateTime; import java.util.function.Function; import lombok.Builder; -import site.timecapsulearchive.core.domain.member_group.data.response.GroupInviteSummaryResponse; +import site.timecapsulearchive.core.domain.member_group.data.response.GroupReceivingInviteSummaryResponse; @Builder public record GroupInviteSummaryDto( @@ -12,19 +12,19 @@ public record GroupInviteSummaryDto( String groupName, String groupProfileUrl, String description, - ZonedDateTime createdAt, + ZonedDateTime groupReceivingInviteTime, String groupOwnerName ) { - public GroupInviteSummaryResponse toResponse( + public GroupReceivingInviteSummaryResponse toResponse( final Function preSignedUrlFunction ) { - return GroupInviteSummaryResponse.builder() + return GroupReceivingInviteSummaryResponse.builder() .groupId(groupId) .groupName(groupName) .groupProfileUrl(preSignedUrlFunction.apply(groupProfileUrl)) .description(description) - .createdAt(createdAt) + .groupReceivingInviteTime(groupReceivingInviteTime) .groupOwnerName(groupOwnerName) .build(); } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/dto/GroupSendingInviteMemberDto.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/dto/GroupSendingInviteMemberDto.java new file mode 100644 index 000000000..2fcb0f82b --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/dto/GroupSendingInviteMemberDto.java @@ -0,0 +1,22 @@ +package site.timecapsulearchive.core.domain.member_group.data.dto; + + +import java.time.ZonedDateTime; +import site.timecapsulearchive.core.domain.member_group.data.response.GroupSendingInviteMemberResponse; + +public record GroupSendingInviteMemberDto( + Long id, + String nickname, + String profileUrl, + ZonedDateTime sendingInvitesCreatedAt +) { + + public GroupSendingInviteMemberResponse toResponse() { + return GroupSendingInviteMemberResponse.builder() + .id(id) + .nickname(nickname) + .profileUrl(profileUrl) + .sendingInvitesCreatedAt(sendingInvitesCreatedAt) + .build(); + } +} diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/dto/GroupSendingInvitesRequestDto.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/dto/GroupSendingInvitesRequestDto.java new file mode 100644 index 000000000..73138d8d5 --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/dto/GroupSendingInvitesRequestDto.java @@ -0,0 +1,20 @@ +package site.timecapsulearchive.core.domain.member_group.data.dto; + +import java.time.ZonedDateTime; + +public record GroupSendingInvitesRequestDto( + Long memberId, + Long groupId, + int size, + ZonedDateTime createdAt +) { + + public static GroupSendingInvitesRequestDto create( + final Long memberId, + final Long groupId, + final int size, + final ZonedDateTime createdAt + ) { + return new GroupSendingInvitesRequestDto(memberId, groupId, size, createdAt); + } +} diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupInviteSummaryResponse.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupReceivingInviteSummaryResponse.java similarity index 64% rename from backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupInviteSummaryResponse.java rename to backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupReceivingInviteSummaryResponse.java index 77acf1acf..13d154fff 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupInviteSummaryResponse.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupReceivingInviteSummaryResponse.java @@ -7,7 +7,7 @@ @Builder @Schema(description = "초대온 그룹 요약 정보") -public record GroupInviteSummaryResponse( +public record GroupReceivingInviteSummaryResponse( @Schema(description = "그룹 아이디") Long groupId, @@ -21,16 +21,17 @@ public record GroupInviteSummaryResponse( @Schema(description = "그룹 설명") String description, - @Schema(description = "그룹 생성일") - ZonedDateTime createdAt, + @Schema(description = "그룹 초대 시간") + ZonedDateTime groupReceivingInviteTime, @Schema(description = "그룹장") String groupOwnerName ) { - public GroupInviteSummaryResponse { - if (createdAt != null) { - createdAt = createdAt.withZoneSameInstant(ResponseMappingConstant.ZONE_ID); + public GroupReceivingInviteSummaryResponse { + if (groupReceivingInviteTime != null) { + groupReceivingInviteTime = groupReceivingInviteTime.withZoneSameInstant( + ResponseMappingConstant.ZONE_ID); } } } \ No newline at end of file diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupInviteSummaryResponses.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupReceivingInvitesSliceResponse.java similarity index 62% rename from backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupInviteSummaryResponses.java rename to backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupReceivingInvitesSliceResponse.java index 4dd508058..815b84658 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupInviteSummaryResponses.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupReceivingInvitesSliceResponse.java @@ -5,22 +5,23 @@ import java.util.function.Function; import site.timecapsulearchive.core.domain.member_group.data.dto.GroupInviteSummaryDto; -public record GroupInviteSummaryResponses( +public record GroupReceivingInvitesSliceResponse( @Schema(description = "초대 온 그룹 요약 정보 리스트") - List responses, + List responses, @Schema(description = "다음 페이지 유무") Boolean hasNext ) { - public static GroupInviteSummaryResponses createOf( + public static GroupReceivingInvitesSliceResponse createOf( final List dtos, final boolean hasNext, final Function preSignedUrlFunction ) { - List groupInviteSummaryResponses = dtos.stream() + List groupReceivingInviteSummaryResponse = dtos.stream() .map(dto -> dto.toResponse(preSignedUrlFunction)).toList(); - return new GroupInviteSummaryResponses(groupInviteSummaryResponses, hasNext); + return new GroupReceivingInvitesSliceResponse(groupReceivingInviteSummaryResponse, + hasNext); } } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupSendingInviteMemberResponse.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupSendingInviteMemberResponse.java new file mode 100644 index 000000000..b4193f30f --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupSendingInviteMemberResponse.java @@ -0,0 +1,19 @@ +package site.timecapsulearchive.core.domain.member_group.data.response; + +import java.time.ZonedDateTime; +import lombok.Builder; +import site.timecapsulearchive.core.global.common.response.ResponseMappingConstant; + +@Builder +public record GroupSendingInviteMemberResponse( + Long id, + String nickname, + String profileUrl, + ZonedDateTime sendingInvitesCreatedAt +) { + public GroupSendingInviteMemberResponse { + if (sendingInvitesCreatedAt != null) { + sendingInvitesCreatedAt = sendingInvitesCreatedAt.withZoneSameInstant(ResponseMappingConstant.ZONE_ID); + } + } +} diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupSendingInvitesResponse.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupSendingInvitesResponse.java new file mode 100644 index 000000000..4be590970 --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupSendingInvitesResponse.java @@ -0,0 +1,23 @@ +package site.timecapsulearchive.core.domain.member_group.data.response; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; +import site.timecapsulearchive.core.domain.member_group.data.dto.GroupSendingInviteMemberDto; + +@Schema(description = "그룹 초대 보낸 목록") +public record GroupSendingInvitesResponse( + + @Schema(description = "초대 보낸 그룹원 정보 리스트") + List responses +) { + + public static GroupSendingInvitesResponse createOf( + final List groupSendingInviteMemberDtos + ) { + List groupSendingInviteMemberResponses = groupSendingInviteMemberDtos.stream() + .map(GroupSendingInviteMemberDto::toResponse) + .toList(); + + return new GroupSendingInvitesResponse(groupSendingInviteMemberResponses); + } +} diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/groupInviteRepository/GroupInviteQueryRepository.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/group_invite_repository/GroupInviteQueryRepository.java similarity index 65% rename from backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/groupInviteRepository/GroupInviteQueryRepository.java rename to backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/group_invite_repository/GroupInviteQueryRepository.java index 7d1725f84..c9c5c3166 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/groupInviteRepository/GroupInviteQueryRepository.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/group_invite_repository/GroupInviteQueryRepository.java @@ -1,9 +1,10 @@ -package site.timecapsulearchive.core.domain.member_group.repository.groupInviteRepository; +package site.timecapsulearchive.core.domain.member_group.repository.group_invite_repository; import java.time.ZonedDateTime; import java.util.List; import org.springframework.data.domain.Slice; import site.timecapsulearchive.core.domain.member_group.data.dto.GroupInviteSummaryDto; +import site.timecapsulearchive.core.domain.member_group.data.dto.GroupSendingInviteMemberDto; public interface GroupInviteQueryRepository { @@ -11,9 +12,14 @@ public interface GroupInviteQueryRepository { List findGroupInviteIdsByGroupIdAndGroupOwnerId(final Long groupId, final Long memberId); - Slice findGroupInvitesSummary( + Slice findGroupReceivingInvitesSlice( final Long memberId, final int size, final ZonedDateTime createdAt ); + + List findGroupSendingInvites( + final Long memberId, + final Long groupId + ); } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/groupInviteRepository/GroupInviteQueryRepositoryImpl.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/group_invite_repository/GroupInviteQueryRepositoryImpl.java similarity index 74% rename from backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/groupInviteRepository/GroupInviteQueryRepositoryImpl.java rename to backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/group_invite_repository/GroupInviteQueryRepositoryImpl.java index ca2e6566b..7f2b33ec6 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/groupInviteRepository/GroupInviteQueryRepositoryImpl.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/group_invite_repository/GroupInviteQueryRepositoryImpl.java @@ -1,4 +1,4 @@ -package site.timecapsulearchive.core.domain.member_group.repository.groupInviteRepository; +package site.timecapsulearchive.core.domain.member_group.repository.group_invite_repository; import static site.timecapsulearchive.core.domain.group.entity.QGroup.group; @@ -21,6 +21,8 @@ import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import site.timecapsulearchive.core.domain.member_group.data.dto.GroupInviteSummaryDto; +import site.timecapsulearchive.core.domain.member_group.data.dto.GroupSendingInviteMemberDto; +import site.timecapsulearchive.core.global.util.SliceUtil; @Repository @RequiredArgsConstructor @@ -72,7 +74,7 @@ public List findGroupInviteIdsByGroupIdAndGroupOwnerId( } @Override - public Slice findGroupInvitesSummary( + public Slice findGroupReceivingInvitesSlice( final Long memberId, final int size, final ZonedDateTime createdAt @@ -85,24 +87,38 @@ public Slice findGroupInvitesSummary( group.groupName, group.groupProfileUrl, group.groupDescription, - group.createdAt, + groupInvite.createdAt, member.nickname ) - ) .from(groupInvite) .join(groupInvite.group, group) - .join(groupInvite.groupOwner, member).on(groupInvite.groupMember.id.eq(memberId)) - .where(groupInvite.createdAt.lt(createdAt)) + .join(groupInvite.groupOwner, member) + .where(groupInvite.groupMember.id.eq(memberId).and(groupInvite.createdAt.lt(createdAt))) .limit(size + 1) .fetch(); - final boolean hasNext = groupInviteSummaryDtos.size() > size; - if (hasNext) { - groupInviteSummaryDtos.remove(size); - } - - return new SliceImpl<>(groupInviteSummaryDtos, Pageable.ofSize(size), hasNext); + return SliceUtil.makeSlice(size, groupInviteSummaryDtos); } + public List findGroupSendingInvites( + final Long memberId, + final Long groupId + ) { + return jpaQueryFactory + .select( + Projections.constructor( + GroupSendingInviteMemberDto.class, + member.id, + member.nickname, + member.profileUrl, + groupInvite.createdAt + ) + ) + .from(groupInvite) + .join(groupInvite.groupMember, member) + .where(groupInvite.group.id.eq(groupId) + .and(groupInvite.groupOwner.id.eq(memberId))) + .fetch(); + } } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/groupInviteRepository/GroupInviteRepository.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/group_invite_repository/GroupInviteRepository.java similarity index 97% rename from backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/groupInviteRepository/GroupInviteRepository.java rename to backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/group_invite_repository/GroupInviteRepository.java index 009600258..b882c940d 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/groupInviteRepository/GroupInviteRepository.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/group_invite_repository/GroupInviteRepository.java @@ -1,4 +1,4 @@ -package site.timecapsulearchive.core.domain.member_group.repository.groupInviteRepository; +package site.timecapsulearchive.core.domain.member_group.repository.group_invite_repository; import java.util.List; import org.springframework.data.jpa.repository.Modifying; diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/memberGroupRepository/MemberGroupQueryRepository.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupQueryRepository.java similarity index 96% rename from backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/memberGroupRepository/MemberGroupQueryRepository.java rename to backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupQueryRepository.java index e44701cb2..f664cc0cc 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/memberGroupRepository/MemberGroupQueryRepository.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupQueryRepository.java @@ -1,4 +1,4 @@ -package site.timecapsulearchive.core.domain.member_group.repository.memberGroupRepository; +package site.timecapsulearchive.core.domain.member_group.repository.member_group_repository; import java.util.List; import java.util.Optional; diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/memberGroupRepository/MemberGroupQueryRepositoryImpl.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupQueryRepositoryImpl.java similarity index 99% rename from backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/memberGroupRepository/MemberGroupQueryRepositoryImpl.java rename to backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupQueryRepositoryImpl.java index 4251ae4ef..9eafc40a2 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/memberGroupRepository/MemberGroupQueryRepositoryImpl.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupQueryRepositoryImpl.java @@ -1,4 +1,4 @@ -package site.timecapsulearchive.core.domain.member_group.repository.memberGroupRepository; +package site.timecapsulearchive.core.domain.member_group.repository.member_group_repository; import static site.timecapsulearchive.core.domain.group.entity.QGroup.group; import static site.timecapsulearchive.core.domain.member.entity.QMember.member; diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/memberGroupRepository/MemberGroupRepository.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupRepository.java similarity index 95% rename from backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/memberGroupRepository/MemberGroupRepository.java rename to backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupRepository.java index e5970ae39..39393cb7b 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/memberGroupRepository/MemberGroupRepository.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupRepository.java @@ -1,4 +1,4 @@ -package site.timecapsulearchive.core.domain.member_group.repository.memberGroupRepository; +package site.timecapsulearchive.core.domain.member_group.repository.member_group_repository; import java.util.List; import java.util.Optional; diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/service/MemberGroupCommandService.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/service/MemberGroupCommandService.java index 5f9e3bbc1..35dc7b94c 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/service/MemberGroupCommandService.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/service/MemberGroupCommandService.java @@ -20,8 +20,8 @@ import site.timecapsulearchive.core.domain.member_group.exception.MemberGroupKickDuplicatedIdException; import site.timecapsulearchive.core.domain.member_group.exception.MemberGroupNotFoundException; import site.timecapsulearchive.core.domain.member_group.exception.NoGroupAuthorityException; -import site.timecapsulearchive.core.domain.member_group.repository.groupInviteRepository.GroupInviteRepository; -import site.timecapsulearchive.core.domain.member_group.repository.memberGroupRepository.MemberGroupRepository; +import site.timecapsulearchive.core.domain.member_group.repository.group_invite_repository.GroupInviteRepository; +import site.timecapsulearchive.core.domain.member_group.repository.member_group_repository.MemberGroupRepository; import site.timecapsulearchive.core.global.config.redis.RedissonLock; import site.timecapsulearchive.core.infra.queue.manager.SocialNotificationManager; @@ -96,7 +96,8 @@ public GroupAcceptNotificationDto acceptGroupInvite(final Long memberId, final L return new GroupAcceptNotificationDto(groupMember.getNickname(), groupOwnerId); } - private void deleteGroupInvite(final Long memberId, final Long groupId, final Long groupOwnerId) { + private void deleteGroupInvite(final Long memberId, final Long groupId, + final Long groupOwnerId) { final int isDenyRequest = groupInviteRepository.deleteGroupInviteByGroupIdAndGroupOwnerIdAndGroupMemberId( groupId, groupOwnerId, memberId); if (isDenyRequest != 1) { diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/service/MemberGroupQueryService.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/service/MemberGroupQueryService.java index 41fba78a2..dd8141997 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/service/MemberGroupQueryService.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/service/MemberGroupQueryService.java @@ -9,8 +9,9 @@ import site.timecapsulearchive.core.domain.group.data.dto.GroupMemberDto; import site.timecapsulearchive.core.domain.group.exception.GroupNotFoundException; import site.timecapsulearchive.core.domain.member_group.data.dto.GroupInviteSummaryDto; -import site.timecapsulearchive.core.domain.member_group.repository.groupInviteRepository.GroupInviteRepository; -import site.timecapsulearchive.core.domain.member_group.repository.memberGroupRepository.MemberGroupRepository; +import site.timecapsulearchive.core.domain.member_group.data.dto.GroupSendingInviteMemberDto; +import site.timecapsulearchive.core.domain.member_group.repository.group_invite_repository.GroupInviteRepository; +import site.timecapsulearchive.core.domain.member_group.repository.member_group_repository.MemberGroupRepository; @Service @RequiredArgsConstructor @@ -20,12 +21,12 @@ public class MemberGroupQueryService { private final GroupInviteRepository groupInviteRepository; private final MemberGroupRepository memberGroupRepository; - public Slice findGroupInvites( + public Slice findGroupReceivingInvitesSlice( final Long memberId, final int size, final ZonedDateTime createdAt ) { - return groupInviteRepository.findGroupInvitesSummary(memberId, size, createdAt); + return groupInviteRepository.findGroupReceivingInvitesSlice(memberId, size, createdAt); } public List findGroupMemberIds(final Long groupId) { @@ -40,4 +41,10 @@ public List findGroupMemberInfos( return memberGroupRepository.findGroupMemberInfos(memberId, groupId); } + public List findGroupSendingInvites( + final Long memberId, + final Long groupId + ) { + return groupInviteRepository.findGroupSendingInvites(memberId, groupId); + } } diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/group/service/GroupCommandServiceTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/group/service/GroupCommandServiceTest.java index f6b55a63f..248433597 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/group/service/GroupCommandServiceTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/group/service/GroupCommandServiceTest.java @@ -34,8 +34,8 @@ import site.timecapsulearchive.core.domain.member_group.entity.MemberGroup; import site.timecapsulearchive.core.domain.member_group.exception.MemberGroupNotFoundException; import site.timecapsulearchive.core.domain.member_group.exception.NoGroupAuthorityException; -import site.timecapsulearchive.core.domain.member_group.repository.groupInviteRepository.GroupInviteRepository; -import site.timecapsulearchive.core.domain.member_group.repository.memberGroupRepository.MemberGroupRepository; +import site.timecapsulearchive.core.domain.member_group.repository.group_invite_repository.GroupInviteRepository; +import site.timecapsulearchive.core.domain.member_group.repository.member_group_repository.MemberGroupRepository; import site.timecapsulearchive.core.global.error.ErrorCode; import site.timecapsulearchive.core.infra.queue.manager.SocialNotificationManager; import site.timecapsulearchive.core.infra.s3.manager.S3ObjectManager; diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/repository/GroupInviteQueryRepositoryTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/repository/GroupInviteQueryRepositoryTest.java index 52048ddda..5e8522e18 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/repository/GroupInviteQueryRepositoryTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/repository/GroupInviteQueryRepositoryTest.java @@ -1,12 +1,12 @@ package site.timecapsulearchive.core.domain.member_group.repository; -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import com.querydsl.jpa.impl.JPAQueryFactory; import jakarta.persistence.EntityManager; +import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.List; -import org.assertj.core.api.Assertions; import org.assertj.core.api.SoftAssertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -22,16 +22,21 @@ import site.timecapsulearchive.core.domain.group.entity.Group; import site.timecapsulearchive.core.domain.member.entity.Member; import site.timecapsulearchive.core.domain.member_group.data.dto.GroupInviteSummaryDto; +import site.timecapsulearchive.core.domain.member_group.data.dto.GroupSendingInviteMemberDto; import site.timecapsulearchive.core.domain.member_group.entity.GroupInvite; -import site.timecapsulearchive.core.domain.member_group.repository.groupInviteRepository.GroupInviteQueryRepository; -import site.timecapsulearchive.core.domain.member_group.repository.groupInviteRepository.GroupInviteQueryRepositoryImpl; +import site.timecapsulearchive.core.domain.member_group.repository.group_invite_repository.GroupInviteQueryRepository; +import site.timecapsulearchive.core.domain.member_group.repository.group_invite_repository.GroupInviteQueryRepositoryImpl; @TestConstructor(autowireMode = AutowireMode.ALL) class GroupInviteQueryRepositoryTest extends RepositoryTest { private static final int MAX_GROUP_COUNT = 2; + private final GroupInviteQueryRepository groupInviteRepository; - private Member groupMember; + + private Long groupId; + private Long groupOwnerId; + private Long groupMemberId; GroupInviteQueryRepositoryTest( JdbcTemplate jdbcTemplate, @@ -47,14 +52,17 @@ void setUp(@Autowired EntityManager entityManager) { // 그룹 초대 할 그룹장들 List groupOwners = MemberFixture.members(0, MAX_GROUP_COUNT); groupOwners.forEach(entityManager::persist); + groupOwnerId = groupOwners.get(0).getId(); //그룹 초대 올 그룹원 - groupMember = MemberFixture.member(2); + Member groupMember = MemberFixture.member(2); entityManager.persist(groupMember); + groupMemberId = groupMember.getId(); // 그룹들 List groups = GroupFixture.groups(0, MAX_GROUP_COUNT); groups.forEach(entityManager::persist); + groupId = groups.get(0).getId(); // 그룹원에게 초대온 그룹 초대들 for (int i = 0; i < MAX_GROUP_COUNT; i++) { @@ -65,55 +73,87 @@ void setUp(@Autowired EntityManager entityManager) { } @Test - void 사용자는_자신에게_온_그룹_초대_목록을_조회할_수_있다() { + void 사용자는_자신에게_온_그룹_초대_목록을_조회하면_그룹_초대목록이_나온다() { //given - Long memberId = groupMember.getId(); + Long memberId = groupMemberId; int size = 1; ZonedDateTime createAt = ZonedDateTime.now().plusDays(1); //when - Slice groupInvitesSummary = groupInviteRepository.findGroupInvitesSummary( + Slice groupInvitesSummary = groupInviteRepository.findGroupReceivingInvitesSlice( memberId, size, createAt); //then - assertThat(groupInvitesSummary.getContent()).isNotNull(); + assertThat(groupInvitesSummary.getContent()).isNotEmpty(); } @Test void 사용자는_자신에게_온_그룹_초대_목록에서_그룹_정보와_그룹장을_알_수_있다() { //given - Long memberId = groupMember.getId(); + Long memberId = groupMemberId; int size = 1; ZonedDateTime createAt = ZonedDateTime.now().plusDays(1); //when - Slice groupInvitesSummary = groupInviteRepository.findGroupInvitesSummary( + Slice groupInvitesSummary = groupInviteRepository.findGroupReceivingInvitesSlice( memberId, size, createAt); //then SoftAssertions.assertSoftly(softly -> { - Assertions.assertThat(groupInvitesSummary).allMatch(g -> !g.groupName().isEmpty()); - Assertions.assertThat(groupInvitesSummary) + assertThat(groupInvitesSummary).allMatch(g -> !g.groupName().isEmpty()); + assertThat(groupInvitesSummary) .allMatch(g -> !g.groupProfileUrl().isEmpty()); - Assertions.assertThat(groupInvitesSummary).allMatch(g -> !g.description().isEmpty()); - Assertions.assertThat(groupInvitesSummary).allMatch(g -> !g.groupOwnerName().isEmpty()); + assertThat(groupInvitesSummary).allMatch(g -> !g.description().isEmpty()); + assertThat(groupInvitesSummary).allMatch(g -> !g.groupOwnerName().isEmpty()); }); } @Test - void 사용자는_조회한_그룹_초대_목록_후_그룹_초대_존재_여부를_확인_할_수_있다() { + void 사용자는_그룹_초대_받은_목록_첫_페이지를_조회_후_다음_페이지에서_그룹_초대_받은_목록을_조회_할_수_있다() { //given - Long memberId = groupMember.getId(); + Long memberId = groupMemberId; int size = 1; - ZonedDateTime createAt = ZonedDateTime.now().plusDays(1); + ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(3); + Slice firstSlice = groupInviteRepository.findGroupReceivingInvitesSlice( + memberId, size, now); //when - Slice groupInvitesSummary = groupInviteRepository.findGroupInvitesSummary( - memberId, size, createAt); + GroupInviteSummaryDto dto = firstSlice.getContent().get(0); + Slice groupInvitesSummary = groupInviteRepository.findGroupReceivingInvitesSlice( + memberId, size, dto.groupReceivingInviteTime().plusSeconds(1L)); + + //then + assertThat(groupInvitesSummary.getContent()).isNotEmpty(); + } + + @Test + void 그룹장은_자신이_보낸_그룹_초대_목록을_조회하면_그룹_초대목록이_나온다() { + //given + //when + List groupSendingInvites = groupInviteRepository.findGroupSendingInvites( + groupOwnerId, groupId); //then - assertThat(groupInvitesSummary.hasNext()).isTrue(); + SoftAssertions.assertSoftly(softly -> { + softly.assertThat(groupSendingInvites).isNotEmpty(); + softly.assertThat(groupSendingInvites).allMatch(dto -> dto.id() != null); + softly.assertThat(groupSendingInvites) + .allMatch(dto -> dto.nickname() != null && !dto.nickname().isBlank()); + softly.assertThat(groupSendingInvites) + .allMatch(dto -> dto.profileUrl() != null && !dto.profileUrl().isBlank()); + softly.assertThat(groupSendingInvites) + .allMatch(dto -> dto.sendingInvitesCreatedAt() != null); + }); } + @Test + void 그룹원은_자신이_보낸_그룹_초대_목록을_조회하면_빈_리스트가_나온다() { + //given + //when + List groupSendingInvites = groupInviteRepository.findGroupSendingInvites( + groupMemberId, groupId); + //then + assertThat(groupSendingInvites).isEmpty(); + } } diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/repository/MemberGroupQueryRepositoryTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/repository/MemberGroupQueryRepositoryTest.java index eec20ba04..04e9cfb94 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/repository/MemberGroupQueryRepositoryTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/repository/MemberGroupQueryRepositoryTest.java @@ -63,10 +63,6 @@ void setup(@Autowired EntityManager entityManager) { groups.add(group); } - //그룹원들 - List members = MemberFixture.members(4, 2); - members.forEach(entityManager::persist); - //그룹에 사용자를 그룹장으로 설정 for (int count = 0; count < GROUP_COUNT; count++) { MemberGroup memberGroup = MemberGroupFixture.memberGroup(member, groups.get(count), @@ -74,6 +70,10 @@ void setup(@Autowired EntityManager entityManager) { entityManager.persist(memberGroup); } + //그룹원들 + List members = MemberFixture.members(4, 2); + members.forEach(entityManager::persist); + //그룹원들 설정 List memberGroups = MemberGroupFixture.memberGroups(members, groups.get(0)); memberGroups.forEach(entityManager::persist); diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/service/MemberGroupCommandServiceTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/service/MemberGroupCommandServiceTest.java index a3306a721..955a6eaf4 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/service/MemberGroupCommandServiceTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/service/MemberGroupCommandServiceTest.java @@ -38,8 +38,8 @@ import site.timecapsulearchive.core.domain.member_group.exception.MemberGroupNotFoundException; import site.timecapsulearchive.core.domain.member_group.exception.NoGroupAuthorityException; import site.timecapsulearchive.core.domain.member_group.facade.MemberGroupFacade; -import site.timecapsulearchive.core.domain.member_group.repository.groupInviteRepository.GroupInviteRepository; -import site.timecapsulearchive.core.domain.member_group.repository.memberGroupRepository.MemberGroupRepository; +import site.timecapsulearchive.core.domain.member_group.repository.group_invite_repository.GroupInviteRepository; +import site.timecapsulearchive.core.domain.member_group.repository.member_group_repository.MemberGroupRepository; import site.timecapsulearchive.core.global.error.ErrorCode; import site.timecapsulearchive.core.infra.queue.manager.SocialNotificationManager; @@ -211,7 +211,8 @@ class MemberGroupCommandServiceTest { given(memberRepository.findMemberById(memberId)).willReturn(Optional.of(groupMember)); given(groupRepository.findGroupById(groupId)).willReturn( Optional.of(GroupFixture.group())); - given(memberGroupRepository.findGroupOwnerId(groupId)).willReturn(Optional.of(groupOwnerId)); + given(memberGroupRepository.findGroupOwnerId(groupId)).willReturn( + Optional.of(groupOwnerId)); given(groupInviteRepository.deleteGroupInviteByGroupIdAndGroupOwnerIdAndGroupMemberId( groupId, groupOwnerId, memberId)).willReturn(1); @@ -223,7 +224,8 @@ class MemberGroupCommandServiceTest { //then SoftAssertions.assertSoftly( softly -> { - assertThat(groupAcceptNotificationDto.groupMemberNickname()).isEqualTo(groupMember.getNickname()); + assertThat(groupAcceptNotificationDto.groupMemberNickname()).isEqualTo( + groupMember.getNickname()); assertThat(groupAcceptNotificationDto.groupOwnerId()).isEqualTo(groupOwnerId); } ); diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/infrastructure/RedisConcurrencyTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/infrastructure/RedisConcurrencyTest.java index dfebd87e9..b86d3999b 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/infrastructure/RedisConcurrencyTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/infrastructure/RedisConcurrencyTest.java @@ -27,8 +27,8 @@ import site.timecapsulearchive.core.domain.member.entity.Member; import site.timecapsulearchive.core.domain.member.repository.MemberRepository; import site.timecapsulearchive.core.domain.member_group.facade.MemberGroupFacade; -import site.timecapsulearchive.core.domain.member_group.repository.groupInviteRepository.GroupInviteRepository; -import site.timecapsulearchive.core.domain.member_group.repository.memberGroupRepository.MemberGroupRepository; +import site.timecapsulearchive.core.domain.member_group.repository.group_invite_repository.GroupInviteRepository; +import site.timecapsulearchive.core.domain.member_group.repository.member_group_repository.MemberGroupRepository; import site.timecapsulearchive.core.domain.member_group.service.MemberGroupCommandService; import site.timecapsulearchive.core.global.error.ErrorCode; import site.timecapsulearchive.core.global.error.exception.RedisLockException;