Skip to content

release: raw_posts R2 cleanup + storage rename (#466)#487

Merged
cocoyoon merged 5 commits into
mainfrom
dev
May 7, 2026
Merged

release: raw_posts R2 cleanup + storage rename (#466)#487
cocoyoon merged 5 commits into
mainfrom
dev

Conversation

@cocoyoon
Copy link
Copy Markdown
Member

@cocoyoon cocoyoon commented May 7, 2026

Summary

  • raw_post 삭제 시 R2 객체 cleanup (verified posts 참조 안 할 때만).
  • AppState storage 명명을 db 패턴에 맞춤: `storage_client` → `operation_storage`, 신규 `assets_storage`.

🤖 Generated with Claude Code

cocoyoon and others added 5 commits May 7, 2026 17:27
* feat(raw_posts): StarStyle.com adapter (#466)

WordPress SSR fashion 사이트(starstyle.com) 어댑터 추가. wots(#465) 인프라
재사용 — discovery_target='raw_posts' 글로벌 피드 모델, PrelabeledData 로
vision 단계 우회.

핵심 차이: per-item 사진 URL 이 없어 thumbnail_url=None → items_thumbnail
processor 가 spots bbox 로 hero crop fallback path 사용. brand/title 분리는
보수적으로 product 통째로 (verify 단계 admin 처리).

- adapters/_starstyle_html.py: parse_post / parse_sitemap /
  decode_skimresources (skim affiliate 디코드)
- adapters/starstyle.py: thin httpx wrapper, fetch + sitemap discover
- scripts/backfill_starstyle_posts.py: sitemap → JSONL streaming → PostgREST
  bulk INSERT (wots 미러)
- service.rs: parse_starstyle_source — slug-sp{ID} 형식 검증
- admin UI: PLATFORM_FILTERS / PLATFORM_TABS / DiscoveryPipelineCard / URL builder
- migration: pipeline_settings starstyle row (모든 cycle OFF)
- 24 단위 테스트 추가 (parser + adapter + prelabeled round-trip)

Closes #466.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(starstyle): force HTTPS on og:image URL (#466)

starstyle 의 og:image 가 http:// 로 노출되는데 admin 은 HTTPS 라
mixed-content 로 이미지가 차단되던 문제. CDN 자체는 HTTPS 정상이라
파서 단계에서 https 강제 변환.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
#484)

starstyle 의 og:image 는 admin (HTTPS) 에서 직접 hotlink 가 막힌다:
  - HTTPS 요청 → 301 redirect to HTTP → mixed-content 차단
  - HTTP 요청 → User-Agent / Referer 가 비어 있으면 403

백필 시점에 boto3 로 upstream 이미지 다운로드 → R2 (RAW_POSTS_R2_BUCKET) 에
``starstyle/{shard}/{external_id}.jpg`` 키로 업로드하고, raw_posts.image_url
을 R2 public URL 로 저장한다. admin 은 R2 직접 fetch (HTTPS clean, hotlink
없음) → Vercel image-proxy 우회.

- HEAD 로 R2 객체 존재 확인 → 재실행 시 중복 업로드 skip (idempotent)
- 다운로드/업로드 실패 시 upstream URL 로 fallback (image_url 그대로)
- RAW_POSTS_R2_* env 미설정 시 mirror skip + warning
- PostData @DataClass(frozen=True) → frozen 제거 (image_url 교체 위해)

검증: 500 row 재백필, 479/500 R2 mirrored. 샘플 R2 URL HTTPS 200 확인.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
# Conflicts:
#	packages/ai-server/scripts/backfill_starstyle_posts.py
* release: starstyle R2 mirror fix (#466) (#485)

* feat(raw_posts): StarStyle.com adapter (#466) (#481)

* feat(raw_posts): StarStyle.com adapter (#466)

WordPress SSR fashion 사이트(starstyle.com) 어댑터 추가. wots(#465) 인프라
재사용 — discovery_target='raw_posts' 글로벌 피드 모델, PrelabeledData 로
vision 단계 우회.

핵심 차이: per-item 사진 URL 이 없어 thumbnail_url=None → items_thumbnail
processor 가 spots bbox 로 hero crop fallback path 사용. brand/title 분리는
보수적으로 product 통째로 (verify 단계 admin 처리).

- adapters/_starstyle_html.py: parse_post / parse_sitemap /
  decode_skimresources (skim affiliate 디코드)
- adapters/starstyle.py: thin httpx wrapper, fetch + sitemap discover
- scripts/backfill_starstyle_posts.py: sitemap → JSONL streaming → PostgREST
  bulk INSERT (wots 미러)
- service.rs: parse_starstyle_source — slug-sp{ID} 형식 검증
- admin UI: PLATFORM_FILTERS / PLATFORM_TABS / DiscoveryPipelineCard / URL builder
- migration: pipeline_settings starstyle row (모든 cycle OFF)
- 24 단위 테스트 추가 (parser + adapter + prelabeled round-trip)

Closes #466.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(starstyle): force HTTPS on og:image URL (#466)

starstyle 의 og:image 가 http:// 로 노출되는데 admin 은 HTTPS 라
mixed-content 로 이미지가 차단되던 문제. CDN 자체는 HTTPS 정상이라
파서 단계에서 https 강제 변환.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore: retrigger CI with bump label

* fix(starstyle-backfill): mirror hero images to R2 before INSERT (#466) (#484)

starstyle 의 og:image 는 admin (HTTPS) 에서 직접 hotlink 가 막힌다:
  - HTTPS 요청 → 301 redirect to HTTP → mixed-content 차단
  - HTTP 요청 → User-Agent / Referer 가 비어 있으면 403

백필 시점에 boto3 로 upstream 이미지 다운로드 → R2 (RAW_POSTS_R2_BUCKET) 에
``starstyle/{shard}/{external_id}.jpg`` 키로 업로드하고, raw_posts.image_url
을 R2 public URL 로 저장한다. admin 은 R2 직접 fetch (HTTPS clean, hotlink
없음) → Vercel image-proxy 우회.

- HEAD 로 R2 객체 존재 확인 → 재실행 시 중복 업로드 skip (idempotent)
- 다운로드/업로드 실패 시 upstream URL 로 fallback (image_url 그대로)
- RAW_POSTS_R2_* env 미설정 시 mirror skip + warning
- PostData @DataClass(frozen=True) → frozen 제거 (image_url 교체 위해)

검증: 500 row 재백필, 479/500 R2 mirrored. 샘플 R2 URL HTTPS 200 확인.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(release): backend bump ai=1.5.1 api=0.10.1 [skip ci]

* feat(raw_posts): R2 cleanup on raw_post delete (#466)

raw_post 삭제 시 image_url 이 raw_posts R2 객체이고 verified posts 가
같은 URL 을 참조하지 않으면 R2 객체도 같이 삭제. verify 후에는 posts.
image_url 가 raw_post.image_url 그대로 복사되므로 (#333) — verified post
가 참조 중이면 보존해야 깨지지 않는다.

또한 storage 명명을 db 패턴(db / assets_db) 에 맞춤:
  - storage_client → operation_storage
  - 신규 RAW_POSTS_R2_* → assets_storage
  - AppConfig.storage / assets_storage, AppState.operation_storage /
    assets_storage 일관 매핑.

config:
  - StorageConfig 두 개 (storage / assets_storage), 별도 R2 버킷 wiring
  - RAW_POSTS_R2_{ACCOUNT_ID, ACCESS_KEY_ID, SECRET_ACCESS_KEY, BUCKET, PUBLIC_URL}

service::delete_item:
  - 시그니처 (assets_db, prod_db, storage, public_url, id) — 4개의 DI
  - raw_post.image_url 추출 → DELETE 진행
  - extract_assets_r2_key 로 R2 key 추출 (public_url prefix strip)
  - posts.image_url COUNT — 0 이면 storage.delete(key) 호출
  - 실패는 best-effort warn (이미 raw_post 삭제는 성공)

테스트: 4개 단위 (key 추출 - prefix/trailing slash/other domain/empty url).

solutions/tests.rs 의 AdminSolutionListQuery 빌드에 has_url=None 추가
(unrelated 사전 컴파일 에러 — 본 PR 의 cargo test --lib 통과 위해 보강).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: decoded-ci <ci@decodedcorp.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 7, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
decoded-app Ready Ready Preview, Comment May 7, 2026 10:13am

@cocoyoon cocoyoon added the bump:minor Backward-compatible additions label May 7, 2026
@cocoyoon cocoyoon merged commit 89d8534 into main May 7, 2026
3 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done in decoded-monorepo May 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bump:minor Backward-compatible additions

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant