Skip to content

Feat: [FN-328] 그룹 권한 삭제#16

Merged
stoneTiger0912 merged 3 commits intomainfrom
feat/remove-down-permission
Mar 1, 2026
Merged

Feat: [FN-328] 그룹 권한 삭제#16
stoneTiger0912 merged 3 commits intomainfrom
feat/remove-down-permission

Conversation

@stoneTiger0912
Copy link
Member

@stoneTiger0912 stoneTiger0912 commented Mar 1, 2026

Summary by CodeRabbit

릴리스 노트

  • New Features

    • 그룹 권한 제거 기능이 추가되었습니다.
  • Refactor

    • 권한 관리 시스템이 개선되어 더 일관된 방식으로 권한 수정 작업을 처리할 수 있게 되었습니다.

@stoneTiger0912 stoneTiger0912 self-assigned this Mar 1, 2026
@coderabbitai
Copy link

coderabbitai bot commented Mar 1, 2026

Walkthrough

권한 제거 기능을 구현하기 위해 새로운 DELETE 엔드포인트를 추가하고 RemovePermissionUseCase와 RemovePermissionService를 도입합니다. AddPermissionCommand를 PermissionCommand로 일반화하여 기존 권한 추가 기능을 리팩터링하고, 필요한 DTO 및 Repository 메서드를 추가합니다.

Changes

Cohort / File(s) Summary
Permission 제거 기능 구현
src/main/java/flipnote/group/adapter/in/web/PermissionController.java, src/main/java/flipnote/group/application/service/RemovePermissionService.java
DELETE 엔드포인트 추가 및 권한 제거 로직 구현. 요청 사용자의 권한 확인, 권한 보유 여부 검증, 대상 권한 존재 여부 확인 후 제거.
Use Case 및 Port 레이어
src/main/java/flipnote/group/application/port/in/RemovePermissionUseCase.java, src/main/java/flipnote/group/application/port/out/GroupRoleRepositoryPort.java
RemovePermissionUseCase 인터페이스 신규 추가 및 GroupRoleRepositoryPort에 removePermission 메서드 추가.
DTO 및 Result 타입
src/main/java/flipnote/group/api/dto/request/RemovePermissionRequestDto.java, src/main/java/flipnote/group/api/dto/response/RemovePermissionResponseDto.java, src/main/java/flipnote/group/application/port/in/result/RemovePermissionResult.java
권한 제거 요청/응답 DTO 및 RemovePermissionResult 레코드 신규 추가.
Command 타입 일반화
src/main/java/flipnote/group/application/port/in/command/PermissionCommand.java, src/main/java/flipnote/group/application/port/in/AddPermissionUseCase.java, src/main/java/flipnote/group/application/service/AddPermissionService.java
AddPermissionCommand를 PermissionCommand로 이름 변경하여 권한 관련 작업 통일.
Persistence 계층
src/main/java/flipnote/group/adapter/out/persistence/GroupRoleRepositoryAdapter.java, src/main/java/flipnote/group/infrastructure/persistence/jpa/GroupRolePermissionRepository.java
GroupRoleRepositoryAdapter에 removePermission 메서드 추가 및 GroupRolePermissionRepository에 deleteByGroupRoleIdAndPermission 쿼리 메서드 추가.
기타 변경
src/main/java/flipnote/group/domain/model/member/GroupMemberRole.java, src/main/resources/application.yml
GroupMemberRole에서 isAtLeast 메서드 제거 및 로깅 설정을 flipnote.image에서 flipnote.group으로 변경.

Sequence Diagram

sequenceDiagram
    participant Client
    participant PermissionController
    participant RemovePermissionService
    participant GroupRoleRepositoryPort
    participant GroupRoleRepositoryAdapter
    
    Client->>PermissionController: DELETE /v1/groups/{groupId}/permissions
    PermissionController->>RemovePermissionService: removePermission(PermissionCommand)
    RemovePermissionService->>GroupRoleRepositoryPort: findRole(userId, groupId)
    GroupRoleRepositoryPort->>GroupRoleRepositoryAdapter: findRole(userId, groupId)
    GroupRoleRepositoryAdapter-->>GroupRoleRepositoryPort: GroupMemberRole
    GroupRoleRepositoryPort-->>RemovePermissionService: GroupMemberRole
    
    RemovePermissionService->>RemovePermissionService: 요청자 권한 > 변경 대상 권한 검증
    RemovePermissionService->>RemovePermissionService: 요청자 권한 보유 여부 확인
    RemovePermissionService->>RemovePermissionService: 변경 대상 권한 존재 여부 확인
    
    RemovePermissionService->>GroupRoleRepositoryPort: removePermission(groupId, role, permission)
    GroupRoleRepositoryPort->>GroupRoleRepositoryAdapter: removePermission(groupId, role, permission)
    GroupRoleRepositoryAdapter->>GroupRoleRepositoryAdapter: 권한 삭제 및 남은 권한 조회
    GroupRoleRepositoryAdapter-->>GroupRoleRepositoryPort: List<GroupPermission>
    GroupRoleRepositoryPort-->>RemovePermissionService: List<GroupPermission>
    
    RemovePermissionService-->>PermissionController: RemovePermissionResult
    PermissionController-->>Client: RemovePermissionResponseDto
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 권한을 정리하는 마법사의 손길,
삭제와 추가를 한 손으로 부려내네.
PermissionCommand라는 이름으로 통일하여,
깔끔한 흐름을 그려나간다.
역할의 계층을 꼼꼼히 확인하며,
안전한 권한 제거의 길을 닦네! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.53% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 그룹 권한 삭제 기능을 명확하게 설명하고 있으며, 변경 사항의 주요 내용과 완벽하게 일치합니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/remove-down-permission

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
src/main/resources/application.yml (1)

