-
Notifications
You must be signed in to change notification settings - Fork 1
feat: 동아리 내 권한 관리 기능 구현 #133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: 동아리 내 권한 관리 기능 구현 #133
Conversation
…ithub.com/JanooGwan/KONECT_BACK_END into feat/CAM-175-update-club-member-authority
a7ad764 to
a01dc72
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
고생하셨습니다.
웬만해서는 하나의 API당 하나의 PR로 작업을 올려주세요! 작업의 볼륨이 커진다면 더 쪼개주시면 좋고요.
그리고 개발한 API는 테스트 후 PR 올리시는 지 궁금합니다!
| @Schema(description = "우선순위 (낮을수록 높은 직급)", example = "0", requiredMode = REQUIRED) | ||
| Integer priority, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
우선순위를 넣은 이유가 무엇인가요??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
우선순위를 이용해서 직급 간 관리를 수행할 수 있도록 하려고 했습니다
(ex. 회장은 운영진보다 우선순위가 높음 -> 회장은 운영진 관리 가능, 그 반대는 못함)
하지만 권한 종류가 4개(회장, 부회장, 운영진, 일반)로 많지 않기 때문에,
priority 필드를 지우고, repository에서 다음과 같이 수정하려고 하고 있습니다.
@Query("""
SELECT cp
FROM ClubPosition cp
WHERE cp.club.id = :clubId
ORDER BY
CASE cp.clubPositionGroup
WHEN gg.agit.konect.domain.club.enums.ClubPositionGroup.PRESIDENT THEN 0
WHEN gg.agit.konect.domain.club.enums.ClubPositionGroup.VICE_PRESIDENT THEN 1
WHEN gg.agit.konect.domain.club.enums.ClubPositionGroup.MANAGER THEN 2
WHEN gg.agit.konect.domain.club.enums.ClubPositionGroup.MEMBER THEN 3
END ASC,
cp.name ASC
""")
List<ClubPosition> findAllByClubId(@Param("clubId") Integer clubId);
| @Schema(description = "이름 변경 가능 여부", example = "false", requiredMode = REQUIRED) | ||
| Boolean canRename, | ||
|
|
||
| @Schema(description = "삭제 가능 여부", example = "false", requiredMode = REQUIRED) | ||
| Boolean canDelete |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이런건 너무 과한 것 같아 보입니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
필드로 꼭 추가할 필요는 없다는 말씀이신가요??
다시 보니 굳이인가 싶기도 하긴 합니다
필드 없이 비즈니스 로직 만으로도 충분할 것 같습니다
| @PatchMapping("/{clubId}/positions/{positionId}") | ||
| ResponseEntity<ClubPositionsResponse> updateClubPositionName( | ||
| @PathVariable(name = "clubId") Integer clubId, | ||
| @PathVariable(name = "positionId") Integer positionId, | ||
| @Valid @RequestBody ClubPositionUpdateRequest request, | ||
| @UserId Integer userId | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PATCH로 지정한 이유가 따로 있나요?positionId를 요청 바디에서 받는 형태는 어떻게 생각하시나요? 다른 API에서도 마찬가지 입니당
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ClubPosition의name만 변경하게 되는 것이라PATCH로 일부 필드만 변경되게끔 하는게 적절하다고 생각했습니다.그렇게 하는게 더 좋을 것 같습니다. uri 길이도 짧아지면서 깔끔해질 것 같습니다
(수정) 좀더 생각해봤는데 지금처럼 두는게 좋다고 생각합니다.
그 이유는ClubPosition내에서 변경 가능한 필드는name밖에 없어서,
여러 필드를 수정하지 않고name필드만 수정하기 때문에 지금처럼 uri 설계하고 매개변수에 positionId 를 두는 것이 적절하다고 생각했습니다.
| 동아리 회장 또는 매니저만 직책을 삭제할 수 있습니다. | ||
| PRESIDENT와 VICE_PRESIDENT 직책은 삭제할 수 없습니다. | ||
| 해당 직책을 사용 중인 회원이 없어야 하며, 해당 그룹에 최소 2개의 직책이 있어야 삭제 가능합니다. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
직책 삭제의 경우 회장, 부회장만 가능하도록 하는 것이 좋아 보여요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
알겠습니다 매니저는 직책 삭제 못하도록 하겠습니다!
| 동아리 회장 또는 매니저만 회원의 직책을 변경할 수 있습니다. | ||
| 자기 자신의 직책은 변경할 수 없으며, 상위 직급만 하위 직급의 회원을 관리할 수 있습니다. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
어차피 회장, 부회장은 직급과 이름이 고정되어 있기에 여기도 마찬가지로 회장, 부회장만 변경 가능하도록 해야할 것 같습니당.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
확인했습니다
| @Operation(summary = "동아리 회원을 강제 탈퇴시킨다.", description = """ | ||
| 동아리 회장 또는 매니저만 회원을 강제 탈퇴시킬 수 있습니다. | ||
| 자기 자신은 강제 탈퇴시킬 수 없으며, 회장은 강제 탈퇴시킬 수 없습니다. | ||
| 상위 직급만 하위 직급의 회원을 강제 탈퇴시킬 수 있습니다. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
굳이 상위, 하위 직급을 나눈다면 발생할 수 있는 케이스가 복잡해지니 일반 멤버에 대해서만 탈퇴를 시키는건 어떻게 생각하시나요?
만약 임원진이나 부회장을 탈퇴시켜야 한다면 회장의 권한으로 직급을 일반 멤버로 내린 뒤에 탈퇴하면 되니까 더 간단해질 것으로 보여요
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
알겠습니다
말씀해주신 대로 탈퇴는 일반 멤버에 대해서만 가능하도록 하겠습니다
| if (targetUserId.equals(requesterId)) { | ||
| throw CustomException.of(CANNOT_CHANGE_OWN_POSITION); | ||
| } | ||
|
|
||
| ClubMember requester = clubMemberRepository.findByClubIdAndUserId(clubId, requesterId) | ||
| .orElseThrow(() -> CustomException.of(NOT_FOUND_CLUB_MEMBER)); | ||
|
|
||
| ClubMember target = clubMemberRepository.findByClubIdAndUserId(clubId, targetUserId) | ||
| .orElseThrow(() -> CustomException.of(NOT_FOUND_CLUB_MEMBER)); | ||
|
|
||
| if (!requester.canManage(target)) { | ||
| throw CustomException.of(CANNOT_MANAGE_HIGHER_POSITION); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if문은 따로 private 메소드로 분리하는건 어떠세요?
repository에서 조회한 엔티티도 검증하는 로직을 getBy~~~처럼 인터페이스의 default 메소드를 만들어 활용하는건 어떠신가요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아 이거 전에도 말씀해 주셨던거 같은데 수정하도록 하겠습니다..
| ClubPosition.builder() | ||
| .name("회장") | ||
| .clubPositionGroup(PRESIDENT) | ||
| .club(savedClub) | ||
| .build(), | ||
| ClubPosition.builder() | ||
| .name("부회장") | ||
| .clubPositionGroup(VICE_PRESIDENT) | ||
| .club(savedClub) | ||
| .build(), | ||
| ClubPosition.builder() | ||
| .name("운영진") | ||
| .clubPositionGroup(MANAGER) | ||
| .club(savedClub) | ||
| .build(), | ||
| ClubPosition.builder() | ||
| .name("일반회원") | ||
| .clubPositionGroup(MEMBER) | ||
| .club(savedClub) | ||
| .build() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for-each? 였는지 기억은 잘 안나지만 enum에 있는 내용을 반복할 수 있는 방법이 있는 것으로 알고 있습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
아 그런가요? 조사해보고 수정하도록 하겠습니다!
동아리 내 권한 관리 기능 구현 완료했습니다.
'부회장' 권한(
ClubPositionGroup) 추가하였고,동아리 생성 시 '회장', '부회장', '운영진', '일반회원' 각각 한 개씩(
ClubPosition) 기본 생성되도록 하였습니다.또한 동아리 내 권한을 관리하거나, 동아리 내 회원 종류(
ClubPosition)를 새로 만들거나 변경할 수 있도록 하였습니다.동아리 권한 변경 관련하여 어떤 방식으로 구현했는지는 하단에 서술하도록 하겠습니다.
ClubPositionGroup종류ClubPosition관리 권한ClubPosition) 생성 가능positionGroup변경 불가ClubPosition수정/삭제 규칙ClubPosition은 그 이름을 변경할 수 있고, 삭제도 가능함. 단 삭제 시에는 특정 조건(그룹 내 인원이 없고, 삭제하고자 하는 그룹이 1개만 있는게 아닌 경우)을 만족해야함ClubPositionCRUD