Skip to content

fix: 크루 가입 신청 승인/거부 후 자동 삭제 및 회원 탈퇴 외래 키 제약 조건 해결#148

Merged
leepg038292 merged 2 commits into
devfrom
fix/crew-join-request-cleanup
Nov 9, 2025
Merged

fix: 크루 가입 신청 승인/거부 후 자동 삭제 및 회원 탈퇴 외래 키 제약 조건 해결#148
leepg038292 merged 2 commits into
devfrom
fix/crew-join-request-cleanup

Conversation

@hskhsmm
Copy link
Copy Markdown
Member

@hskhsmm hskhsmm commented Nov 9, 2025

#️⃣ 연관 이슈

ex) #147


작업 목적

문제 1: 승인/거부된 가입 신청이 계속 남아있음

  • 이미 처리된 신청(APPROVED/REJECTED)이 DB에 계속 보관됨
  • 설계적으로 승인/거부 완료 = 더 이상 "신청"이 아님

문제 2: 회원 탈퇴 시 외래 키 제약 조건 에러

  1. MVP 참조 문제
    crew_statistics.mvp_user_id → users.user_id

  2. 가입 신청 처리자 참조 문제
    crew_join_requests.processed_by → users.user_id

→ User 삭제 시 500 에러 발생


📋 변경 사항

  1. CrewStatisticsRepository

// 회원 탈퇴 시 MVP 참조 해제 메서드 추가
@Modifying
@query("UPDATE CrewStatisticsEntity cs SET cs.mvpUser = null, cs.mvpDistance = null " +
"WHERE cs.mvpUser.id = :userId")
int clearMvpByUserId(@Param("userId") Long userId);

  1. UserService

// 회원 탈퇴 로직에 MVP 참조 해제 추가
int clearedMvpCount = crewStatisticsRepository.clearMvpByUserId(userId);

  1. CrewJoinServiceImpl - 승인 로직

// Before
joinRequest.approve(getUserEntity(user.getUserId()), "가입 승인");
joinRequestRepository.saveAndFlush(joinRequest); // APPROVED 상태 보관
CrewMemberEntity newMember = CrewMemberEntity.createMember(crew, joinRequest.getUser());
crewMemberRepository.save(newMember);

// After
CrewMemberEntity newMember = CrewMemberEntity.createMember(crew, joinRequest.getUser());
crewMemberRepository.save(newMember);
joinRequestRepository.delete(joinRequest); // ✂️ 승인 시 삭제

  1. CrewJoinServiceImpl - 거부 로직

// Before
joinRequest.reject(getUserEntity(user.getUserId()), reason); // REJECTED 상태 보관

// After
joinRequestRepository.delete(joinRequest); // ✂️ 거부 시 삭제


🔍 해결 방법

Before (문제 상황)

가입 신청 → 승인 → APPROVED 상태로 저장

crew_member 추가

processed_by 참조 유지 ⚠️

처리자 탈퇴 시 외래 키 에러!

After (해결)

가입 신청 → 승인 → join_request 삭제 ✂️

crew_member 추가

참조 없음 ✅

처리자 탈퇴 가능!


🎯 기대 효과

  1. 설계 개선
  • ✅ 승인/거부 완료 = "신청" 삭제 (의미적으로 올바름)
  • ✅ DB에는 PENDING 상태만 존재
  • ✅ 불필요한 히스토리 데이터 제거
  1. 외래 키 문제 해결
  • ✅ crew_statistics.mvp_user_id → NULL 처리
  • ✅ crew_join_requests.processed_by → 원천 차단 (레코드 자체 삭제)
  • ✅ 회원 탈퇴 정상 동작
  1. DB 용량 절약

-- Before
SELECT COUNT(*) FROM crew_join_requests; -- 수천 개 (모든 승인/거부 히스토리)

-- After
SELECT COUNT(*) FROM crew_join_requests; -- 수십 개 (PENDING만)


🧪 테스트

빌드 테스트

./gradlew clean build -x test

BUILD SUCCESSFUL in 16s

