Skip to content

feat(cody): ③ Conditions 화면 (ShopperPreference + client-only fit) #629

Description

@thxforall

목적

F1 adapter의 ShopperPreference 입력 화면을 구현한다. 예산(budget_krw) · 쇼핑몰(retailer_scope) · 성별(gender) · 국가(country)를 사용자가 설정하고, client-only fit(오버/슬림/무관)은 ShopperPreference 분리, FE 상태로만 관리한다. 모든 조건이 기본값을 가지므로 스킵 가능 — ④ Recommended로 진행하거나 설정값을 반영한 추천을 받는다.

범위

  • 화면 설계 (wireframes.md §2 ③)
  • 레이아웃 · 상태 관리 · 조건값 변경
  • F1 adapter(cody-match.ts)의 ShopperPreference 타입 사용
  • client-only fit 분리 (ShopperPreference에 fit 필드 없음 — ClientOnlyFitPreference로 별도 관리)
  • budget → preference_variant tier 매핑 참조(F7 reconcile에서 상세화)
  • 비로그인 가능, auth 미필요
  • 실패 상태 없음 (모든 값이 valid default 존재)

화면 스펙

컴포넌트

예산 슬라이더 (budget_krw, 단위 원)

  • 3단 preset: 20만 / 50만 / 무제한(0)
  • 슬라이더 or 버튼 세트, 자유 입력 가능(선택)
  • 기본값: 50만(budget-500k tier, mvp-scope §2 기준)

쇼핑몰 체크박스 (retailer_scope)

  • ☑ 무신사
  • ☑ 29CM
  • ☑ W컨셉
  • ☑ 전체 (추후 글로벌 옵션, Phase 2)
  • 기본값: 무신사 + 29CM (kr scope)
  • 다중 선택 가능

성별 (gender)

  • ▢ 남
  • ▢ 여
  • ☑ 유니섹스 (기본값)

국가 (country, 선택적)

  • 기본값: "KR"
  • 드롭다운(Phase 2에서 multi-country 지원 시 활성화)

핏(오버/슬림/무관)client-only, ShopperPreference 아님

  • ▢ 오버
  • ☑ 슬림
  • ▢ 무관
  • 기본값: 슬림
  • 이 필드는 ClientOnlyFitPreference (UI 전용) 로 관리 — backend ShopperPreference.fit 없음(CONTEXT.md 정의)

상태

  • default: 모든 필드가 기본값. 제출 버튼 활성화.
  • loading: 없음. client-only → 즉시 반영.
  • error: 없음. 모든 값이 valid.
  • empty: 해당 없음.

전환

  • [이 조건으로 추천 → ④]: 설정값을 담아 ④ Recommended로 이동
    • store 업데이트: ShopperPreference(budget_krw, retailer_scope, country, gender) + ClientOnlyFitPreference(fit)
    • F5가 이 값을 읽어 추천 재계산
  • [건너뛰고 추천 → ④]: 기본값으로 ④로 진행
  • [← Analysis]: 뒤로가기 → ② Analysis로 돌아감

