Skip to content

feat: all user group/#691#709

Open
redjungi09 wants to merge 5 commits into
developfrom
feat/all-user-group/#691
Open

feat: all user group/#691#709
redjungi09 wants to merge 5 commits into
developfrom
feat/all-user-group/#691

Conversation

@redjungi09
Copy link
Copy Markdown
Collaborator

변경사항

  • GroupCategoryGLOBAL 카테고리 추가
  • 전체 유저 그룹(GLOBAL) 탈퇴·삭제·수정 차단 — GroupPolicyvalidateNotGlobal()canQuitGroup() 내 GLOBAL 체크 추가
  • 이메일 인증 완료 시 GLOBAL 그룹 자동 가입 처리 — VerifyEmailService에서 findByCategory(GLOBAL)addMember 호출
  • GroupJpaRepositoryfindByCategory, GroupPersistenceAdapteraddMember 메서드 추가
  • Flyway V42 마이그레이션: groups.fk_user_id nullable 전환, GLOBAL 그룹 레코드 삽입, 기존 ACTIVE 유저 전원 자동 가입

관련 이슈

Closes #691

추가 컨텍스트

  • GLOBAL 그룹은 오너가 없어 fk_user_idNULL이므로 기존 NOT NULL 제약 제거가 필요했습니다.
  • 이메일 인증 흐름에 그룹 가입 로직이 들어가면서 VerifyEmailServiceGroupRepositoryPort를 의존하게 됐는데, 도메인 경계 침범 여지가 있어 이벤트 방식으로 분리할 수도 있지만 우선 단순하게 직접 호출로 처리했습니다.

@redjungi09 redjungi09 changed the title Feat/all user group/#691 feat: all user group/#691 May 8, 2026
@redjungi09 redjungi09 changed the base branch from main to develop May 8, 2026 01:50
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request implements a 'GLOBAL' group category that automatically includes all active users. Changes include database migrations to support ownerless groups, automatic membership upon email verification, and policy constraints to protect the global group from deletion or modification. Feedback identifies a risk of NonUniqueResultException in the repository layer and recommends refactoring validation logic to ensure regular groups cannot be updated to the global category.

.orElseThrow(GroupNotFoundException::new);

int currentMemberCount = groupRepositoryPort.countMembers(command.groupId());
policy.validateNotGlobal(group);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

The current validation only prevents modifying an existing GLOBAL group. It is critical to also prevent regular groups from being updated to the GLOBAL category, as this would create unauthorized global groups with owners, potentially breaking system assumptions and security boundaries.

Suggested change
policy.validateNotGlobal(group);
policy.validateNotGlobal(group.category());
policy.validateNotGlobal(command.category());

Comment on lines +26 to +27
@EntityGraph(attributePaths = {"owner"})
Optional<GroupJpaEntity> findByCategory(GroupCategory category);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The findByCategory method returns an Optional, which implies that only one group can exist per category. While this is correct for the GLOBAL category, other categories like TEAM or CLUB typically have multiple groups. Calling this method with such categories will result in a NonUniqueResultException at runtime. Consider renaming this to findGlobalGroup() or changing the return type to List<GroupJpaEntity> to avoid unexpected crashes. Additionally, adding a unique constraint on the category column for the GLOBAL value in the database migration would further ensure data integrity.

Comment on lines +56 to +60
public void validateNotGlobal(Group group) {
if (group.category() == GroupCategory.GLOBAL) {
throw new GroupAccessDeniedException();
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Refactoring validateNotGlobal to accept a GroupCategory instead of a Group object makes the policy more versatile. This allows you to validate both the current state of a group and the intended state during an update (e.g., preventing a group from being changed to the GLOBAL category).

Suggested change
public void validateNotGlobal(Group group) {
if (group.category() == GroupCategory.GLOBAL) {
throw new GroupAccessDeniedException();
}
}
public void validateNotGlobal(GroupCategory category) {
if (category == GroupCategory.GLOBAL) {
throw new GroupAccessDeniedException();
}
}

Group group = groupRepositoryPort.findById(command.groupId())
.orElseThrow(GroupNotFoundException::new);

groupPolicy.validateNotGlobal(group);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Update the call to validateNotGlobal to pass the group's category, matching the suggested policy refactoring.

Suggested change
groupPolicy.validateNotGlobal(group);
groupPolicy.validateNotGlobal(group.category());

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.

[FEAT] 전체 유저 그룹 생성

1 participant