From 42efafbf2b90481b78a87a20c838884b40e3eb19 Mon Sep 17 00:00:00 2001 From: GaBaljaintheroom Date: Wed, 8 May 2024 15:16:17 +0900 Subject: [PATCH] =?UTF-8?q?feat=20:=20=ED=94=84=EB=A1=9D=EC=8B=9C=20?= =?UTF-8?q?=ED=8C=A8=ED=84=B4=EC=9C=BC=EB=A1=9C=20=EC=84=9C=EB=B9=84?= =?UTF-8?q?=EC=8A=A4=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/domain/group/api/GroupApi.java | 13 +-- .../domain/group/api/GroupApiController.java | 18 +++- .../group/service/GroupReadService.java | 20 +++++ .../group/service/GroupReadServiceImpl.java | 53 ++++++++++++ .../domain/group/service/GroupService.java | 84 +------------------ .../group/service/GroupServiceImpl.java | 47 +++++++++++ .../group/service/GroupWriteService.java | 10 +++ .../group/service/GroupWriteServiceImpl.java | 53 ++++++++++++ 8 files changed, 206 insertions(+), 92 deletions(-) create mode 100644 backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupReadService.java create mode 100644 backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupReadServiceImpl.java create mode 100644 backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupServiceImpl.java create mode 100644 backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupWriteService.java create mode 100644 backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupWriteServiceImpl.java diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/api/GroupApi.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/api/GroupApi.java index d90e76ef5..e80e56508 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/api/GroupApi.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/api/GroupApi.java @@ -181,13 +181,14 @@ ResponseEntity> findGroups( description = "처리 시작" ) }) - @PostMapping(value = "/groups/{group_id}/members/{member_id}/invitation") - ResponseEntity inviteGroup( - @Parameter(in = ParameterIn.PATH, description = "그룹 아이디", required = true, schema = @Schema()) - @PathVariable("group_id") Long groupId, + ResponseEntity> inviteGroup( + Long memberId, - @Parameter(in = ParameterIn.PATH, description = "대상 회원 아이디", required = true, schema = @Schema()) - @PathVariable("member_id") Long memberId + @Parameter(in = ParameterIn.PATH, description = "그룹 아이디", required = true) + Long groupId, + + @Parameter(in = ParameterIn.PATH, description = "대상 회원 아이디", required = true) + Long targetId ); @Operation( diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/api/GroupApiController.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/api/GroupApiController.java index e8a067e35..1f5afbd46 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/api/GroupApiController.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/api/GroupApiController.java @@ -84,7 +84,8 @@ public ResponseEntity> findGroupDetailById( @AuthenticationPrincipal final Long memberId, @PathVariable("group_id") final Long groupId ) { - final GroupDetailDto groupDetailDto = groupService.findGroupDetailByGroupId(memberId, groupId); + final GroupDetailDto groupDetailDto = groupService.findGroupDetailByGroupId(memberId, + groupId); return ResponseEntity.ok( ApiSpec.success( @@ -118,9 +119,20 @@ public ResponseEntity> findGroups( ); } + @PostMapping(value = "/invite/{group_id}/member/{target_id}") @Override - public ResponseEntity inviteGroup(Long groupId, Long memberId) { - return null; + public ResponseEntity> inviteGroup( + @AuthenticationPrincipal final Long memberId, + @PathVariable("group_id") final Long groupId, + @PathVariable("target_id") final Long targetId + ) { + groupService.inviteGroup(memberId, groupId, targetId); + + return ResponseEntity.ok( + ApiSpec.empty( + SuccessCode.SUCCESS + ) + ); } @Override diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupReadService.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupReadService.java new file mode 100644 index 000000000..df5824887 --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupReadService.java @@ -0,0 +1,20 @@ +package site.timecapsulearchive.core.domain.group.service; + +import java.time.ZonedDateTime; +import org.springframework.data.domain.Slice; +import site.timecapsulearchive.core.domain.group.data.dto.GroupDetailDto; +import site.timecapsulearchive.core.domain.group.data.dto.GroupSummaryDto; +import site.timecapsulearchive.core.domain.group.entity.Group; + +public interface GroupReadService { + + Group findGroupById(final Long groupId); + + Slice findGroupsSlice( + final Long memberId, + final int size, + final ZonedDateTime createdAt + ); + + GroupDetailDto findGroupDetailByGroupId(final Long memberId, final Long groupId); +} diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupReadServiceImpl.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupReadServiceImpl.java new file mode 100644 index 000000000..fd639f66f --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupReadServiceImpl.java @@ -0,0 +1,53 @@ +package site.timecapsulearchive.core.domain.group.service; + +import java.time.ZonedDateTime; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Slice; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import site.timecapsulearchive.core.domain.group.data.dto.GroupDetailDto; +import site.timecapsulearchive.core.domain.group.data.dto.GroupSummaryDto; +import site.timecapsulearchive.core.domain.group.entity.Group; +import site.timecapsulearchive.core.domain.group.exception.GroupNotFoundException; +import site.timecapsulearchive.core.domain.group.repository.GroupQueryRepository; +import site.timecapsulearchive.core.domain.group.repository.GroupRepository; + +@Service +@RequiredArgsConstructor +public class GroupReadServiceImpl implements GroupReadService { + + private final GroupQueryRepository groupQueryRepository; + private final GroupRepository groupRepository; + + + @Transactional(readOnly = true) + public Group findGroupById(final Long groupId) { + return groupRepository.findGroupById(groupId) + .orElseThrow(GroupNotFoundException::new); + } + + @Transactional(readOnly = true) + public Slice findGroupsSlice( + final Long memberId, + final int size, + final ZonedDateTime createdAt + ) { + return groupQueryRepository.findGroupsSlice(memberId, size, createdAt); + } + + @Transactional(readOnly = true) + public GroupDetailDto findGroupDetailByGroupId(final Long memberId, final Long groupId) { + final GroupDetailDto groupDetailDto = groupQueryRepository.findGroupDetailByGroupId(groupId) + .orElseThrow(GroupNotFoundException::new); + + final boolean isGroupMember = groupDetailDto.members() + .stream() + .anyMatch(m -> m.memberId().equals(memberId)); + + if (!isGroupMember) { + throw new GroupNotFoundException(); + } + + return groupDetailDto; + } +} diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupService.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupService.java index 98b3b1603..5c04d6a01 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupService.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupService.java @@ -1,87 +1,5 @@ package site.timecapsulearchive.core.domain.group.service; -import lombok.RequiredArgsConstructor; -import java.time.ZonedDateTime; -import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Slice; -import org.springframework.stereotype.Service; -import org.springframework.transaction.TransactionStatus; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.transaction.support.TransactionCallbackWithoutResult; -import org.springframework.transaction.support.TransactionTemplate; -import site.timecapsulearchive.core.domain.group.data.dto.GroupCreateDto; -import site.timecapsulearchive.core.domain.group.data.dto.GroupDetailDto; -import site.timecapsulearchive.core.domain.group.data.dto.GroupSummaryDto; -import site.timecapsulearchive.core.domain.group.entity.Group; -import site.timecapsulearchive.core.domain.group.entity.MemberGroup; -import site.timecapsulearchive.core.domain.group.exception.GroupNotFoundException; -import site.timecapsulearchive.core.domain.group.repository.GroupQueryRepository; -import site.timecapsulearchive.core.domain.group.repository.GroupRepository; -import site.timecapsulearchive.core.domain.group.repository.MemberGroupRepository; -import site.timecapsulearchive.core.domain.member.entity.Member; -import site.timecapsulearchive.core.domain.member.exception.MemberNotFoundException; -import site.timecapsulearchive.core.domain.member.repository.MemberRepository; -import site.timecapsulearchive.core.infra.queue.manager.SocialNotificationManager; +public interface GroupService extends GroupReadService, GroupWriteService { -@Service -@RequiredArgsConstructor -public class GroupService { - - private final GroupRepository groupRepository; - private final MemberRepository memberRepository; - private final MemberGroupRepository memberGroupRepository; - private final TransactionTemplate transactionTemplate; - private final SocialNotificationManager socialNotificationManager; - private final GroupQueryRepository groupQueryRepository; - - public void createGroup(final Long memberId, final GroupCreateDto dto) { - final Member member = memberRepository.findMemberById(memberId) - .orElseThrow(MemberNotFoundException::new); - - final Group group = dto.toEntity(); - - final MemberGroup memberGroup = MemberGroup.createGroupOwner(member, group); - - transactionTemplate.execute(new TransactionCallbackWithoutResult() { - @Override - protected void doInTransactionWithoutResult(TransactionStatus status) { - groupRepository.save(group); - memberGroupRepository.save(memberGroup); - } - }); - - socialNotificationManager.sendGroupInviteMessage(member.getNickname(), - dto.groupProfileUrl(), dto.targetIds()); - } - - @Transactional(readOnly = true) - public Group findGroupById(Long groupId) { - return groupRepository.findGroupById(groupId) - .orElseThrow(GroupNotFoundException::new); - } - - @Transactional(readOnly = true) - public Slice findGroupsSlice( - final Long memberId, - final int size, - final ZonedDateTime createdAt - ) { - return groupQueryRepository.findGroupsSlice(memberId, size, createdAt); - } - - @Transactional(readOnly = true) - public GroupDetailDto findGroupDetailByGroupId(final Long memberId, final Long groupId) { - final GroupDetailDto groupDetailDto = groupQueryRepository.findGroupDetailByGroupId(groupId) - .orElseThrow(GroupNotFoundException::new); - - final boolean isGroupMember = groupDetailDto.members() - .stream() - .anyMatch(m -> m.memberId().equals(memberId)); - - if (!isGroupMember) { - throw new GroupNotFoundException(); - } - - return groupDetailDto; - } } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupServiceImpl.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupServiceImpl.java new file mode 100644 index 000000000..b765342d7 --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupServiceImpl.java @@ -0,0 +1,47 @@ +package site.timecapsulearchive.core.domain.group.service; + +import java.time.ZonedDateTime; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Slice; +import org.springframework.stereotype.Service; +import site.timecapsulearchive.core.domain.group.data.dto.GroupCreateDto; +import site.timecapsulearchive.core.domain.group.data.dto.GroupDetailDto; +import site.timecapsulearchive.core.domain.group.data.dto.GroupSummaryDto; +import site.timecapsulearchive.core.domain.group.entity.Group; + +@Service +@RequiredArgsConstructor +public class GroupServiceImpl implements GroupService { + + private final GroupReadService groupReadService; + private final GroupWriteService groupWriteService; + + @Override + public Group findGroupById(final Long groupId) { + return groupReadService.findGroupById(groupId); + } + + @Override + public Slice findGroupsSlice( + final Long memberId, + final int size, + final ZonedDateTime createdAt + ) { + return groupReadService.findGroupsSlice(memberId, size, createdAt); + } + + @Override + public GroupDetailDto findGroupDetailByGroupId(final Long memberId, final Long groupId) { + return groupReadService.findGroupDetailByGroupId(memberId, groupId); + } + + @Override + public void createGroup(final Long memberId, final GroupCreateDto dto) { + groupWriteService.createGroup(memberId, dto); + } + + @Override + public void inviteGroup(final Long memberId, final Long groupId, final Long targetId) { + groupWriteService.inviteGroup(memberId, groupId, targetId); + } +} diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupWriteService.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupWriteService.java new file mode 100644 index 000000000..de57f7747 --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupWriteService.java @@ -0,0 +1,10 @@ +package site.timecapsulearchive.core.domain.group.service; + +import site.timecapsulearchive.core.domain.group.data.dto.GroupCreateDto; + +public interface GroupWriteService { + + void createGroup(final Long memberId, final GroupCreateDto dto); + + void inviteGroup(final Long memberId, final Long groupId, final Long targetId); +} diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupWriteServiceImpl.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupWriteServiceImpl.java new file mode 100644 index 000000000..d7c64718f --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/GroupWriteServiceImpl.java @@ -0,0 +1,53 @@ +package site.timecapsulearchive.core.domain.group.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.TransactionStatus; +import org.springframework.transaction.support.TransactionCallbackWithoutResult; +import org.springframework.transaction.support.TransactionTemplate; +import site.timecapsulearchive.core.domain.group.data.dto.GroupCreateDto; +import site.timecapsulearchive.core.domain.group.entity.Group; +import site.timecapsulearchive.core.domain.group.entity.MemberGroup; +import site.timecapsulearchive.core.domain.group.repository.GroupRepository; +import site.timecapsulearchive.core.domain.group.repository.MemberGroupRepository; +import site.timecapsulearchive.core.domain.member.entity.Member; +import site.timecapsulearchive.core.domain.member.exception.MemberNotFoundException; +import site.timecapsulearchive.core.domain.member.repository.MemberRepository; +import site.timecapsulearchive.core.infra.queue.manager.SocialNotificationManager; + +@Service +@RequiredArgsConstructor +public class GroupWriteServiceImpl implements GroupWriteService { + + private final GroupRepository groupRepository; + private final MemberRepository memberRepository; + private final MemberGroupRepository memberGroupRepository; + private final TransactionTemplate transactionTemplate; + private final SocialNotificationManager socialNotificationManager; + + public void createGroup(final Long memberId, final GroupCreateDto dto) { + final Member member = memberRepository.findMemberById(memberId) + .orElseThrow(MemberNotFoundException::new); + + final Group group = dto.toEntity(); + + final MemberGroup memberGroup = MemberGroup.createGroupOwner(member, group); + + transactionTemplate.execute(new TransactionCallbackWithoutResult() { + @Override + protected void doInTransactionWithoutResult(TransactionStatus status) { + groupRepository.save(group); + memberGroupRepository.save(memberGroup); + } + }); + + socialNotificationManager.sendGroupInviteMessage(member.getNickname(), + dto.groupProfileUrl(), dto.targetIds()); + } + + @Override + public void inviteGroup(Long memberId, Long groupId, Long targetId) { + + } + +}