Skip to content

[P9] 토너먼트 매치 로직 백엔드 이관 + 브래킷 무결성 서버 강제 #683

Description

@sevineleven

ROI · P9 · 대형 독립 작업 — 임팩트 높음(SSOT/무결성) / 노력 L(1 PR 다층)
매치 로직 백엔드 이관. 규모가 커 단독 PR·계획으로 마지막.


  • 매치 진행 로직(페어링·셔플·부전승·다음매치 계산)이 프론트에만 있고, 서버는 탈락 여부·소속·라운드만 검증한다. "누가 누구와 붙나"가 100% 프론트 신뢰라 서버가 브래킷 무결성을 보장하지 못한다 (SSOT 아님).
  • 셔플이 클라 랜덤이라 같은 토너먼트도 사용자마다 페어 순서가 다르고, 서버가 진행 순서를 추적·복원할 수 없다.
  • web·app·향후 플랫폼이 각자 알고리즘을 재구현해야 한다.

무엇을

서버가 tournament_histories 에서 매치를 파생해 내려주고, 프론트는 그리기만 한다. 스키마 변경 0 (전부 파생).

지금 프론트가 하는 일 이관 후 서버
페어 정하기 (가격순 정렬 + 인접) 서버가 페어 정해 currentMatch 로 내려줌
셔플 (매번 랜덤) 결정론 시드(tournamentUserId+round) — 새로고침해도 같은 페어
부전승 (홀수 시 마지막 아이템) 시드 랜덤(중립, 가격 편향 없음)으로 서버가 선정
다음 매치 계산 (낙관 remainingItems 조작) POST /matches 응답에 nextMatch (결승 아니어도)
라운드 끝 감지 후 refetch nextMatch 가 다음 라운드 첫 페어로 자동
준결승/결승 연출 판정 서버가 주는 currentRound 로 FE 파생 (<=4 준결승, ==2 결승)

새로 생기는 것 (이관의 핵심 가치)

  • 페어링 강제 검증 — POST 의 {first,second} 가 서버 지정 페어와 다르면 거부 (브래킷 무결성)
  • 멱등 처리 — 같은 매치 재시도 시 409 대신 멱등 성공 응답 (승자 다르면 거부)
  • transitionStage 필드는 신설 안 함currentRound 파생 중복이라 서버는 안 내려줌

결정 사항: 부전승 = 시드 랜덤(중립), 재시도 = 멱등 성공, 응답 = additive(remainingItems 유지, POST 만 래퍼로).

공수 (1 PR, 중간 규모, 마이그레이션 0)

작업 크기
파생 함수 신설 (RoundBracket: 정렬→페어→시드 부전승→시드 셔플→current/next) M (본체)
도메인 단위테스트 (부전승·홀수·타이·시드 재현) M
recordMatch (페어 검증 + 응답 확장 + 멱등) M
getTournamentById inProgress 배선 S
DTO (MatchPair + POST 응답 래퍼) S
컨트롤러 + *Api/*ApiExamples S~M
통합테스트 contract M

Metadata

Metadata

Assignees

Labels

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

Type

Fields

No fields configured for Task.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions