feat(cafe24): 읽기 지연 보정("마지막 쓰기가 권위") + 상품 정보 패널

증상: 상세페이지를 적용해도 편집기에 수정 전 소스가 보이고 한참 뒤에야
반영됨. 원인은 우리 캐시가 아니라(전부 no-store) 카페24 관리자 API 가 PUT
뒤 한동안 GET 에서 예전 값을 돌려주는 읽기 지연. 예전 코드는 2.4초만
기다린 뒤 GET 값을 그대로 믿어 예전 소스 표시·지문 충돌 오판·예전 값
백업이 생겼다.

- 상세설명: 쓰기 성공 시 MANUAL/SCHEDULED revision 을 기준으로, 카페24 값이
  유예시간 안의 revision 중 하나와 같으면 지연(pending)으로 보고 마지막
  쓰기를 표시·지문 기준으로 쓴다. 모르는 값이면 외부 변경(external).
  store.resolve_description / db.revision_digests(md5) / 배너 2종.
- 적용(apply)은 유효 현재값으로 BACKUP·지문 대조·변경없음 판정. 재조회
  확인 결과는 감사로그에만 남긴다.
- 스칼라(상품명·가격·이미지·진열/판매): PUT 응답을 cafe24_products.
  last_write_snapshot(JSONB, 마이그레이션 004)에 남기고 GET 의 updated_date
  가 그보다 이전이면 스냅샷으로 덮어씀. 옵션/품목도 섹션별 스냅샷.
- 3분할 화면: 목록 | 편집기 | 상품 정보 패널(_side.html, /pane 이 두 조각을
  한 응답으로). routes_product_info.py JSON API — 상품명/판매가/공급가/
  소비자가, 대표이미지 업로드(POST /admin/products/images → PUT detail_image
  + image_upload_type=A), 옵션 생성/이름·썸네일·표시방식 수정/삭제, 품목
  자체코드·추가금액·진열·판매 일괄 수정. 화면은 PUT 응답으로 그린다.
- client.delete/timeout, products.upload_images·options·variants 래퍼.
- 유닛테스트 21건 추가(88 통과), 문서(CAFE24_MODULE 3-3/3-4, DATABASES,
  .env.example CAFE24_READ_LAG_GRACE_MIN) 갱신.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
2026-09-18 18:07:42 +09:00
parent 8ea0db9245
commit 40766d805d
21 changed files with 2782 additions and 99 deletions
@@ -0,0 +1,19 @@
-- cafe24_db 마이그레이션 004 — 쓰기 직후 스냅샷 (카페24 읽기 지연 보정)
--
-- 카페24 관리자 API 는 PUT 직후 한동안 GET 에서 예전 값을 돌려준다.
-- PUT 응답의 상품 값(상품명·가격·이미지·진열/판매·updated_date)을 여기 남겨,
-- GET 의 updated_date 가 스냅샷보다 이전이면 스냅샷으로 화면을 덮어씌운다.
-- 상세설명(HTML)은 cafe24_product_revisions 가 담당하므로 넣지 않는다.
--
-- 적용:
-- docker exec -i postgres-db psql -U postgres -d cafe24_db < scripts/sql/cafe24_db_004_write_snapshot.sql
-- 멱등 — 여러 번 실행해도 안전.
ALTER TABLE cafe24_products
ADD COLUMN IF NOT EXISTS last_write_snapshot JSONB,
ADD COLUMN IF NOT EXISTS last_written_at TIMESTAMPTZ;
COMMENT ON COLUMN cafe24_products.last_write_snapshot IS
'카페24 PUT 응답 상품 값(상품명·가격·이미지·진열/판매·updated_date). 읽기 지연 보정용';
COMMENT ON COLUMN cafe24_products.last_written_at IS
'마지막으로 카페24에 쓴 시각. 유예시간(CAFE24_READ_LAG_GRACE_MIN) 판정용';