Skip to content

refactor: sprint1 hardening#25

Merged
popeye0618 merged 10 commits into
mainfrom
refactor/sprint1-hardening
May 14, 2026
Merged

refactor: sprint1 hardening#25
popeye0618 merged 10 commits into
mainfrom
refactor/sprint1-hardening

Conversation

@popeye0618

@popeye0618 popeye0618 commented May 14, 2026

Copy link
Copy Markdown
Contributor

📌 작업 개요

여러 기술적 수정사항들 수정 및 테스트

🔗 관련 이슈

  • Closes #

✨ 변경 사항

🧪 테스트

  • 단위 테스트 추가/수정
  • 로컬에서 동작 확인

✅ 체크리스트

  • 브랜치명이 Git Flow 컨벤션을 따릅니다 (feature/, fix/, hotfix/ 등)
  • 커밋 메시지가 Conventional Commits 컨벤션을 따릅니다
  • 리뷰 가능한 단위로 작업을 분리했습니다
  • 관련 문서를 업데이트했습니다 (필요 시)

💬 리뷰어에게

@codex

- 회원 탈퇴 시 afterCommit 콜백으로 WithdrawalPolicy 적용 로직 추가
- 트랜잭션이 활성화되지 않은 경우 즉시 콜백 처리하도록 수정
- 테스트에 TransactionSynchronization 초기화 및 검증 로직 추가
- 회원 탈퇴 서비스 테스트에 tearDown 메서드로 트랜잭션 정리 코드 추가
- 탈퇴 시 트랜잭션 동기화가 없을 경우 즉시 후처리 동작 검증
- WithdrawalPolicy validate, apply 호출 및 Refresh Token 폐기 로직 검증
- 회원 상태 변경(MemberStatus.DELETED) 및 요청 컨텍스트 처리 확인
- RefreshTokenRepository에 PESSIMISTIC_WRITE 잠금 설정 및 테스트 케이스 작성
- 동시에 동일 RefreshToken 조회 시 대기 및 상태 갱신(ROTATED) 검증
- 트랜잭션 종료 후 다른 조회가 정상 동작하는지 확인
- 테스트 환경 설정에 flyway 비활성화 및 JPA ddl-auto=create-drop 추가
- EmailEncryptor 유틸 클래스와 EmailEncryptionConfig, Properties를 통해 암호화 키 설정
- 이메일 암호화 필드 추가(Member, UserSchoolVerification) 및 관련 엔티티 수정
- 이메일 암호화 저장(Signup) 및 복호화 처리(Query) 로직 추가
- 학교 이메일 인증 서비스에 암호화된 이메일 데이터 저장 로직 반영
- 테스트 코드 및 API 문서(MemberDocsTest) 수정 및 보완
- 이메일 인증 요청 시 UserSchoolVerification 상태가 PENDING인 항목 검증 로직 추가
- 상태 검증 실패 시 MemberErrorCode.SCHOOL_VERIFICATION_NOT_FOUND 예외 발생 처리
- SchoolEmailVerificationServiceTest에 관련 단위 테스트 추가
- 잘못된 학교 인증 요청 시 발생하는 예외 및 동작 검증 테스트 보완
- 학교 이메일 인증 메일 발송을 트랜잭션 커밋 이후로 지연 처리
- TransactionSynchronizationManager를 활용한 afterCommit 콜백 메서드 registerAfterCommit 추가
- SchoolEmailVerificationServiceTest에 이메일 발송 동작 검증 테스트 추가
- 테스트 정리(TearDown) 단계에서 트랜잭션 동기화 초기화 로직 추가
- 실패 시도 증가(failureRecorder.increaseAttempt) 로직을 검증 조건 내부로 이동
- 조건에 의한 의도치 않은 로직 실행 방지 위해 테스트 코드 수정
- 불필요한 Mock 및 verify 호출 제거로 테스트 단순화
- failureRecorder 및 tokenHasher 동작 검증 테스트 보완
@chatgpt-codex-connector

Copy link
Copy Markdown

요청하신 트리거/PR 정보를 확인했지만, 현재로서는 **구체적인 수정 요청(버그, 실패한 CI, 변경 지시 코멘트)**이 포함되어 있지 않아 적용할 코드 변경을 특정할 수 없었습니다.

제가 확인한 내용

  • <TRIGGER>: PR 템플릿 본문 + @codex 멘션
  • <PR_INFO>: 기존 PR 메타데이터(제목: refactor: sprint1 hardening)
  • <PR_COMMENT>: 추가 리뷰 코멘트/변경 요청 없음

따라서 이번 턴에서는 코드 수정, 커밋, 후속 PR 생성을 진행하지 않았습니다.

원하시면 다음 중 하나로 바로 진행할 수 있습니다:

  1. 코드 리뷰 모드: 현재 브랜치 변경분을 제가 직접 점검하고 개선 PR 제안
  2. CI 복구 모드: 실패 로그를 주시면 원인 분석 후 수정 커밋
  3. PR 본문 개선 모드: 현재 템플릿을 실제 작업 내용으로 정리해 드래프트 작성

View task →

@popeye0618

Copy link
Copy Markdown
Contributor Author

@codex 코드 리뷰 모드

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 704c338361

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +40 to +41
val email = request.email.trim().lowercase()
val emailHash = emailHasher.hash(email)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge 로그인과 같은 이메일 정규화를 적용하라

이번 커밋에서 회원가입은 request.email.trim().lowercase()로 해시를 만들도록 바뀌었지만, 로그인(AuthLoginService.login)은 여전히 원문 request.email을 그대로 해시합니다. 그 결과 사용자가 가입 시 Test@Unit.com처럼 대소문자/공백이 섞인 이메일을 입력하면 DB에는 정규화된 해시가 저장되고, 이후 같은 입력값으로 로그인할 때 해시가 달라져 INVALID_LOGIN_CREDENTIALS가 발생합니다. 가입과 로그인에서 동일한 정규화 규칙을 공유하도록 맞춰야 합니다.

Useful? React with 👍 / 👎.

Comment on lines +53 to +55
override fun afterCommit() {
action()
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge afterCommit 콜백 예외를 탈퇴 응답과 분리하라

withdrawalPolicies.applyafterCommit에서 그대로 실행하면, 콜백 내부 예외가 호출자까지 전파되는 동안 DB 커밋은 이미 완료되어 회원은 DELETED 상태인데 API는 실패(5xx)로 보일 수 있습니다. 이 커밋에서 후처리를 트랜잭션 밖으로 이동했기 때문에 새로 생긴 불일치이며, 클라이언트 재시도/운영 모니터링에서 "실패처럼 보이지만 실제로는 탈퇴 완료" 상태를 만듭니다. 콜백 예외를 별도 처리(try-catch + 로깅/비동기 재처리)해 커밋 결과와 응답 의미를 분리하는 편이 안전합니다.

Useful? React with 👍 / 👎.

- 로그인 요청 시 이메일 입력값의 공백 제거 및 소문자 변환 처리 추가
- 이메일 해시 생성 전 불필요한 대소문자 및 공백 문제 방지
- MemberRepository 조회 시 일관된 이메일 데이터 사용 보장
- WithdrawalPolicy 적용 로직을 applyWithdrawalPoliciesAfterCommit 메서드로 분리
- 후처리 중 예외 발생 시 memberId 및 정책명을 포함한 에러 로그 추가
- 로그 처리를 위해 MemberWithdrawalService에 LoggerFactory 추가
- MemberWithdrawalService에 회원 동의 철회 처리 로직 추가
- MemberConsent 엔티티에 withdraw 메서드 추가 및 withdrawnAt 저장 처리
- MemberConsentRepository에 findAllByMemberId 메서드 추가
- 회원 탈퇴 서비스 테스트(MemberWithdrawalServiceTest)에 동의 철회 검증 로직 추가
- 트랜잭션 동기화 없는 상황에서도 동의 철회 동작 검증 테스트 보완
@popeye0618

Copy link
Copy Markdown
Contributor Author

@codex 코드 리뷰 모드

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bd78f620d7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +28 to +29
val email = request.email.trim().lowercase()
val emailHash = emailHasher.hash(email)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge 기존 이메일 해시와 호환되게 로그인 조회를 유지하세요

여기서 이메일을 trim().lowercase()로 정규화한 뒤 해시를 조회하면, 이 커밋 이전에 대소문자 그대로 해시 저장된 회원(예: User@school.ac.kr)은 동일 주소로 로그인해도 항상 다른 해시가 되어 INVALID_LOGIN_CREDENTIALS로 실패합니다. 즉 배포 시점부터 일부 기존 계정이 즉시 로그인 불가 상태가 될 수 있으므로, 최소한 데이터 백필(backfill) 완료 전까지는 기존 해시 포맷도 함께 조회하거나, 마이그레이션을 선행해 해시 일관성을 맞춰야 합니다.

Useful? React with 👍 / 👎.

Comment on lines +40 to +41
val email = request.email.trim().lowercase()
val emailHash = emailHasher.hash(email)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge 이메일 중복 검사에 레거시 해시 호환 경로를 추가하세요

회원가입에서 이메일을 소문자 정규화해 해시를 만들기 시작했지만 기존 데이터는 비정규화 해시를 그대로 가지고 있어, 과거에 대문자로 가입된 주소와 동일한 메일박스가 새로운 소문자 해시로 중복 가입될 수 있습니다. 이 경우 existsByEmailHashAndDeletedAtIsNull가 false가 되어 동일 실사용 이메일에 대해 활성 계정이 2개 생길 수 있으므로, 정규화 전/후 해시를 모두 차단하거나 사전 마이그레이션으로 기존 해시를 통합해야 합니다.

Useful? React with 👍 / 👎.

@popeye0618
popeye0618 merged commit a0975c8 into main May 14, 2026
1 check passed
@popeye0618
popeye0618 deleted the refactor/sprint1-hardening branch May 14, 2026 04:17
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