You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
코디 재현 엔진(Cody Recreation Engine) consumer MVP의 프론트엔드 vertical slice를 구축한다. 셀럽/인플루언서 룩 이미지 → AI 코디 분석 → 유저 예산·쇼핑몰 조건 → style formula 충족하는 대체 상품 룩 세트 추천 → affiliate 구매. 백엔드 CodyMatchService(Stage 2 / cody-match-stage2) gRPC ship 이전이므로 mock fixture 기반으로 5+2 화면 + 단일 adapter seam을 먼저 안정화하고, 백엔드 ready 시 adapter 내부만 교체한다.
⚠️VTON(가상 피팅) 아님. VTON은 mvp-scope §5 기준 Phase 3 별개 기능 — 본 Epic과 무관 (아래 "제약·주의" VTON 분리 참조).
범위
5 core 화면(① Upload → ② Analysis → ③ Conditions → ④ Recommended → ⑤ Item Detail) + 2 보조 surface((+)Saved 보드 · (+)Shop-this-look 공유 slug). 9개 feature(#626–#634)로 분해. 모든 신규 화면은 packages/web/app/cody/, 로직은 packages/web/lib/ 아래에만 생성한다.
신규 라우트 디렉토리가 위 경로표 7개와 정확히 일치 — 금지 디렉토리(app/cody/screens·app/cody/detail, app/request·app/(request)·app/(consumer), /recreate) 0건
cody adapter 파일은 lib/api/adapters/cody-match.ts(types+entry) + cody-match-mock.ts(mock) 단 2개 — 그 외 cody adapter 파일 0건(codyAnalysisAdapter.ts, recommended/adapter.ts, useCodyMatch.ts, CodyEngineAdapter 등 금지)
타입은 cody-match-stage2 §2.2/§2.1 전 필드를 mirror — 누락·발명 금지. fixture도 full 형태(CandidateSKU의 relaxation_level·image_verification·confidence·reason 등 전 필드 포함).
별도 adapter 파일 생성 절대 금지(codyAnalysisAdapter.ts, recommended/adapter.ts, useCodyMatch.ts, CodyEngineAdapter 등).
#632은 이 단일 adapter의 mock → real reconcile 체크리스트 전용(구현 아님).
⚠️useImageUpload(lib/hooks/useImageUpload.ts) 재사용 금지 — 내부에서 useRequestStore + startDetection() 호출(line 93) → 옛 detection flow 트리거. #627는 위 3개 부품 + 새 cody upload hook/store(codyStore) 만 사용.
참조
decoded-docs/Project/wireframes.md — 5+1 화면 lo-fi + §4 실패·빈 상태 카탈로그
목적
코디 재현 엔진(Cody Recreation Engine) consumer MVP의 프론트엔드 vertical slice를 구축한다. 셀럽/인플루언서 룩 이미지 → AI 코디 분석 → 유저 예산·쇼핑몰 조건 → style formula 충족하는 대체 상품 룩 세트 추천 → affiliate 구매. 백엔드
CodyMatchService(Stage 2 / cody-match-stage2) gRPC ship 이전이므로 mock fixture 기반으로 5+2 화면 + 단일 adapter seam을 먼저 안정화하고, 백엔드 ready 시 adapter 내부만 교체한다.범위
5 core 화면(① Upload → ② Analysis → ③ Conditions → ④ Recommended → ⑤ Item Detail) + 2 보조 surface((+)Saved 보드 · (+)Shop-this-look 공유 slug). 9개 feature(#626–#634)로 분해. 모든 신규 화면은
packages/web/app/cody/, 로직은packages/web/lib/아래에만 생성한다.화면 / 경로 (SSOT — 이 표 밖 경로 금지)
app/cody/page.tsxapp/cody/analysis/page.tsxapp/cody/conditions/page.tsxapp/cody/recommended/page.tsxapp/cody/item/[skuHash]/page.tsxapp/cody/saved/page.tsx(gated)app/cody/looks/[slug]/page.tsx(public read)lib/stores/codyStore.tslib/api/adapters/cody-match.ts(types+entry) ·lib/api/adapters/cody-match-mock.ts(mock)lib/components/cody/*하위 feature (생성 후
Fn→ 실제 #번호로 교체)feat(cody): 라우트 스캐폴딩 + codyStore + 단일 adapter/타입 모듈 + 부품 재사용(의존:[])feat(cody): ① Upload 화면 (Storage real)(의존:[#626])feat(cody): ② Analysis 화면 (cody_analysis mock + style_formula UI)(의존:[#626])feat(cody): ③ Conditions 화면 (ShopperPreference + client-only fit)(의존:[#626])feat(cody): ④ Recommended 화면 (full CodyMatchResult fixture + FE composition)(의존:[#626, #628, #629])feat(cody): ⑤ Item Detail 화면 (CandidateSKU full + affiliate redirect)(의존:[#630])feat(cody): adapter reconcile 체크리스트 (mock → CodyMatchService S2)(의존:[#626])feat(cody): 실패·빈 상태 8종 통합 QA (cross-cutting) + VTON 비의존 검증(의존:[#627, #628, #630, #631])feat(cody): (+)Saved 보드 + Shop-this-look 공유 slug (gated)(의존:[#626, #631])의존성 그래프
크리티컬 패스: #626 → (#628·#629) → #630 → #631 → #633 / #634. #627·#628·#629·#632은 #626 후 병렬 가능.
Acceptance Criteria (epic-level · 검증가능)
Fn이 실제 #번호로 치환됨app/cody/screens·app/cody/detail,app/request·app/(request)·app/(consumer),/recreate) 0건lib/api/adapters/cody-match.ts(types+entry) +cody-match-mock.ts(mock) 단 2개 — 그 외 cody adapter 파일 0건(codyAnalysisAdapter.ts,recommended/adapter.ts,useCodyMatch.ts,CodyEngineAdapter등 금지)cody-match.ts에서만 import (별도 adapter import 0건)app/cody/*·lib/components/cody/*가lib/components/vton·lib/stores/vtonStore·/api/v1/vton에서 import 0건 (grep 검증)/cody/*smoke test 전 화면 통과 + VTON modal/state 미의존 확인useImageUpload미사용(startDetection()미트리거),DropZone+compressImage+uploadImage+codyStore로 동작백엔드 경계 (mock · real / contract 출처)
useImageUpload재사용 금지cody_analysis)CodyAnalysis)AnalysisQuality배지는 FE-only mock state —cody_analysis에 confidence 필드 없음ShopperPreference)fit은ClientOnlyFitPreference(client-side),ShopperPreference에 없음CodyMatchResultfull fixture)per_role후보에서 FE 조합 (outfit composition = Stage 3 미구현)CandidateSKUfull) + affiliate redirectCandidateSKU= §2.2 ·affiliate_url= §7.1catalog_itemsaffiliate_url은CandidateSKU/§2.2 아님 — 쓰면 catalog_items §7.1 출처 명시단일 adapter seam (BLOCKER)
lib/api/adapters/cody-match.ts하나에 모든 타입 + entry function.cody-match-mock.ts는 mock 구현. feat(cody): ② Analysis 화면 (cody_analysis mock + style_formula UI) #628/feat(cody): ④ Recommended 화면 (full CodyMatchResult fixture + FE composition) #630/feat(cody): ⑤ Item Detail 화면 (CandidateSKU full + affiliate redirect) #631/#634는 여기서 import만 한다.CandidateSKU의relaxation_level·image_verification·confidence·reason등 전 필드 포함).codyAnalysisAdapter.ts,recommended/adapter.ts,useCodyMatch.ts,CodyEngineAdapter등).제약 · 주의
AnalysisQuality배지) / ④(feat(cody): ④ Recommended 화면 (full CodyMatchResult fixture + FE composition) #630) 예산초과·빈결과(0건)·품절 auto-swap·affiliate 미커버·👎 재랭킹 / ⑤(feat(cody): ⑤ Item Detail 화면 (CandidateSKU full + affiliate redirect) #631) 링크끊김·미가입 저장(gated). feat(cody): 실패·빈 상태 8종 통합 QA (cross-cutting) + VTON 비의존 검증 #633 = 위 8종이 feat(cody): ① Upload 화면 (Storage real) #627~#631에 빠짐없이 구현됐는지 통합 검증 + 누락 catch (구현 아님, cross-cutting QA). ③ Conditions(feat(cody): ③ Conditions 화면 (ShopperPreference + client-only fit) #629)는 전부 default → empty/error 상태 없음 → feat(cody): 실패·빈 상태 8종 통합 QA (cross-cutting) + VTON 비의존 검증 #633 deps에서 제외.CodyMatchServiceS2 reconcile은 체크리스트 전용(구현 아님).core_combination/substitute_axis는cody_analysis(stage2 §2.1)는 소비하나 mvp-scope §3 예시엔must_keep/replaceable만 존재 → adapter에서 optional 확장으로 두고 feat(cody): adapter reconcile 체크리스트 (mock → CodyMatchService S2) #632 reconcile gap에 명시.CandidateSKU.confidence(per-SKU 매칭점수) ≠AnalysisQuality(② 분석 품질 배지).cody_analysis에 confidence 필드 없음.preference_variant(budget-100k / budget-500k / budget-1M / authentic) = Preference Variant(백엔드 request-tier 축). 둘은 별개 — 혼용 금지.lib/components/vton/VtonModal.tsx,app/lab/vton,app/api/v1/vton/*, root layoutLazyVtonModal(app/layout.tsx) 존재하나 cody와 무관.app/cody/*·lib/components/cody/*는lib/components/vton·lib/stores/vtonStore·/api/v1/vton에서 import 0건,/cody/*smoke test가 VTON modal/state 미의존.성공지표 (mvp-scope §6 — launch 후 1주 baseline 후 재조정)
핵심 재사용 자산 (repo 검증 완료)
DropZone—packages/web/lib/components/request/DropZone.tsxcompressImage—packages/web/lib/utils/imageCompression.tsuploadImage—packages/web/lib/api/posts.tsuseImageUpload(lib/hooks/useImageUpload.ts) 재사용 금지 — 내부에서useRequestStore+startDetection()호출(line 93) → 옛 detection flow 트리거. #627는 위 3개 부품 + 새 cody upload hook/store(codyStore) 만 사용.참조
decoded-docs/Project/wireframes.md— 5+1 화면 lo-fi + §4 실패·빈 상태 카탈로그decoded-docs/Project/mvp-scope.md— §2 화면 · §3cody_analysis스키마 · §6 성공지표decoded-docs/Project/user-scenarios.md— §1 파이프라인 · §3 entry(E1/E2/E3) · §4 실패 루프decoded-docs/Architecture/cody-match-stage2.md— §2.1CodyAnalysis/ShopperPreference· §2.2CandidateSKU/CodyMatchResult· §7.1catalog_items/affiliate_urldecoded-monorepo/CONTEXT.md— Cody glossary (Composition Variant / Preference Variant / Shopper Preference / Client-only Fit / Analysis Quality / VTON)별도 infra 이슈 (codex BLOCKER 분리)
infra(cody): saved_looks user-scoped 저장 테이블 + RLS(#634에서 분리,type:infra+ human checkpoint 필요)