diff --git a/src/main/java/flipnote/group/adapter/in/web/MemberController.java b/src/main/java/flipnote/group/adapter/in/web/MemberController.java index 2c0573f..f0e0633 100644 --- a/src/main/java/flipnote/group/adapter/in/web/MemberController.java +++ b/src/main/java/flipnote/group/adapter/in/web/MemberController.java @@ -12,16 +12,19 @@ import flipnote.group.api.dto.response.FindGroupMemberResponseDto; import flipnote.group.application.port.in.FindGroupMemberUseCase; +import flipnote.group.application.port.in.KickMemberUseCase; import flipnote.group.application.port.in.command.FindGroupMemberCommand; +import flipnote.group.application.port.in.command.KickMemberCommand; import flipnote.group.application.port.in.result.FindGroupMemberResult; import lombok.RequiredArgsConstructor; @RequiredArgsConstructor @RestController -@RequestMapping("/v1/groups/{groupId}") +@RequestMapping("/v1/groups/{groupId}/members") public class MemberController { private final FindGroupMemberUseCase findGroupMemberUseCase; + private final KickMemberUseCase kickMemberUseCase; /** * 그룹 내 멤버 전체 조회 @@ -29,7 +32,7 @@ public class MemberController { * @param groupId * @return */ - @GetMapping("/members") + @GetMapping("") public ResponseEntity findGroupMembers( @RequestHeader("X-USER-ID") Long userId, @PathVariable("groupId") Long groupId) { @@ -43,4 +46,23 @@ public ResponseEntity findGroupMembers( return ResponseEntity.ok(res); } + /** + * 그룹 멤버 추방 + * @param userId + * @param groupId + * @param memberId + * @return + */ + @DeleteMapping("/{memberId}") + public ResponseEntity kickGroupMember( + @RequestHeader("X-USER-ID") Long userId, + @PathVariable("groupId") Long groupId, + @PathVariable("memberId") Long memberId + ) { + KickMemberCommand cmd = new KickMemberCommand(userId, groupId, memberId); + + kickMemberUseCase.kickMember(cmd); + + return ResponseEntity.noContent().build(); + } } diff --git a/src/main/java/flipnote/group/adapter/in/web/PermissionController.java b/src/main/java/flipnote/group/adapter/in/web/PermissionController.java index 79153a0..8d4897e 100644 --- a/src/main/java/flipnote/group/adapter/in/web/PermissionController.java +++ b/src/main/java/flipnote/group/adapter/in/web/PermissionController.java @@ -94,8 +94,4 @@ public ResponseEntity findMyPermission( return ResponseEntity.ok(res); } - - //todo 그룹 멤버 추방 - - //todo 가입 신청 허가 } diff --git a/src/main/java/flipnote/group/adapter/out/entity/GroupMemberEntity.java b/src/main/java/flipnote/group/adapter/out/entity/GroupMemberEntity.java index 80836d7..17bb04e 100644 --- a/src/main/java/flipnote/group/adapter/out/entity/GroupMemberEntity.java +++ b/src/main/java/flipnote/group/adapter/out/entity/GroupMemberEntity.java @@ -49,7 +49,8 @@ public class GroupMemberEntity extends BaseEntity { private RoleEntity role; @Builder - private GroupMemberEntity(Long groupId, Long userId, RoleEntity role) { + private GroupMemberEntity(Long id, Long groupId, Long userId, RoleEntity role) { + this.id = id; this.groupId = groupId; this.userId = userId; this.role = role; @@ -71,6 +72,7 @@ public static GroupMemberEntity create(Long groupId, Long userId, RoleEntity rol public MemberInfo toMemberInfo() { return MemberInfo.builder() + .memberId(this.getId()) .userId(this.getUserId()) .role(this.getRole().getRole()) .build(); diff --git a/src/main/java/flipnote/group/adapter/out/persistence/GroupMemberRepositoryAdapter.java b/src/main/java/flipnote/group/adapter/out/persistence/GroupMemberRepositoryAdapter.java index a07fef6..2f469f6 100644 --- a/src/main/java/flipnote/group/adapter/out/persistence/GroupMemberRepositoryAdapter.java +++ b/src/main/java/flipnote/group/adapter/out/persistence/GroupMemberRepositoryAdapter.java @@ -1,6 +1,7 @@ package flipnote.group.adapter.out.persistence; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import org.springframework.stereotype.Repository; @@ -86,4 +87,27 @@ public GroupMemberEntity findMyRole(Long groupId, Long userId) { return entity; } + + @Override + public void deleteGroupMember(Long memberId) { + + GroupMemberEntity groupMember = groupMemberRepository.findById(memberId).orElseThrow( + () -> new IllegalArgumentException("not exist member") + ); + + groupMemberRepository.deleteById(memberId); + + //그룹 인원수 동기화 + GroupEntity group = groupRepository.findByIdForUpdate(groupMember.getGroupId()).orElseThrow( + () -> new IllegalArgumentException("not exist group") + ); + + group.minusCount(); + + } + + @Override + public boolean checkMember(Long memberId) { + return groupMemberRepository.existsById(memberId); + } } diff --git a/src/main/java/flipnote/group/adapter/out/persistence/GroupRoleRepositoryAdapter.java b/src/main/java/flipnote/group/adapter/out/persistence/GroupRoleRepositoryAdapter.java index bb5a606..59d38c0 100644 --- a/src/main/java/flipnote/group/adapter/out/persistence/GroupRoleRepositoryAdapter.java +++ b/src/main/java/flipnote/group/adapter/out/persistence/GroupRoleRepositoryAdapter.java @@ -30,15 +30,15 @@ public class GroupRoleRepositoryAdapter implements GroupRoleRepositoryPort { private static final Map> DEFAULT_PERMS_BY_ROLE = Map.of( GroupMemberRole.OWNER, List.of( - GroupPermission.KICK, + GroupPermission.MEMBER_MANAGE, GroupPermission.JOIN_REQUEST_MANAGE ), GroupMemberRole.HEAD_MANAGER, List.of( - GroupPermission.KICK, + GroupPermission.MEMBER_MANAGE, GroupPermission.JOIN_REQUEST_MANAGE ), GroupMemberRole.MANAGER, List.of( - GroupPermission.KICK, + GroupPermission.MEMBER_MANAGE, GroupPermission.JOIN_REQUEST_MANAGE ), GroupMemberRole.MEMBER, List.of() @@ -104,7 +104,12 @@ public boolean checkRole(Long userId, Long groupId, GroupMemberRole groupMemberR */ @Override public boolean checkPermission(Long userId, Long groupId, GroupPermission permission) { - return groupRolePermissionRepository.existsUserInGroupPermission(groupId, userId, permission); + + GroupMemberEntity groupMember = groupMemberRepository.findByGroupIdAndUserId(groupId, userId).orElseThrow( + () -> new IllegalArgumentException("not exist member") + ); + + return groupRoleRepository.existsByGroupIdAndRole(groupId, groupMember.getRole().getRole()); } /** diff --git a/src/main/java/flipnote/group/application/port/in/KickMemberUseCase.java b/src/main/java/flipnote/group/application/port/in/KickMemberUseCase.java new file mode 100644 index 0000000..8f4eb27 --- /dev/null +++ b/src/main/java/flipnote/group/application/port/in/KickMemberUseCase.java @@ -0,0 +1,7 @@ +package flipnote.group.application.port.in; + +import flipnote.group.application.port.in.command.KickMemberCommand; + +public interface KickMemberUseCase { + void kickMember(KickMemberCommand cmd); +} diff --git a/src/main/java/flipnote/group/application/port/in/command/KickMemberCommand.java b/src/main/java/flipnote/group/application/port/in/command/KickMemberCommand.java new file mode 100644 index 0000000..becdda8 --- /dev/null +++ b/src/main/java/flipnote/group/application/port/in/command/KickMemberCommand.java @@ -0,0 +1,8 @@ +package flipnote.group.application.port.in.command; + +public record KickMemberCommand( + Long userId, + Long groupId, + Long memberId +) { +} diff --git a/src/main/java/flipnote/group/application/port/out/GroupMemberRepositoryPort.java b/src/main/java/flipnote/group/application/port/out/GroupMemberRepositoryPort.java index 164fbcb..c301161 100644 --- a/src/main/java/flipnote/group/application/port/out/GroupMemberRepositoryPort.java +++ b/src/main/java/flipnote/group/application/port/out/GroupMemberRepositoryPort.java @@ -15,4 +15,8 @@ public interface GroupMemberRepositoryPort { GroupMemberEntity findMyRole(Long groupId, Long userId); boolean checkOwner(Long groupId, Long userId); + + void deleteGroupMember(Long memberId); + + boolean checkMember(Long aLong); } diff --git a/src/main/java/flipnote/group/application/service/KickMemberService.java b/src/main/java/flipnote/group/application/service/KickMemberService.java new file mode 100644 index 0000000..3eb446c --- /dev/null +++ b/src/main/java/flipnote/group/application/service/KickMemberService.java @@ -0,0 +1,38 @@ +package flipnote.group.application.service; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import flipnote.group.application.port.in.KickMemberUseCase; +import flipnote.group.application.port.in.command.KickMemberCommand; +import flipnote.group.application.port.out.GroupMemberRepositoryPort; +import flipnote.group.application.port.out.GroupRoleRepositoryPort; +import flipnote.group.domain.model.permission.GroupPermission; +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class KickMemberService implements KickMemberUseCase { + + private final GroupMemberRepositoryPort groupMemberRepository; + private final GroupRoleRepositoryPort groupRoleRepository; + + @Override + @Transactional + public void kickMember(KickMemberCommand cmd) { + //권한 체크 + boolean hasPermission = groupRoleRepository.checkPermission(cmd.userId(), cmd.groupId(), GroupPermission.MEMBER_MANAGE); + if(!hasPermission) { + throw new IllegalArgumentException("not exist permission"); + } + + boolean isExist = groupMemberRepository.checkMember(cmd.memberId()); + + if(!isExist) { + throw new IllegalArgumentException("not exist member"); + } + + groupMemberRepository.deleteGroupMember(cmd.memberId()); + + } +} diff --git a/src/main/java/flipnote/group/domain/model/member/MemberInfo.java b/src/main/java/flipnote/group/domain/model/member/MemberInfo.java index ddc7390..07d220e 100644 --- a/src/main/java/flipnote/group/domain/model/member/MemberInfo.java +++ b/src/main/java/flipnote/group/domain/model/member/MemberInfo.java @@ -8,11 +8,13 @@ @Getter @NoArgsConstructor(access = AccessLevel.PRIVATE) public class MemberInfo { + private Long memberId; private Long userId; private GroupMemberRole role; @Builder - private MemberInfo(Long userId, GroupMemberRole role) { + private MemberInfo(Long memberId, Long userId, GroupMemberRole role) { + this.memberId = memberId; this.userId = userId; this.role = role; } diff --git a/src/main/java/flipnote/group/domain/model/permission/GroupPermission.java b/src/main/java/flipnote/group/domain/model/permission/GroupPermission.java index 0a68e81..bba16ae 100644 --- a/src/main/java/flipnote/group/domain/model/permission/GroupPermission.java +++ b/src/main/java/flipnote/group/domain/model/permission/GroupPermission.java @@ -1,5 +1,5 @@ package flipnote.group.domain.model.permission; public enum GroupPermission { - KICK, JOIN_REQUEST_MANAGE + MEMBER_MANAGE, JOIN_REQUEST_MANAGE } diff --git a/src/main/java/flipnote/group/infrastructure/persistence/jpa/GroupRoleRepository.java b/src/main/java/flipnote/group/infrastructure/persistence/jpa/GroupRoleRepository.java index 1996b3b..c1d9dfc 100644 --- a/src/main/java/flipnote/group/infrastructure/persistence/jpa/GroupRoleRepository.java +++ b/src/main/java/flipnote/group/infrastructure/persistence/jpa/GroupRoleRepository.java @@ -10,4 +10,6 @@ public interface GroupRoleRepository extends JpaRepository { Optional findByGroupIdAndRole(Long groupId, GroupMemberRole groupMemberRole); + + boolean existsByGroupIdAndRole(Long groupId, GroupMemberRole role); }