Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
import org.tuna.zoopzoop.backend.domain.member.dto.res.*;
import org.tuna.zoopzoop.backend.domain.member.entity.Member;
import org.tuna.zoopzoop.backend.domain.member.service.MemberService;
import org.tuna.zoopzoop.backend.domain.space.membership.service.MembershipService;
import org.tuna.zoopzoop.backend.domain.space.space.entity.Space;
import org.tuna.zoopzoop.backend.domain.space.space.service.SpaceService;
import org.tuna.zoopzoop.backend.global.rsData.RsData;
import org.tuna.zoopzoop.backend.global.security.jwt.CustomUserDetails;

Expand All @@ -27,6 +30,8 @@
public class ApiV1MemberController {
private final MemberService memberService;
private final RefreshTokenService refreshTokenService;
private final MembershipService membershipService;
private final SpaceService spaceService;
/// api/v1/member/me : 사용자 정보 조회 (GET)
/// api/v1/member/edit : 사용자 닉네임 수정 (PUT)
/// api/v1/member : 사용자 탈퇴 (DELETE)
Expand Down Expand Up @@ -147,6 +152,13 @@ public ResponseEntity<RsData<Void>> deleteMember(
@AuthenticationPrincipal CustomUserDetails userDetails
) {
Member member = userDetails.getMember();

// 사용자가 유일한 어드민인 모든 스페이스 삭제
List<Space> deletableSpaces = membershipService.findByOnlyAdmin(member);
for (Space space : deletableSpaces) {
spaceService.deleteSpace(space.getId());
}

refreshTokenService.deleteByMember(member);
memberService.hardDeleteMember(member);
return ResponseEntity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,5 @@ public interface MembershipRepository extends JpaRepository<Membership, Integer>
// 여러 Space에 속한 Member 목록 한번에 조회 (JOIN FETCH로 Member 정보까지)
@Query("SELECT m FROM Membership m JOIN FETCH m.member WHERE m.space IN :spaces AND m.authority <> org.tuna.zoopzoop.backend.domain.space.membership.enums.Authority.PENDING")
List<Membership> findAllMembersInSpaces(@Param("spaces") List<Space> spaces);

}
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,33 @@ public List<Membership> findByMember(Member member, String state) {
}
}

/**
* 멤버가 ADMIN 권한을 가진 스페이스 목록 조회
* @param member 조회할 멤버
* @return 멤버가 유일한 ADMIN 권한을 가진 스페이스 목록
*/
public List<Space> findByAdmin(Member member) {
return membershipRepository.findAllByMemberAndAuthorityOrderById(member, Authority.ADMIN)
.stream()
.map(Membership::getSpace)
.collect(Collectors.toList());
}
Comment on lines +101 to +106
Copy link

Copilot AI Oct 13, 2025

Choose a reason for hiding this comment

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

The Javadoc comment incorrectly describes this method as returning spaces where the member is the 'sole admin', but the implementation returns all spaces where the member has admin authority, regardless of other admins.

Copilot uses AI. Check for mistakes.

/**
* 멤버가 유일한 ADMIN 권한을 가진 스페이스 목록 조회
* @param member 조회할 멤버
* @return 멤버가 유일한 ADMIN 권한을 가진 스페이스 목록
*/
public List<Space> findByOnlyAdmin(Member member) {
// 1. 멤버가 ADMIN 권한을 가진 모든 스페이스 조회
List<Space> adminSpaces = findByAdmin(member);

// 2. 각 스페이스에서 ADMIN 멤버 수가 1명인 스페이스만 필터링
return adminSpaces.stream()
.filter(space -> membershipRepository.countBySpaceAndAuthority(space, Authority.ADMIN) == 1)
.collect(Collectors.toList());
Comment on lines +114 to +120
Copy link

Copilot AI Oct 13, 2025

Choose a reason for hiding this comment

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

This implementation makes a separate database query for each admin space to count admins. Consider using a single query with GROUP BY and HAVING clauses to improve performance when processing multiple spaces.

Suggested change
// 1. 멤버가 ADMIN 권한을 가진 모든 스페이스 조회
List<Space> adminSpaces = findByAdmin(member);
// 2. 각 스페이스에서 ADMIN 멤버 수가 1명인 스페이스만 필터링
return adminSpaces.stream()
.filter(space -> membershipRepository.countBySpaceAndAuthority(space, Authority.ADMIN) == 1)
.collect(Collectors.toList());
// Use a single query to find spaces where the member is the only ADMIN
return membershipRepository.findSpacesWhereMemberIsOnlyAdmin(member, Authority.ADMIN);

Copilot uses AI. Check for mistakes.
}

/**
* 스페이스에 속한 멤버 중 초대 상태(PENDING)인 멤버십 목록 조회
* @param space 조회할 스페이스
Expand Down