Skip to content

fix: 플레이 링크로 만든 토너먼트에서 불가능한 동작이 노출되는 문제 #602

Description

@kanghaeun

버그 내용

플레이 링크로 진입하면 CLONE 토너먼트가 생성되고 진입한 사용자가 그 CLONE의 주최자가 된다
(postFromPlayLink — "호출자가 새 토너먼트의 소유자가 되며").

그런데 프론트의 권한 판단이 전부 isOwner 기준이라 CLONE 주최자가 모든 조건을 통과한다.
서버는 CLONE에서 협업 기능을 닫아두고 있는데, 프론트는 이를 모른 채 진입점을 노출하고 사용자가 누른 뒤에야 에러로 거절된다.

동작 서버 현재 프론트
아이템 추가 TOURNAMENT-032 로 거절 + 버튼 노출
아이템 수정·삭제 거절 (전용 코드 없음, TOURNAMENT-001 로 추정) 수정·삭제 버튼 노출
플레이 링크 공유 TOURNAMENT-024 로 거절 isRoot 로 이미 숨김
친구 초대 초대 코드는 발급되나 이후 흐름 미지원 초대 배너 노출

특히 수정·삭제는 TOURNAMENT-001(TOURNAMENT_FORBIDDEN)로 내려오는 것으로 보이는데, 이 경우 tournament/[id]/layout.tsx 가 홈으로 리다이렉트해 모호한 안내와 함께 화면 밖으로 튕긴다.

응답에는 ROOT/CLONE을 구분하는 isRoot 가 이미 내려온다.
결과 화면은 이 값을 제대로 사용하고 있으나(ResultClient.tsx canSharePlayLink = isRoot && isOwner), 담기 화면·아이템 권한·초대 진입점에서는 isRoot 를 보지 않는다.

새 규칙을 만드는 게 아니라, 이미 있는 규칙을 빠뜨린 곳에 채우는 작업이다.

친구 초대를 숨기는 이유

CLONE에서 친구 초대는 미지원으로 확정되었다.

초대 코드가 발급되어 초대 자체는 가능하지만, 참여자가 합류한 뒤 CLONE 주최자가 시작하면 참여자는 후보 0개인 빈 담기 화면에 갇힌다 (아이템 추가도 TOURNAMENT-032 로 막혀 아무 동작도 불가).
또한 TOURNAMENT-031 로 CLONE에서는 그룹 결과 조회가 막혀 있어, 끝까지 진행하더라도 결과 비교라는 초대의 목적을 달성할 수 없다.

서버의 CLONE 제약이 모두 협업 기능을 닫는 방향(024/031/032)인 만큼, 초대만 열려 있던 것이 예외였다. 진입점을 숨겨 정책을 일치시킨다.

버그 재현 방법

  • Given: 완료된 토너먼트의 플레이 링크를 공유받는다
  • When: 링크로 진입해 생성된 담기 화면에서 아래를 시도한다
    • +버튼으로 상품 추가
    • 상품을 눌러 수정·삭제
    • 상단 "친구와 함께 담아보세요" 로 친구 초대
  • Then: 세 진입점 모두 정상 노출되지만, 추가·수정·삭제는 서버에서 거절되고
    초대는 성공하더라도 참여자가 진행 불가 상태에 빠진다

예상 결과

CLONE에서는 할 수 없는 동작의 진입점 자체가 노출되지 않아야 한다.

작업 상세 내용

  • isAddItemBlocked 에 CLONE 조건 추가 — !tournamentData.isRoot || ...
    (showAddButton 과 담기 다이얼로그 open 조건에 이미 연결되어 있어 함께 막힌다)
  • canEditTournamentItemif (!tournament.isRoot) return false; 추가
    → 상세 화면 readOnly(수정·삭제 버튼)와 item/[itemId]/layout.tsx 진입 가드에 동시 반영
  • TournamentItemBasket.tsx 의 인라인 조건(isOwner || item.userId === userData.id)을
    canEditTournamentItem 으로 교체 — 권한 조건이 두 곳에 중복 정의된 상태
  • CLONE 이면 ParticipantPanel(친구 초대 진입점) 숨김
  • CLONE 이고 후보가 0개인 경우 빈 담기 화면 대신 안내 노출
    (진입점을 모두 숨기면 아무것도 없는 백지가 되므로, 상태를 알 수 있어야 한다)
  • 기존 에러 처리(TOURNAMENT-032 토스트 등)는 유지.
    쿼리 액션(?action=OPEN_GET_ITEM_DIALOG)으로 다이얼로그가 직접 열릴 수 있고,
    캐시가 낡으면 요청이 나갈 수 있어 버튼 숨김은 예방이지 보증이 아니다

Activity

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

Metadata

Metadata

Assignees

Labels

fixSomething isn't working

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions