Skip to content

토너먼트 CLONE 잔재 정리 (4-1단계) - #1191

Open
sevineleven wants to merge 1 commit into
devfrom
refactor/1188-clone-remnant-cleanup
Open

sevineleven wants to merge 1 commit into
devfrom
refactor/1188-clone-remnant-cleanup

Conversation

@sevineleven

@sevineleven sevineleven commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

Situation

#1188

  • 토너먼트 CLONE 잔재 정리 (4-1단계) #1188
  • 착수 후 드러난 것
    • 에러 코드 024 · 029 · 031 은 서비스에서 던지는 곳 0곳. API 문서 예시에만 남아 실제로 안 나는 응답을 계약처럼 안내
    • API 설명 여러 곳이 CLONE 시절 기준. 플레이 링크 입장이 "복제 토너먼트 생성", 참여는 "PENDING 에서만" 으로 서술
    • 옛 클론 id 요청이 아직 오는지 측정값 없음

팀 질문: tournament_users 유지 여부

  • 토너먼트 개선 때 tournament_users 를 유지할지 없앨지 질문
  • 방장 · 히스토리를 참여 행 id 대신 user_id 로 가리키면 어떤지 질문
    • 원인: 근거가 코드 · 문서 어디에도 정리되지 않음

Task

#1188

Action

도달할 수 없는 코드 제거

대상 근거
에러 코드 024 · 029 · 031 던지는 곳 0곳. enum · 예외 팩토리 · 문서 예시 제거, 번호는 결번
findBySourceTournamentId 호출 0곳
아이템 조회의 sourceTournamentId ?: 분기 호출부 5곳 모두 ROOT 로 해소한 뒤 호출. 항상 같은 쪽으로만 흐름

잔재 클론 id 관측 카운터 추가

  • 메트릭 tournament.clone_redirect 추가
kind 오르는 때
resolved 옛 클론 id 요청을 shim 이 ROOT 로 해소해 정상 응답
item_guard 옛 클론 id 의 아이템 추가 · 수정 · 삭제가 클론 가드(032 · 038)에 막힘
  • ROOT id 정상 요청은 세지 않음
    • 원인: 정상 요청까지 세면 0 으로 내려올 수 없어 4-2 착수 판단에 못 씀
  • 가드 5곳의 클론 판정을 헬퍼 하나로 묶음
선택지 장점 비용
메트릭 카운터 (채택) 빈도 · 추세를 바로 봄. 0 유지 여부가 한눈에 보임 요청 단위 상세 없음
매 요청 로그 어느 클론 id 인지까지 보임 빈도를 보려면 로그 집계 필요
관측 없이 4-2 바로 진행 PR 하나 줄어듦 옛 클론 주소 사용자가 404 를 받는지 모른 채 제거

API 문서 · 주석을 현재 동작으로 정정

대상 이전 이후
단건 조회 isRoot 원본 true · 사본 false deprecated. 항상 true
단건 조회 sourceTournamentId 사본이면 원본 id deprecated. 항상 생략
플레이 링크 입장 원본을 복제한 새 토너먼트 생성 원본에 참여 행 추가, 원본 id 반환
목록 playType 참여는 PENDING 에서만 플레이 링크(COMPLETED)로도 참여
완료 이벤트 주석 클론일 때 발행 주최자 참여 행인지로 발행
  • 지금은 나올 수 없는 응답 예시(isRoot=false CLONE 진행 중)를 참여자 예시로 교체
  • 응답 필드 자체는 유지
    • 원인: 클라 계약

tournament_users 를 유지하는 이유

  • 한 사람이 한 토너먼트에서 하는 한 판의 상태(진행 단계 · 완료 시각 · 참여 닉네임)를 담을 자리가 필요함
  • 그 자리 후보 비교
