Skip to content

[VTON] Modal 사용성·도메인 정합성 4-in-1 (filter/search/UI/render bug) #602

@thxforall

Description

@thxforall

Summary

Try-On 모달의 사용성 갭과 도메인 정합성 결함 4가지를 한 epic으로 묶어 4개 PR로 분할 진행.

# 종류 항목 PR
1 Feature items에 카테고리 필터링·검색 (DB 정본 7개 중 GA-안전 부분집합 노출) PR-3
2 Bug+Feature posts 1장만 로드되는 결함 + posts 검색 추가 PR-3 (root cause), PR-4 (검색)
3 Bug X 버튼이 헤더 텍스트와 정렬 안 됨 PR-1
4 Bug BeforeAfter slider 첫 렌더 시 after만 보이고 before width=0 PR-2

Background

Root cause 분석 (grill 완료)

  • Bug Ci/monorepo pre push local #2 (posts 1장만 로드)와 Feature ci: monorepo pre-push local CI orchestration #1 (카테고리)은 같은 원인packages/web/app/api/v1/vton/items/route.ts:6posts/route.ts:5의 화이트리스트 VTON_CATEGORY_CODES = ["tops","bottoms"]로 인해 그 외 subcategory를 가진 spot이 모두 filter out → posts는 eligible 0건이 되어 1장만 통과
  • DB 정본 카테고리: packages/api-server/migration/src/m20260110_000002_update_categories_and_seed_subcategories.rs:41-50의 Wearables 7개 (headwear, eyewear, accessories, tops, bottoms, shoes, bags)
  • Item은 카테고리 컬럼 없음solutions 테이블에 subcategory_id 없고 spots.subcategory_id로만 분류. 한 item이 여러 subcategory에 등장 가능 → API에서 dedupe 필요
  • VTON 모델 능력 (Google Vertex AI virtual-try-on-001 GA): tops, bottoms, dresses, shoes 공식 지원. bags/accessories/headwear/eyewear는 비공식 또는 별도 모델 필요

도메인 용어 정리

  • "카테고리" = subcategories.code (Wearables 부모 카테고리 하의 7개 코드)
  • VTON 노출 카테고리 화이트리스트는 코드 상수(VTON_CATEGORY_CODES)가 SSOT (이번 단계)
  • 향후 운영팀이 토글하려면 subcategories.vton_enabled 컬럼 추가 — 별도 phase로

Scope (확정)

노출 카테고리

tops, bottoms, shoes — Google VTON GA 공식 지원 3종만. bags/headwear/eyewear/accessories는 백로그.

검색 layer

  • Items: 기존 hybrid(Meilisearch + DB ilike) + solutions.keywords jsonb stringify ilike 추가
  • Posts: items와 동일 hybrid 패턴 신규 (title/artist_name/group_name/context 4-field DB fallback)
  • 빈 결과 cross-category hint는 백로그

UI

  • X 버튼은 ItemPanel 헤더 안으로 통합 (flex items-center justify-between)
  • 카테고리 탭 라벨은 한/영 병기: Tops 상의, Bottoms 하의, Shoes 신발 (DB seed name jsonb와 정확히 일치)

Render bug

  • BeforeAfterSlider.tsx를 clip-path 방식으로 리팩토 — containerRef.offsetWidth 측정 제거, SSR/초기 렌더 안전

Non-goals

  • subcategories.vton_enabled 컬럼 추가 (백로그)
  • Meilisearch 인덱스 schema에 keywords 추가 (백로그 — ai-server/api-server 영향)
  • 빈 결과 cross-category 카운트 hint (백로그)
  • bags/headwear/eyewear/accessories 카테고리 노출 (PoC 검증 후 별도 phase)
  • "셔츠/스커트" 수준 sub-subcategory 필터 (DB 모델 확장 필요 → 별도 큰 작업)

PR 분할

PR 제목 base 의존성 추정
PR-1 fix(vton-modal): close button alignment in panel header dev 없음 30분
PR-2 fix(vton-slider): initial render shows after-only (clip-path refactor) dev 없음 30분
PR-3 feat(vton): expand whitelist to shoes + dedupe + keywords search + bilingual labels dev 없음 4-6시간
PR-4 feat(vton-posts): hybrid search across title/artist/group/context dev PR-3 머지 후 2-3시간

QA branch flow

  1. PR-1, PR-2 병렬 → 각자 codex review → 머지 to dev
  2. PR-3 → codex review (adversarial: 카테고리 확장의 데이터 정합성 리스크) → QA 브랜치에서 검증 → 머지 to dev
  3. PR-4 → codex review → QA → 머지 to dev

Acceptance criteria (Parent epic)

  • VTON 모달에서 카테고리 탭에 Tops 상의 / Bottoms 하의 / Shoes 신발 3개 노출
  • Posts 탭에 24개에 가까운 posts가 로드됨 (현재 1개에서 개선 확인)
  • Posts 탭에서 검색창으로 artist 이름 검색 시 매칭 posts 노출
  • X 버튼이 "Virtual Try-On PoC" 텍스트와 같은 vertical line에 정렬
  • BeforeAfter slider 첫 렌더 시 50% 위치에 before/after 반반 표시 (드래그 없이도)
  • 한국어 사용자: 카테고리 라벨이 한글로 직관적
  • 카테고리 cross-filter 시 동일 solution이 여러 카테고리에 중복 노출되지 않음 (dedupe)

Related code

  • packages/web/lib/components/vton/VtonModal.tsx
  • packages/web/lib/components/vton/VtonItemPanel.tsx
  • packages/web/lib/components/vton/BeforeAfterSlider.tsx
  • packages/web/lib/hooks/useVtonItemFetch.ts
  • packages/web/lib/hooks/useVtonPostFetch.ts
  • packages/web/app/api/v1/vton/items/route.ts
  • packages/web/app/api/v1/vton/posts/route.ts
  • DB seed 정본: packages/api-server/migration/src/m20260110_000002_update_categories_and_seed_subcategories.rs

Workflow

  • Grilled with grill-with-docs skill (Matt Pocock variant)
  • Superpowers TDD + executing-plans for PR-3/PR-4
  • Codex review on every PR (/codex:review --background, adversarial on PR-3)
  • Worktree-isolated branches, QA branch verification before dev merge

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingenhancementNew feature or request

    Type

    No type
    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