Acceptance Criteria

  • app/cody/conditions/page.tsx 생성 — 예산·쇼핑몰·성별·핏 입력 폼
  • lib/stores/codyStore.ts에 ShopperPreference + ClientOnlyFitPreference 상태 추가
    • ShopperPreference: budget_krw, retailer_scope('kr'|'global'|'both'), country, gender('male'|'female'|'unisex'), excluded_brands[], preferred_retailers[]
    • ClientOnlyFitPreference: 'over'|'slim'|'any' (FE 전용, backend 미송신)
  • 기본값 설정: budget_krw=500_000, retailer_scope='kr', country='KR', gender='unisex', fit='slim'
  • 슬라이더/버튼으로 budget_krw 변경 시 store 즉시 업데이트
  • 체크박스로 retailer_scope 변경 시 store 즉시 업데이트
  • fit(오버/슬림/무관) 변경은 ShopperPreference 아님 — ClientOnlyFitPreference만 업데이트 확인
  • [이 조건으로 추천] 클릭 → store에 현재값 저장 후 app/cody/recommended 라우트 이동
  • [건너뛰고 추천] 클릭 → 기본값 초기화 후 ④로 이동
  • [← Analysis] 클릭 → app/cody/analysis 로 뒤로 이동
  • lib/components/cody/ConditionsForm 컴포넌트 추가(또는 inline)
  • VTON 무의존성 검증: app/cody/conditions/*에서 lib/components/vton, lib/stores/vtonStore, /api/v1/vton import 0건 확인
  • fit 분리 확인: ShopperPreference 타입에 fit 필드 없고, ClientOnlyFitPreference로만 관리

핵심 파일

경로 역할
packages/web/app/cody/conditions/page.tsx ③ Conditions 화면 페이지 컴포넌트
packages/web/lib/stores/codyStore.ts ShopperPreference + ClientOnlyFitPreference 상태 저장소 (F1이 먼저 기초 설정)
packages/web/lib/components/cody/ConditionsForm.tsx (선택) 예산·쇼핑몰·성별·핏 폼 컴포넌트
packages/web/lib/api/adapters/cody-match.ts F1이 정의한 단일 adapter (ShopperPreference 타입 import)

금지 경로: /recreate, /request, /(request), /(consumer), /cody/screens, /cody/detail

mock · real 경계

  • Mock: client-only, 즉시 반영. 백엔드 호출 없음.
  • Real: F5(Recommended)가 이 상태를 읽어 POST /raw-posts/{id}/match?variant=<tier> 호출 시 ShopperPreference 전달.
    • 단, fit은 전달 안 함 — F5가 FE 필터로만 처리(Phase 2+에서 backend로)
  • Contract 출처: cody-match-stage2 §2.1 (ShopperPreference, 4-tier budget bucketing) · mvp-scope §2·§1 P4

의존성

  • F1 (Adapter): ShopperPreference 타입 + codyStore 초기화
  • F3 (Analysis): ③로의 [조건 설정] CTA는 ② 화면에서 발생 → 라우트 기준 정확성
  • F5 (Recommended): ShopperPreference를 읽어 추천 요청 시 전달

제약 · 주의

  1. ShopperPreference ≠ ClientOnlyFitPreference: CONTEXT.md 정의 준수

    • ShopperPreference (backend): budget_krw, retailer_scope, country, gender, excluded_brands, preferred_retailers
    • ClientOnlyFitPreference (FE): 'over'|'slim'|'any'
    • codyStore에는 둘 다 저장되지만, F5 요청 시 ShopperPreference만 backend로 송신
  2. 단일 adapter 규칙: cody-match.ts에만 ShopperPreference 타입 정의 — codyAdapterConditions.ts, conditions/adapter.ts 등 별도 파일 생성 금지

  3. budget → preference_variant 매핑:

    • 20만 → F7에서 확정(미정: custom budget_krw=200_000 vs snap budget-100k). 본 이슈는 단정하지 않음
    • 50만 이하 → budget-500k
    • 100만 이하 → budget-1M
    • 0(무제한) → authentic
    • 구체적 매핑은 F7 reconcile 체크리스트에서 확정(본 이슈는 예산값 저장만)
  4. 기본값 모두 valid: 모든 필드가 스킵 가능 — ④에서도 기본값으로 추천 수신 가능

  5. 모바일 우선 (wireframes.md §0): 360–390px 기준 세로 뷰포트

참조

  • wireframes.md §2 ③ Conditions — 레이아웃·컴포넌트·상태
  • mvp-scope.md §2·§1 P4 — 조건 화면 정의
  • cody-match-stage2.md §2.1 — ShopperPreference 타입 (backend 계약)
  • CONTEXT.md — Shopper Preference · Client-only Fit Preference · 용어 정의
  • user-scenarios.md §4 — 실패 상태(F4는 없음)
  • [[F1]] — ShopperPreference 타입 정의 · codyStore 초기화
  • [[F5]] — ShopperPreference 소비 (추천 요청 시)

Metadata

Metadata

Assignees

No one assigned

    Labels

    codyCody Recreation Engine MVPenhancementNew feature or requestfrontend프론트엔드

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions