feat(cafe24): 옵션값+품목 통합 목록, 드래그 순서, 옵션값 불러오기

- 옵션 1개 상품은 한 행에 썸네일·옵션값 이름·품목코드(복사)·자체코드·
  추가금액·진열·판매를 두고 「저장」 한 번으로 옵션 PUT → 품목 PUT.
- 옵션 없는 상품: 행 추가/삭제 후 저장 → 옵션 생성 → 카페24가 부여한
  품목코드를 재시도 조회(products.wait_for_variants)로 받아 자체코드·
  추가금액·썸네일까지 이어서 반영.
- 순서 드래그는 품목 display_order 로 저장(옵션값 재배열 PUT 은 위치 짝맞춤
  때문에 품목코드↔이름이 뒤바뀔 수 있어 사용하지 않음).
- 「옵션값 불러오기」: 탭/공백 구분 텍스트(이름·판매가·추가금액·자체코드)
  붙여넣기 → 행 자동 채움. 기존 옵션은 이름으로 짝지어 코드/금액만.
- 옵션 2개 이상(조합) 상품은 기존 2열 화면 유지.
- 모달 JS 를 app/static/cafe24-options.js 로 분리. 유닛테스트 90 통과,
  통합 하네스 통과, 헤드리스 크롬 렌더 확인.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-09-18 23:25:52 +09:00
parent be0d44ded6
commit 8125a59366
8 changed files with 1002 additions and 360 deletions
+27
View File
@@ -402,6 +402,33 @@ def list_variants(client: Cafe24Client, product_no: int) -> list[dict[str, Any]]
return variants if isinstance(variants, list) else []
def wait_for_variants(
client: Cafe24Client,
product_no: int,
expected: int,
*,
attempts: int = 4,
delay: float = 0.8,
) -> list[dict[str, Any]]:
"""옵션 생성 직후 카페24가 자동 생성한 품목이 조회될 때까지 짧게 재시도한다.
상세설명과 같은 읽기 지연이 품목 조회에도 있다 — POST options 직후 GET variants 가
비어 있거나 일부만 올 수 있다. 기대 개수(옵션값 수)만큼 오면 바로 돌려준다.
끝까지 못 채워도 마지막 결과를 돌려준다(호출부가 안내).
"""
latest: list[dict[str, Any]] = []
for attempt in range(max(1, attempts)):
if attempt:
time.sleep(delay)
try:
latest = list_variants(client, product_no)
except Exception: # noqa: BLE001 — 조회 실패는 다음 시도로
latest = []
if len(latest) >= max(1, expected):
return latest
return latest
def update_variants(
client: Cafe24Client, product_no: int, requests: list[dict[str, Any]]
) -> list[dict[str, Any]]: