구현할 기능
서버가 플레이 링크 생성(POST /{id}/play-link)을 멱등하게 바꿨습니다 (core#980, core#985 머지 완료). 이제 상태와 무관하게 항상 200을 반환하므로, 클라의 방어 로직을 걷어내고 남아 있는 버그를 해소합니다.
| 호출 시점 상태 |
이전 |
이후 |
| 미생성 |
200 |
200 (동일) |
| 유효한 링크 있음 |
409 |
200 + 기존 만료시각 (연장 안 함) |
| 만료됨 |
409 (막다른 길) |
200 + 새 14일 |
| 주최자 탈퇴로 무효화 |
403 |
403 (유지) |
서버 배포로 "두 번째부터 공유가 안 되는" 증상 자체는 이미 사라졌습니다. 다만 클라에만 남은 버그가 하나 더 있습니다.
남은 버그 — 만료된 링크를 그대로 공유함
PlateShareDialog 의 가드가 값의 존재만 확인하고 시각을 비교하지 않습니다.
const hasExistingPlayLink = Boolean(initialPlayLinkExpiresAt);
14일이 지나 링크가 죽어도 컬럼에는 과거 시각이 남아 있어 true 가 됩니다. 클라는 POST 를 건너뛰고 죽은 링크를 그대로 공유하며, 주최자에게는 "링크를 성공적으로 공유했어요" 토스트까지 띄웁니다. 받은 사람만 만료 에러를 보고, 주최자는 자기 링크가 죽은 줄 모릅니다.
서버가 멱등해졌으므로 이제 가드를 없애고 항상 호출하면 이 문제가 함께 사라집니다. 미생성이면 생성, 만료면 갱신, 유효하면 기존 값을 그대로 받습니다.
작업 상세 내용
참고
TOURNAMENT-025 는 결번 처리되었습니다. 서버가 코드를 계약으로 보고 번호를 재사용하지 않기로 했으므로, packages/core/src/consts/errorCode.ts 의 엔트리는 지우지 말고 유지합니다.
- 대상 파일
apps/web/src/app/tournament/[id]/result/_components/plate-share-dialog/PlateShareDialog.tsx
apps/web/src/app/tournament/[id]/result/_hooks/usePostPlayLink.ts
- 서버는 이미 배포되었으므로 클라 단독 배포로 안전합니다. (반대 순서는 회귀 — 서버 PR의 "배포 순서" 참고)
구현할 기능
서버가 플레이 링크 생성(
POST /{id}/play-link)을 멱등하게 바꿨습니다 (core#980, core#985 머지 완료). 이제 상태와 무관하게 항상 200을 반환하므로, 클라의 방어 로직을 걷어내고 남아 있는 버그를 해소합니다.서버 배포로 "두 번째부터 공유가 안 되는" 증상 자체는 이미 사라졌습니다. 다만 클라에만 남은 버그가 하나 더 있습니다.
남은 버그 — 만료된 링크를 그대로 공유함
PlateShareDialog의 가드가 값의 존재만 확인하고 시각을 비교하지 않습니다.14일이 지나 링크가 죽어도 컬럼에는 과거 시각이 남아 있어
true가 됩니다. 클라는POST를 건너뛰고 죽은 링크를 그대로 공유하며, 주최자에게는 "링크를 성공적으로 공유했어요" 토스트까지 띄웁니다. 받은 사람만 만료 에러를 보고, 주최자는 자기 링크가 죽은 줄 모릅니다.서버가 멱등해졌으므로 이제 가드를 없애고 항상 호출하면 이 문제가 함께 사라집니다. 미생성이면 생성, 만료면 갱신, 유효하면 기존 값을 그대로 받습니다.
작업 상세 내용
hasExistingPlayLink가드 제거 — 항상postPlayLinkMutation()호출usePostPlayLink의 409 관련 주석 정리 (TOURNAMENT-025는 더 이상 발생하지 않음)POST성공 후 토너먼트 상세 쿼리 무효화 또는 응답의playLinkExpiresAt반영 — 같은 세션에서 재공유 시 상태가 낡지 않도록참고
TOURNAMENT-025는 결번 처리되었습니다. 서버가 코드를 계약으로 보고 번호를 재사용하지 않기로 했으므로,packages/core/src/consts/errorCode.ts의 엔트리는 지우지 말고 유지합니다.apps/web/src/app/tournament/[id]/result/_components/plate-share-dialog/PlateShareDialog.tsxapps/web/src/app/tournament/[id]/result/_hooks/usePostPlayLink.ts