Skip to content

추출 부분값을 200 으로 반환하고 크롭 불가 포맷의 위장 업로드를 고친다 - #37

Merged
m-a-king merged 1 commit into
mainfrom
feat/35-partial-extraction-and-image-format
Aug 15, 2026
Merged

추출 부분값을 200 으로 반환하고 크롭 불가 포맷의 위장 업로드를 고친다#37
m-a-king merged 1 commit into
mainfrom
feat/35-partial-extraction-and-image-format

Conversation

@m-a-king

Copy link
Copy Markdown
Collaborator

Situation

Task

  • 값이 하나라도 있으면 성공으로 내려보낸다. 다만 하나도 못 건졌으면 여전히 실패로 닫아야 한다. 사용자에게 "무엇을 채우라" 할 근거조차 없기 때문이다.
  • 크롭할 수 없는 포맷을 png 로 위장해 올리는 문제를 고친다.
  • 부분값은 성공 응답이라 실패 코드가 남지 않는다. 어느 필드를 못 채웠는지 관측할 자리를 만든다.

Action

응답 계약

추출 결과
세 필드 전부 200 200 (그대로)
일부만 채움 422 UNTRUSTWORTHY_VALUE 200 (채운 값 그대로)
하나도 못 채움 422 UNTRUSTWORTHY_VALUE 422 (그대로)
  • 응답 필드는 원래 nullable 이라 스키마 변경이 없다. 달라지는 것은 "언제 실패로 닫는가" 하나다.
  • 에스컬레이션 판정은 건드리지 않았다. 부분값일 때 헤드리스 브라우저로 한 번 더 시도하는 것은 여전히 옳다. 이번 변경으로 달라지는 건 "그래도 부분값이면 어떻게 끝내는가" 뿐이라, 승격 조건과 종결 조건을 분리해 두었다.
  • currency 는 원래 READY 필수가 아니라, 단독으로 남아도 "건졌다" 의 근거로 세지 않는다.

크롭 불가 포맷의 위장 업로드

ImageCropperImageIO 로 디코딩하는데 png·jpeg 만 지원해 나머지는 크롭을 건너뛴다(의도된 fallback). 그런데 업로드는 항상 .png · image/png 로 하드코딩돼 있었다.

크롭 업로드 바이트
성공 PNG 인코딩 결과 .png / image/png 그대로
건너뜀 원본 그대로 .png / image/png (위장) 원본 확장자 / 원본 content-type
  • 등록이 허용하는 5개 포맷(png·jpeg·webp·heic·heif) 중 셋이 이 경로를 탄다. 아이폰 사용자가 원본 포맷으로 올리는 흔한 경로다.
  • 관측 범위(prod 30일 18건)에서 HEIC 은 1건뿐이었지만, 그건 표본이 작아서지 안전해서가 아니다.

관측

  • 부분값으로 내려보낼 때 못 채운 필드 이름을 로그에 남긴다. 성공 응답이라 code 가 안 남아, 이게 없으면 이름이 없었는지 가격이 없었는지 사후 판별이 불가능하다.
  • 업로드 로그에 크롭 여부를 더한다. croppedUrl 이라는 필드명과 달리 크롭을 건너뛴 경우가 섞여 있어, 원본이 그대로 올라간 비율을 알 수 없었다.

Result

  • 검증에서 비자명한 부분: 위장 업로드는 바이트만 봐서는 잡히지 않아, stub 이 key 와 content-type 도 기록하게 하고 크롭 성공(png) 케이스와 크롭 불가(heic) 케이스를 짝으로 고정했다. 크롭 성공 쪽 단언이 대조군 역할을 한다.
  • 배포 순서 주의: core 가 먼저다. 이 변경이 먼저 나가면 core 가 부분값을 READY 불변식 위반으로 받아 FAILED 로 떨어뜨린다. core PR(추출 부분값을 INCOMPLETE 로 수용하고 유저 입력으로 완성한다 core#945)이 머지·배포된 뒤에 이 PR 을 배포해야 한다.
  • 후속: 계약 정본(infra contracts/extraction-api.md)이 아직 "세 필드 non-null 을 Extractor 가 보장한다, 못 채우면 422" 로 되어 있어 별도 PR 로 고쳐야 한다.

연관 이슈

- 응답 경계가 세 필드(name·imageUrl·currentPrice) 중 하나라도 비면 422 로 닫아 채운 값까지 함께 버렸다. prod 30일 이미지 추출 18건 중 16건이 이 게이트에 걸렸는데, 사진에 가격이 박혀 있지 않은 것은 정상 입력이라 그 계약은 사실상 "쇼핑몰 화면 캡처"만 통과시켰다
- 값이 하나라도 있으면 200 으로 내려보내고, 하나도 못 건졌을 때만 UNTRUSTWORTHY_VALUE 로 닫는다. 호출자가 부분값을 INCOMPLETE 로 받아 사용자가 나머지를 채운다 (TeamPiKi/core#944)
- 에스컬레이션 판정(missingReadyField)은 그대로 뒀다 — 부분값일 때 헤드리스로 한 번 더 시도하는 것은 여전히 옳고, 달라지는 건 "그래도 부분값이면 어떻게 끝내는가" 뿐이다
- 크롭 불가 포맷(HEIC·WebP·HEIF 는 ImageIO 에 디코더가 없다)의 원본을 .png · image/png 로 올리던 버그를 함께 고친다. prod 에 확장자·content-type 은 png 인데 바이트는 HEIC 인 객체가 실제로 있었고, 브라우저 대부분이 그 파일을 렌더링하지 못한다. 등록 허용 5개 포맷 중 셋이 이 경로를 탄다
- 부분값은 성공 응답이라 code 가 남지 않아 어느 필드가 비었는지 사후 판별이 불가능하다 — missing 을 로그로 남긴다
- 크롭 여부(cropped)도 로그에 더한다. croppedUrl 이라는 이름과 달리 크롭을 건너뛴 경우가 섞여 있어, 원본이 그대로 올라간 비율을 알 수 없었다
@m-a-king m-a-king added the feat 외부 가시적 새 기능 label Aug 15, 2026
@m-a-king m-a-king self-assigned this Aug 15, 2026
@coderabbitai

coderabbitai Bot commented Aug 15, 2026

Copy link
Copy Markdown

Important

Review available on request

  • 🔍 Trigger review

Reviews should be triggered manually for repositories with fewer than 10 stars. Select Trigger review above or comment @coderabbitai review to review the latest changes. For a full review, comment @coderabbitai full review.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9a360098-f1e1-4779-9397-1d69496413a9


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

feat 외부 가시적 새 기능

Projects

None yet

Development

Successfully merging this pull request may close these issues.

추출 결과가 불완전해도 채운 만큼 반환하고 크롭 불가 포맷의 위장 업로드를 고친다

1 participant