55-55: 기본 프로필 DEBUG 설정은 운영 리스크가 있습니다.

Line 55의 flipnote.group: DEBUG는 기본 설정에서 로그량 증가와 민감 정보 노출 가능성을 키웁니다. 기본은 INFO로 두고, 디버그는 로컬/개발 프로필로 분리하는 편이 안전합니다.

제안 변경안
 logging:
   level:
-    flipnote.group: DEBUG
+    flipnote.group: INFO
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/resources/application.yml` at line 55, 현재 기본 설정에 flipnote.group:
DEBUG로 되어 있어 운영 리스크가 있으니 기본 로그 레벨을 DEBUG에서 INFO로 변경하고, DEBUG 레벨은 개발 전용 프로파일로
분리하세요; 구체적으로 application.yml의 flipnote.group 값을 INFO로 바꾸고 개발용 설정(예:
application-dev.yml 또는 application.yml 내 spring.profiles: dev 블록)에
flipnote.group: DEBUG를 옮겨 로컬/개발 환경에서만 활성화되도록 하세요.
src/main/java/flipnote/group/adapter/in/web/PermissionController.java (1)

58-70: 삭제 엔드포인트의 응답 타입을 구체 DTO로 고정하세요.

ResponseEntity<?> 대신 ResponseEntity<RemovePermissionResponseDto>를 사용하면 API 계약이 명확해지고 타입 안정성이 좋아집니다.

🔧 제안 변경
- public ResponseEntity<?> changeDownPermission(
+ public ResponseEntity<RemovePermissionResponseDto> changeDownPermission(
     `@RequestHeader`("X-USER-ID") Long userId,
     `@PathVariable`("groupId") Long groupId,
     `@Valid` `@RequestBody` RemovePermissionRequestDto req) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/flipnote/group/adapter/in/web/PermissionController.java` around
lines 58 - 70, Update the controller method signature and return type to be
concrete: change changeDownPermission's return type from ResponseEntity<?> to
ResponseEntity<RemovePermissionResponseDto>, and ensure the method returns
ResponseEntity.ok(res) where res is the RemovePermissionResponseDto already
built; locate the changeDownPermission method and the
RemovePermissionResponseDto usage (and keep PermissionCommand and
removePermissionUseCase.removePermission(cmd) calls unchanged) so the method
signature, any annotations, and imports reflect
ResponseEntity<RemovePermissionResponseDto> for type safety.
src/main/java/flipnote/group/application/service/RemovePermissionService.java (1)

27-50: 권한 검증 규칙을 공통 컴포넌트로 추출하는 것을 권장합니다.

현재 검증 흐름이 AddPermissionService와 거의 동일하게 반복되어, 이후 정책 변경 시 한쪽만 수정되는 드리프트 위험이 있습니다. PermissionValidationPolicy(또는 Validator)로 추출해 add/remove에서 재사용하는 편이 안전합니다.