테스트 시나리오

  1. 가입 신청 승인

  2. 김철수가 크루 가입 신청

  3. 크루장이 승인

  4. ✅ crew_member 테이블에 김철수 추가

  5. ✅ crew_join_requests에서 신청 삭제됨

  6. 가입 신청 거부

  7. 김철수가 크루 가입 신청

  8. 크루장이 거부

  9. ✅ crew_member에 김철수 없음

  10. ✅ crew_join_requests에서 신청 삭제됨

  11. MVP였던 사용자 탈퇴

  12. 홍길동이 50km 뛰어서 MVP 달성

  13. 크루장 위임 후 탈퇴

  14. ✅ crew_statistics.mvp_user_id → NULL

  15. ✅ User 삭제 성공

  16. 승인했던 크루장 탈퇴

  17. 홍길동(크루장)이 김철수 가입 승인

  18. join_request 삭제됨 (승인 시)

  19. 홍길동이 크루장 위임 후 탈퇴

  20. ✅ 참조 없으므로 User 삭제 성공


📊 데이터베이스 영향도

기존 데이터 처리

  • 이미 APPROVED/REJECTED 상태인 레코드는 그대로 유지
  • 신규 승인/거부부터 자동 삭제 적용
  • 필요 시 기존 데이터 수동 정리 가능

SQL 쿼리 변경

-- 승인 시
-- Before: UPDATE crew_join_requests SET status='APPROVED', ...
-- After: DELETE FROM crew_join_requests WHERE id=?

-- 거부 시
-- Before: UPDATE crew_join_requests SET status='REJECTED', ...
-- After: DELETE FROM crew_join_requests WHERE id=?

-- 탈퇴 시 (추가)
UPDATE crew_statistics SET mvp_user_id=NULL WHERE mvp_user_id=?


🔗 관련 이슈

  • 회원 탈퇴 외래 키 제약 조건 에러 (#이슈번호)

⚠️ Breaking Changes

API 응답 변경 없음

  • 승인/거부 API 응답은 동일
  • 클라이언트 수정 불필요

데이터 변경

  • 승인/거부 히스토리가 DB에 남지 않음
  • 필요 시 추후 별도 히스토리 테이블 추가 가능

📝 추가 고려 사항

히스토리가 필요한 경우 (선택사항)

-- 추후 구현 가능
CREATE TABLE crew_join_history (
id BIGINT PRIMARY KEY,
crew_id BIGINT NOT NULL,
user_id BIGINT NOT NULL,
approved_by_nickname VARCHAR(20), -- FK 아닌 문자열로 저장
action VARCHAR(20), -- APPROVED/REJECTED
approved_at DATETIME,
reason VARCHAR(500)
);


✅ 체크리스트

  • CrewStatisticsRepository.clearMvpByUserId() 추가
  • UserService.deleteUser()에 MVP 참조 해제 추가
  • CrewJoinServiceImpl.approveJoinRequest() 수정 (삭제 로직)
  • CrewJoinServiceImpl.rejectJoinRequest() 수정 (삭제 로직)
  • 빌드 테스트 통과
  • 실제 환경에서 승인/거부 동작 확인
  • 회원 탈퇴 정상 동작 확인
  • API 문서 업데이트 (필요 시)

📸 스크린샷 (선택사항)

승인 전:
crew_join_requests
├── id: 123
├── status: PENDING
├── user_id: 456
└── processed_by: null

승인 후:
crew_join_requests
└── (레코드 삭제됨) ✂️

crew_member
├── id: 789
├── crew_id: 1
└── user_id: 456 ✅ 새로 추가


🚀 배포 전 확인사항

  1. ✅ 빌드 성공
  2. ⏳ 스테이징 환경 테스트
  3. ⏳ 가입 승인/거부 동작 확인
  4. ⏳ 회원 탈퇴 동작 확인
  5. ⏳ 프로덕션 배포

@hskhsmm hskhsmm requested a review from leepg038292 November 9, 2025 16:12
@hskhsmm hskhsmm self-assigned this Nov 9, 2025
@hskhsmm hskhsmm added the smin 홍성민이 관리하거나 작성한 이슈입니다 label Nov 9, 2025
@hskhsmm hskhsmm added the fix label Nov 9, 2025
Copy link
Copy Markdown
Contributor

@leepg038292 leepg038292 left a comment

Choose a reason for hiding this comment

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

외래 키 제약 조건 문제 해결 확인했습니다.

@leepg038292 leepg038292 merged commit 65d56a5 into dev Nov 9, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix smin 홍성민이 관리하거나 작성한 이슈입니다

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants