Summary
R2(decoded-media)에 적재된 fashion-decode 이미지를 Vision AI로 파싱해 구조화 데이터(ParsedDecodeResult)로 추출하고, 기존 seed 파이프라인(seed_posts → seed_spots → seed_solutions)에 투입한다.
플랫폼 무관 — warehouse.source_media 의 parse_status='pending' 레코드만 바라보고 동작한다.
Related:
Architecture
ARQ 잡 (10분 간격)
→ source_media WHERE parse_status='pending' LIMIT 10
→ R2 GET (r2_key)
→ GeminiClient (gemini-3-flash-preview)
input: image bytes + caption
output: ParsedDecodeResult (Pydantic structured output)
→ seed_writer:
seed_posts ← image_url=r2_url, media_source={platform, external_id}
seed_spots ← position_left/top, subcategory_code (item별)
seed_solutions ← brand, product_name, price_*
seed_asset ← archived_url=r2_url, image_hash
→ source_media UPDATE parse_status='parsed', seed_post_id=<new>, parse_result=<json>
스키마 (재사용)
class ParsedItem(BaseModel):
brand: str
product_name: str | None
price_amount: float | None
price_currency: str | None # USD | KRW | EUR | ...
subcategory: str # top | bottom | shoes | bag | accessory | ...
position_x_pct: int # 0-100 (seed_spots.position_left)
position_y_pct: int # 0-100 (seed_spots.position_top)
class ParsedDecodeResult(BaseModel):
celebrity_name: str | None
group_name: str | None
occasion: str | None
items: list[ParsedItem]
엔티티 매칭(brand 문자열 → brands 테이블 FK 해소)은 파이프라인 4(디테일 enrichment) 담당. 여기서는 문자열 그대로 seed_solutions 에 저장.
파일
신규
| 파일 |
역할 |
packages/ai-server/src/services/media/vision_parser.py |
MediaVisionParser |
packages/ai-server/src/services/media/seed_writer.py |
source_media → seed_* 매핑 |
packages/ai-server/src/services/media/jobs.py |
parse_media_job ARQ 잡 |
수정
| 파일 |
변경 |
packages/ai-server/src/bootstrap.py |
파싱 잡 10분 스케줄 등록 |
packages/ai-server/src/api/media.py |
POST /media/items/{id}/reparse 수동 재파싱 |
에러 처리
- 파싱 실패:
parse_status='failed', parse_result={error: ...} — 재시도 최대 3회
- 아이템 0개:
parse_status='skipped' (fashion-decode 포맷이 아님)
- Vision API rate-limit: ARQ backoff
검증
🤖 Generated with Claude Code
Summary
R2(
decoded-media)에 적재된 fashion-decode 이미지를 Vision AI로 파싱해 구조화 데이터(ParsedDecodeResult)로 추출하고, 기존 seed 파이프라인(seed_posts → seed_spots → seed_solutions)에 투입한다.플랫폼 무관 —
warehouse.source_media의parse_status='pending'레코드만 바라보고 동작한다.Related:
source_media테이블 + R2 적재)Architecture
스키마 (재사용)
파일
신규
packages/ai-server/src/services/media/vision_parser.pyMediaVisionParserpackages/ai-server/src/services/media/seed_writer.pysource_media → seed_*매핑packages/ai-server/src/services/media/jobs.pyparse_media_jobARQ 잡수정
packages/ai-server/src/bootstrap.pypackages/ai-server/src/api/media.pyPOST /media/items/{id}/reparse수동 재파싱에러 처리
parse_status='failed',parse_result={error: ...}— 재시도 최대 3회parse_status='skipped'(fashion-decode 포맷이 아님)검증
source_media(pending)→ 파싱 잡 1회 →seed_posts/seed_spots/seed_solutions생성 +parse_status='parsed'🤖 Generated with Claude Code