자리 한 사람의 판을 담을 수 있나 결과
tournament_users 참여 행 (채택) 가능. (토너먼트, 사람)마다 한 줄 토너먼트 하나에 사람마다 한 줄
tournaments.status 불가. 토너먼트당 칸 하나 사람마다 토너먼트 복사. 이것이 CLONE 의 기원
users 테이블 컬럼 불가. 한 사람이 여러 토너먼트에 참여 토너먼트마다 칸이 필요해 결국 매핑 테이블
히스토리에서 매번 파생 일부만. 완료 여부는 셀 수 있음 참여만 하고 안 고른 사람 · 닉네임은 표현 불가

User 도메인을 직접 쓰지 않는 이유

축 참여 행으로 감쌈 (현행) User 를 직접 씀
표시명 참여 닉네임 스냅샷(#1018). 프로필 수정과 분리 프로필 닉네임과 묶여 토너먼트별 이름 불가
탈퇴 참여 행 · 기록이 그대로 남고 결과에 탈퇴 표시(isWithdrawn)만 붙음 User 상태 변화가 토너먼트 결과 조회까지 번짐
게스트 승계(#1081) 참여 행의 user 칸만 교체 토너먼트 테이블 여러 곳의 user 식별자 교체
경계 User 와의 접점이 참여 행의 user_id 하나 토너먼트 도메인이 User 내부에 직접 의존
  • User 는 표시용 프로필 이미지 · 폴백 닉네임 조회와 회원 게이트에만 사용
  • 엔티티 연관관계(@ManyToOne) 없이 raw id 로만 연결하는 팀 스키마 원칙과도 같은 방향

방장 · 히스토리를 참여 행 id 로 가리키는 이유

상황 참여 행 id (현행) user_id 로 바꾸면
게스트가 회원으로 로그인(#1081) 참여 행 user 칸 하나만 교체. 방장 · 기록은 행 id 를 따라 유지 방장 · 기록 전부 재작성. FK 없음이라 누락을 DB 가 못 막음
같은 방에 회원 계정도 있음 게스트 행만 접음. 두 시절 기록이 각 행에 따로 남음 두 시절 기록이 한 user_id 로 섞임
진행 중 대진표 seed 가 seedOf(참여 행 id, 라운드) 라 순서 유지 seed 가 바뀌어 진행 중 대진 순서가 다시 섞임
  • 예외: tournament_items.user_id 는 "아이템을 담은 사람" 이라 user_id 유지
    • 비용: 게스트 승계 때 아이템만 따로 이관
  • 이 근거를 TournamentUser 상단 주석에 기록
  • 참조: 시각 자료 (클론에서 참여 행으로)

Result

응답 변화 없음

  • shim · 032 · 038 가드 그대로 동작
  • 옛 클론 id 요청은 응답 그대로, 카운터만 오름

확인 방법

  • 잔재 클론 id 단건 조회: ROOT 로 해소해 200, resolved +1
  • ROOT id 단건 조회: 카운터 그대로
    • 정상 요청을 세지 않는다는 판단이 실제로 지켜지는지 확인하는 대조군
  • 잔재 클론 id 아이템 삭제: 403 TOURNAMENT-038 유지, item_guard +1, 원본 아이템 보존

후속


연관 이슈

Summary by CodeRabbit

  • 변경 사항
    • 플레이 링크로 참여하면 복제 토너먼트가 아닌 원본 토너먼트에 참가합니다. 이미 참여한 경우 기존 참여를 이어가며, 동일한 토너먼트 ID를 반환합니다.
    • 플레이 링크 참여자도 해당 토너먼트에서 결과 확인과 플레이를 할 수 있습니다.
    • 기존 복제 토너먼트 ID로 조회하면 원본 토너먼트로 연결됩니다. 단, 해당 ID를 통한 아이템 수정은 계속 제한됩니다.

- 도달 불가 에러 코드 024 · 029 · 031 제거
  - 번호는 결번 유지
  - 원인: 던지는 곳 0곳. API 문서 예시에만 남음
- findBySourceTournamentId 제거
  - 원인: 호출 0곳
- 토너먼트 아이템 조회의 클론 분기 제거
  - 원인: 호출부 5곳 모두 ROOT 로 해소한 뒤 호출
- 잔재 클론 id 관측 카운터 추가 (tournament.clone_redirect)
  - kind=resolved: 리다이렉트 shim 이 ROOT 로 해소
  - kind=item_guard: 아이템 쓰기 클론 가드에 막힘
  - 원인: 4-2단계 shim · 가드 제거 판단 근거
- API 문서 · 주석을 CLONE 제거 이후 모델로 갱신
  - isRoot · sourceTournamentId 는 deprecated 표기. 응답은 그대로 유지
- 방장 · 히스토리를 참여 행 id 로 가리키는 이유를 TournamentUser 주석에 기록
@sevineleven sevineleven added the refactor 구조 개선, 외부 동작 불변 label Oct 12, 2026
@sevineleven sevineleven linked an issue Oct 12, 2026 that may be closed by this pull request
@sevineleven sevineleven self-assigned this Oct 12, 2026
@github-actions

Copy link
Copy Markdown

Discord 스레드 연동용 메타데이터입니다. discord-pr-bot 워크플로가 자동 생성하며, 수정·삭제하면 PR 과 Discord 알림 연동이 끊깁니다.

@coderabbitai

coderabbitai Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: TeamPiKi/core/.coderabbit.yml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c1a3bb34-4076-4e0a-befd-388940b4841f

📥 Commits

Reviewing files that changed from the base of the PR and between f71aad2 and ea09197.


📒 Files selected for processing (20)
  • src/main/kotlin/com/depromeet/piki/tournament/controller/TournamentApi.kt
  • src/main/kotlin/com/depromeet/piki/tournament/controller/TournamentApiExamples.kt
  • src/main/kotlin/com/depromeet/piki/tournament/controller/TournamentController.kt
  • src/main/kotlin/com/depromeet/piki/tournament/controller/dto/TournamentDetailResponse.kt
  • src/main/kotlin/com/depromeet/piki/tournament/domain/Tournament.kt
  • src/main/kotlin/com/depromeet/piki/tournament/domain/TournamentPlayType.kt
  • src/main/kotlin/com/depromeet/piki/tournament/domain/TournamentUser.kt
  • src/main/kotlin/com/depromeet/piki/tournament/event/TournamentCompleted.kt
  • src/main/kotlin/com/depromeet/piki/tournament/event/TournamentPlayedFromLink.kt
  • src/main/kotlin/com/depromeet/piki/tournament/event/TournamentResultReady.kt
  • src/main/kotlin/com/depromeet/piki/tournament/repository/TournamentJpaRepository.kt
  • src/main/kotlin/com/depromeet/piki/tournament/repository/TournamentRepository.kt
  • src/main/kotlin/com/depromeet/piki/tournament/repository/TournamentRepositoryImpl.kt
  • src/main/kotlin/com/depromeet/piki/tournament/service/CloneRedirectMetrics.kt
  • src/main/kotlin/com/depromeet/piki/tournament/service/TournamentErrorCode.kt
  • src/main/kotlin/com/depromeet/piki/tournament/service/TournamentException.kt
  • src/main/kotlin/com/depromeet/piki/tournament/service/TournamentItemPersistenceService.kt
  • src/main/kotlin/com/depromeet/piki/tournament/service/TournamentService.kt
  • src/main/kotlin/com/depromeet/piki/tournament/service/dto/TournamentDetail.kt
  • src/test/kotlin/com/depromeet/piki/tournament/controller/TournamentIntegrationTest.kt

💤 Files with no reviewable changes (4)
  • src/main/kotlin/com/depromeet/piki/tournament/repository/TournamentJpaRepository.kt
  • src/main/kotlin/com/depromeet/piki/tournament/repository/TournamentRepositoryImpl.kt
  • src/main/kotlin/com/depromeet/piki/tournament/repository/TournamentRepository.kt
  • src/main/kotlin/com/depromeet/piki/tournament/service/TournamentException.kt

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.



Walkthrough

이 변경은 토너먼트 참여자 기준으로 API 설명과 도메인 주석을 수정합니다. 잔재 CLONE ID 해소와 아이템 가드의 계측을 추가하고, CLONE 전용 조회 메서드와 오류 정의를 제거합니다.

Changes

토너먼트 CLONE 잔재 정리

Layer / File(s) Summary
참여자 중심 계약과 설명 정리
src/main/kotlin/com/depromeet/piki/tournament/controller/TournamentApi.kt, src/main/kotlin/com/depromeet/piki/tournament/controller/TournamentApiExamples.kt, src/main/kotlin/com/depromeet/piki/tournament/controller/TournamentController.kt, src/main/kotlin/com/depromeet/piki/tournament/controller/dto/TournamentDetailResponse.kt, src/main/kotlin/com/depromeet/piki/tournament/domain/*, src/main/kotlin/com/depromeet/piki/tournament/event/*, src/main/kotlin/com/depromeet/piki/tournament/service/dto/TournamentDetail.kt
문서와 주석은 플레이 링크 참여자도 같은 토너먼트의 참여자로 설명합니다. isRoot는 항상 true이고 sourceTournamentId는 null이라는 설명을 추가했습니다. 도메인 참여 행 ID와 참여자별 진행·완료 조건도 설명을 갱신했습니다.
잔재 ID 해소와 아이템 가드 계측
src/main/kotlin/com/depromeet/piki/tournament/service/CloneRedirectMetrics.kt, src/main/kotlin/com/depromeet/piki/tournament/service/TournamentService.kt, src/main/kotlin/com/depromeet/piki/tournament/service/TournamentItemPersistenceService.kt, src/test/kotlin/com/depromeet/piki/tournament/controller/TournamentIntegrationTest.kt
CLONE ID를 해소하거나 아이템 가드가 요청을 차단할 때 카운터를 기록합니다. 통합 테스트는 카운터 증가, 기존 403 응답, ROOT 아이템 보존을 확인합니다.
CLONE 전용 조회와 오류 코드 정리
src/main/kotlin/com/depromeet/piki/tournament/repository/*, src/main/kotlin/com/depromeet/piki/tournament/service/TournamentErrorCode.kt, src/main/kotlin/com/depromeet/piki/tournament/service/TournamentException.kt, src/main/kotlin/com/depromeet/piki/tournament/service/TournamentService.kt
아이템 조회는 전달된 토너먼트 ID를 사용합니다. 원본 ID 기준 조회 메서드와 CLONE 전용 오류 코드 및 예외 생성 메서드를 제거했습니다.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

연계 이슈 검토

Objective Addressed Explanation
[#1188] 에러 코드 024·029·031 및 관련 예시·예외 생성 메서드 제거, 번호 결번 유지 ✅
[#1188] findBySourceTournamentId와 아이템 조회의 CLONE 분기 제거 ✅
[#1188] 잔재 CLONE ID 해소와 CLONE 아이템 가드 계측 추가 ✅
[#1188] API 설명·주석 갱신, 참여 행 ID 사용 근거 기록. 응답 필드와 리다이렉트·가드 유지 ✅

Merge Risk: ⚪ Minimal · up to ea091

The clone cleanup and new counters have no established merge-blocking issue. Confirm downstream metric scraping during rollout.

Pre-merge checks | Passed 1 | Failed 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 43.75% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 48 functions across 16 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR


🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

refactor 구조 개선, 외부 동작 불변

Projects

None yet

Development

Successfully merging this pull request may close these issues.

토너먼트 CLONE 잔재 정리 (4-1단계)

1 participant