♻️ 리팩터링 예시
 public class RemovePermissionService implements RemovePermissionUseCase {
 
+  private final PermissionValidationPolicy permissionValidationPolicy;
   private final GroupRoleRepositoryPort groupRoleRepository;
 
   `@Override`
   `@Transactional`
   public RemovePermissionResult removePermission(PermissionCommand cmd) {
     GroupMemberRole role = groupRoleRepository.findRole(cmd.userId(), cmd.groupId());
-
-    if(!role.isHigherThan(cmd.changeRole())) {
-      throw new IllegalArgumentException("host lower than changeRole");
-    }
-
-    boolean existHostPermission = groupRoleRepository.checkPermission(cmd.userId(), cmd.groupId(), cmd.permission());
-    if(!existHostPermission) {
-      throw new IllegalArgumentException("host not exist permission");
-    }
-
-    boolean existPermission = groupRoleRepository.existPermission(cmd.changeRole(), cmd.groupId(), cmd.permission());
-    if(!existPermission) {
-      throw new IllegalArgumentException("role not exist permission");
-    }
+    permissionValidationPolicy.validateManagePermission(cmd, role);
 
     List<GroupPermission> groupPermissions = groupRoleRepository.removePermission(
       cmd.groupId(), cmd.changeRole(), cmd.permission()
     );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/main/java/flipnote/group/application/service/RemovePermissionService.java`
around lines 27 - 50, The permission validation logic duplicated between
RemovePermissionService.removePermission and AddPermissionService should be
extracted into a shared component (e.g., PermissionValidationPolicy or
PermissionValidator) to avoid drift; create a new class
(PermissionValidationPolicy) that encapsulates checks currently performed via
groupRoleRepository.findRole(...), role.isHigherThan(...),
groupRoleRepository.checkPermission(...), and
groupRoleRepository.existPermission(...), then replace the inline checks in
RemovePermissionService.removePermission (and mirror in AddPermissionService)
with calls to the new policy methods so both services reuse the same validation
flow.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@src/main/java/flipnote/group/adapter/out/persistence/GroupRoleRepositoryAdapter.java`:
- Around line 179-181: Update the thrown IllegalArgumentException in
GroupRoleRepositoryAdapter where roleEntity is fetched (the
findByGroupIdAndRole(...) orElseThrow) to use a message that reflects a missing
role (e.g., "role not found for group" or include groupId and role) instead of
"not exists member" so the error matches the failure in role lookup.

---

Nitpick comments:
In `@src/main/java/flipnote/group/adapter/in/web/PermissionController.java`:
- Around line 58-70: Update the controller method signature and return type to
be concrete: change changeDownPermission's return type from ResponseEntity<?> to
ResponseEntity<RemovePermissionResponseDto>, and ensure the method returns
ResponseEntity.ok(res) where res is the RemovePermissionResponseDto already
built; locate the changeDownPermission method and the
RemovePermissionResponseDto usage (and keep PermissionCommand and
removePermissionUseCase.removePermission(cmd) calls unchanged) so the method
signature, any annotations, and imports reflect
ResponseEntity<RemovePermissionResponseDto> for type safety.

In
`@src/main/java/flipnote/group/application/service/RemovePermissionService.java`:
- Around line 27-50: The permission validation logic duplicated between
RemovePermissionService.removePermission and AddPermissionService should be
extracted into a shared component (e.g., PermissionValidationPolicy or
PermissionValidator) to avoid drift; create a new class
(PermissionValidationPolicy) that encapsulates checks currently performed via
groupRoleRepository.findRole(...), role.isHigherThan(...),
groupRoleRepository.checkPermission(...), and
groupRoleRepository.existPermission(...), then replace the inline checks in
RemovePermissionService.removePermission (and mirror in AddPermissionService)
with calls to the new policy methods so both services reuse the same validation
flow.

In `@src/main/resources/application.yml`:
- Line 55: 현재 기본 설정에 flipnote.group: DEBUG로 되어 있어 운영 리스크가 있으니 기본 로그 레벨을 DEBUG에서
INFO로 변경하고, DEBUG 레벨은 개발 전용 프로파일로 분리하세요; 구체적으로 application.yml의 flipnote.group
값을 INFO로 바꾸고 개발용 설정(예: application-dev.yml 또는 application.yml 내 spring.profiles:
dev 블록)에 flipnote.group: DEBUG를 옮겨 로컬/개발 환경에서만 활성화되도록 하세요.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9a1c141 and 2391f55.

📒 Files selected for processing (14)
  • src/main/java/flipnote/group/adapter/in/web/PermissionController.java
  • src/main/java/flipnote/group/adapter/out/persistence/GroupRoleRepositoryAdapter.java
  • src/main/java/flipnote/group/api/dto/request/RemovePermissionRequestDto.java
  • src/main/java/flipnote/group/api/dto/response/RemovePermissionResponseDto.java
  • src/main/java/flipnote/group/application/port/in/AddPermissionUseCase.java
  • src/main/java/flipnote/group/application/port/in/RemovePermissionUseCase.java
  • src/main/java/flipnote/group/application/port/in/command/PermissionCommand.java
  • src/main/java/flipnote/group/application/port/in/result/RemovePermissionResult.java
  • src/main/java/flipnote/group/application/port/out/GroupRoleRepositoryPort.java
  • src/main/java/flipnote/group/application/service/AddPermissionService.java
  • src/main/java/flipnote/group/application/service/RemovePermissionService.java
  • src/main/java/flipnote/group/domain/model/member/GroupMemberRole.java
  • src/main/java/flipnote/group/infrastructure/persistence/jpa/GroupRolePermissionRepository.java
  • src/main/resources/application.yml
💤 Files with no reviewable changes (1)
  • src/main/java/flipnote/group/domain/model/member/GroupMemberRole.java

@stoneTiger0912 stoneTiger0912 merged commit fd65827 into main Mar 1, 2026
1 check passed
@stoneTiger0912 stoneTiger0912 deleted the feat/remove-down-permission branch March 1, 2026 11:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant