Skip to content

이미지 등록 v1(multipart) 경로 삭제 - #969

Open
m-a-king wants to merge 1 commit into
devfrom
refactor/967-remove-image-upload-v1
Open

이미지 등록 v1(multipart) 경로 삭제#969
m-a-king wants to merge 1 commit into
devfrom
refactor/967-remove-image-upload-v1

Conversation

@m-a-king

@m-a-king m-a-king commented Aug 23, 2026

Copy link
Copy Markdown
Collaborator

Situation

  • 이미지 등록에 두 경로가 공존했다. v1 은 서버가 multipart 로 바이트를 받아 S3 에 올리고, v2 는 presigned URL 을 발급해 클라가 직접 올린 뒤 확정한다.
  • v1 은 raw key 를 매 요청 새 UUID 로 만들어, 같은 요청이 두 번 도착하면(응답 유실 후 재시도 등) 그것이 재시도인지 새 등록인지 구분할 근거가 없었다. 결과로 위시가 하나 더 생기고 등록 한도도 이중 차감됐다. 위시는 지울 수 있어도 한도는 돌아오지 않는다.
  • v2 는 imageKey 가 그 요청의 자연 키라 claim 이 한쪽만 등록한다.

Task

  • v1 을 삭제해 경로를 하나로 줄인다.
  • 삭제 가능 시점을 추측이 아니라 실측으로 확정한다. 서버가 먼저 지우면 클라가 죽는다.

Action

  • 삭제 범위: 양쪽 도메인(위시·토너먼트)의 v1 핸들러, *Api 문서 블록, *ApiExamples 분기, 서비스·영속화 메서드, uploadRaw.
  • deleteRawsQuietly 도 함께 삭제했다. 작업 중 v1 전용이라 호출부가 통째로 사라진다는 것이 드러났다. v2 는 raw 를 클라가 올리므로 서버가 회수하지 않고, 매이지 못한 raw 는 폴링이 pending 매핑을 정리한 뒤 S3 lifecycle 이 만료시킨다.
  • 삭제 시점은 두 번 확인해 확정했다. 처음에는 prod 메트릭에서 v1 이 2일간 5회 호출되고 v2 는 0회라 보류했다. 클라 배포 후 nginx 접근 로그로 다시 봤을 때 v2 호출이 잡히고 v1 은 2026-08-20 15:19 UTC 를 마지막으로 끊겼다. 로그의 v1 호출이 전부 PIKI_APP UA 였는데, 앱이 react-native-webview 래퍼라 부르던 주체가 앱 안의 웹이었다. 웹 배포와 함께 넘어가므로 스토어 배포를 기다릴 필요가 없었다.

테스트

검증 처리 이유
다건(5장) 등록 후 각각 READY 전이 이관 v2 에 단건 전이만 있었다
여러 장이어도 이벤트 1회만 발행 이관 v2 에 없던 검증
CLONE 토너먼트면 403 이관 발급 단계에서 거부된다
정원 32개 초과 400 이관 정원 판정을 확정 단계가 쥐므로 confirm 에서 검증
정원 동시성 직렬화 이관 발급은 미리 끝내고 confirm 만 동시에 쏴 저장 시점 경합만 남김
이미지 파트 미전송 400 소멸 v2 는 JSON 이라 개념이 없다
빈 바이트 400 소멸 서버가 바이트를 받지 않는다. 내용·크기 검증은 #678 이 담당
거부 시 raw 를 올리지 않는다 소멸 서버가 raw 를 올리지 않는다
persist 실패 시 raw 즉시 회수 소멸 서버가 회수하지 않는다
  • 동시성 테스트의 raw 회수 단언 자리에는 "거부된 요청의 pending 매핑이 롤백으로 남는다" 를 넣었다. 그래야 폴링이 나중에 다시 집을 수 있어, v2 에서 같은 자리를 지키는 성질이다.
  • *Api 의 summary 에 있는 "v2" 표기는 유지했다. 경로와 클라 호칭이 그대로라 문서 이름만 바꾸면 참조가 흔들린다.

Result

  • 679줄 삭제(추가 199줄). 재시도가 실데이터를 남기는 창이 닫혔다.
  • 남은 재시도 손실은 한도 숫자뿐이다. URL 등록의 409 와 presign 재시도가 그렇고, 둘 다 별도 과제다.
  • 배포 후 v1 호출이 0 으로 유지되는지는 같은 방법(actuator 메트릭의 uri 라벨, nginx 접근 로그)으로 재확인할 수 있다.

연관 이슈

- 클라(웹)가 v2 로 전환을 마쳐 서버가 바이트를 받을 이유가 없어졌다. 앱은 react-native-webview 래퍼라 웹 배포와 함께 넘어가므로 스토어 배포를 기다리지 않는다
- 삭제 시점은 prod 실측으로 확정했다. 처음 확인 때는 v1 이 2일간 5회 호출되고 v2 는 0회라 보류했고, 클라 배포 후 재확인해 v2 호출과 v1 중단(마지막 2026-08-20 15:19 UTC)을 보고 진행했다
- v1 은 재시도마다 새 UUID raw key 를 만들어, 응답 유실 후 재시도가 중복 위시를 만들고 등록 한도도 이중 차감했다. v2 는 imageKey 가 요청의 자연 키라 claim 이 한쪽만 등록한다
- ImagePresignService.deleteRawsQuietly 도 함께 삭제했다. v1 전용이라 호출부가 통째로 사라졌고, v2 는 raw 를 클라가 올리므로 서버가 회수하지 않고 폴링·lifecycle 에 맡긴다
- v1 테스트 중 v2 에 없던 검증 5개(다건 READY 전이·이벤트 1회 발행·CLONE 403·정원 32 초과·정원 동시성)는 v2 경로로 이관했다
- multipart 전용 검증(파트 미전송·빈 바이트·raw 업로드와 회수)은 v2 에 개념이 없어 함께 소멸시켰다. 동시성 테스트의 raw 회수 단언 자리에는 거부된 요청의 pending 매핑이 롤백으로 남는지를 넣어 같은 성질을 지킨다
@m-a-king m-a-king added the refactor 구조 개선, 외부 동작 불변 label Aug 23, 2026
@m-a-king m-a-king self-assigned this Aug 23, 2026
@github-actions

Copy link
Copy Markdown

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

@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: c66fe4d2-fdac-4733-a6df-7295be1a26a9


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.

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.

이미지 등록 v1(multipart) 경로 삭제, v2 presign/confirm 으로 단일화

1 participant