글로벌 샵 온보딩 여정 및 Progress UX
docs/spec/global-shop-onboarding-journey.md
글로벌 샵 온보딩 여정 및 Progress UX
개요
MAKITT 플랫폼의 글로벌 샵 온보딩 사용자 경험(UX) 명세서입니다. 지구본(Globe) 화면을 통한 초기 온보딩과 /home 화면의 온보딩 진행 현황 대시보드를 정의합니다.
배경
현재 구현 현황:
- 3D 지구본 온보딩 씬(Scene 0-6): 국가 선택 → 샵 정보 → 상품 정보 → 디자인 스타일
- /home 대시보드: Quick Link 그리드 + 하단 채팅박스
변경 방향:
/home화면 상단에 "10분만에 전세계 론칭하기" CTA 배치- 하단 채팅박스 제거
- 국가별 온보딩 진행도 대시보드 추가
목표
- 초기 온보딩(지구본 화면)에서 메인 마켓 기준점 확립
- /home 화면에서 국가별 온보딩 진행 현황 시각화
- 5가지 설정 카테고리별 완성도 트래킹
- 사용자가 "다음 해야 할 일"을 직관적으로 파악
스코프
1. 지구본 화면 (초기 온보딩)
경로: /onboarding
디렉토리: makitt-client/apps/web/src/app/[locale]/onboarding/page.tsx
3D 지구본을 활용한 몰입형 온보딩 경험을 제공합니다.
2. /home 화면 (온보딩 진행 현황)
경로: /home
디렉토리: makitt-client/apps/web/src/app/[locale]/home/page.tsx
샵 운영 대시보드에서 국가별 온보딩 진행도를 확인합니다.
지구본 화면 (초기 온보딩)
Scene 구조
Scene 0 → Scene 1 → Scene 2 → Scene 3 → Scene 4 → Scene 5 → Scene 6
(안개) (인사) (국가선택) (샵정보) (상품정보) (디자인) (완료)
전체 온보딩 플로우 다이어그램
flowchart TB subgraph Onboarding["초기 온보딩 (지구본 화면)"] direction TB S0[Scene 0<br/>안개 효과] S1[Scene 1<br/>인사말] S2[Scene 2<br/>국가 선택] S3[Scene 3<br/>샵 정보 입력] S4[Scene 4<br/>샘플 상품 추가] S5[Scene 5<br/>디자인 스타일] S6[Scene 6<br/>AI 생성 + 가입] S0 --> S1 S1 --> S2 S2 --> S3 S3 --> S4 S4 --> S5 S5 --> S6 end subgraph CountrySelection["국가/마켓 선택"] direction LR Globe[3D 지구본] Primary["첫 번째 선택<br/>= 메인 마켓"] Additional["추가 마켓<br/>(복수 선택 가능)"] Globe --> Primary Primary --> Additional end subgraph HomeOnboarding["/home 화면 온보딩"] direction TB CTA["10분만에 전세계 론칭하기<br/>CTA 배너"] Progress["전체 진행률<br/>Progress Bar"] Dashboard["국가별 온보딩 대시보드"] Categories["5가지 설정 카테고리"] CTA --> Progress Progress --> Dashboard Dashboard --> Categories end S6 --> HomeOnboarding S2 -.-> CountrySelection
Scene 상세
| Scene | 이름 | 설명 | 디렉토리 |
|---|---|---|---|
| 0 | Awakening | 안개 효과와 함께 지구본 등장 | features/onboarding/ui/Scene0/ |
| 1 | Greeting | "안녕하세요! 국가를 선택해주세요" | features/onboarding/ui/Scene1/ |
| 2 | Country Selection | 글로브 회전 + 국가 선택 UI | features/onboarding/ui/Scene2/ |
| 3 | Shop Setup | 스토어 이름/URL/설명 입력 | features/onboarding/ui/LandingExperience/ |
| 4 | Product Setup | 샘플 상품 추가 (선택) | features/onboarding/ui/LandingExperience/ |
| 5 | Design Selection | 스토어 스타일 선택 | features/onboarding/ui/LandingExperience/ |
| 6 | Complete | AI 디자인 생성 + 가입 유도 | features/onboarding/ui/AIDesignResultPanel/ |
3D Globe 컴포넌트
디렉토리: makitt-client/apps/web/src/features/onboarding/lib/
| 컴포넌트 | 파일 | 설명 |
|---|---|---|
| Globe | Globe.tsx | 기본 지구본 (커스텀 셰이더) |
| InteractiveGlobe | InteractiveGlobe.tsx | 마우스 인터랙션 지원 |
| GlobeController | GlobeController/ | 회전 애니메이션 제어 |
| FlagContainer | FlagContainer/ | 국가 플래그 3D 표시 |
| Atmosphere | Atmosphere/ | 대기 효과 |
| Stars | Stars/ | 배경 별 |
국가(마켓) 선택 플로우
┌─────────────────────────────────────────────────────────────────┐
│ 지구본 (3D Globe) │
│ │
│ 🌍 │
│ ╭──────────╮ │
│ │ 🇰🇷 │ ← 클릭하면 글로브가 해당 국가로 회전 │
│ ╰──────────╯ │
│ │
│ 선택된 국가: 🇰🇷 한국 (메인 마켓) │
│ │
│ [+ 마켓 추가] [다음 →] │
└─────────────────────────────────────────────────────────────────┘
메인 마켓 기준점:
- 첫 번째로 선택한 국가가 **메인 마켓(Primary Market)**으로 설정
- 메인 마켓의 언어/통화가 샵의 기본 설정이 됨
- 이후 추가 마켓은 번역 대상이 됨
Country Store 상태 관리
파일: makitt-client/apps/web/src/features/onboarding/model/country.store.ts
interface CountryState { selectedCountries: SimpleCountryData[]; // 선택된 국가 목록 targetCountry: SimpleCountryData | null; // 글로브 회전 대상 hoveredCountry: string | null; // hover 상태 }
/home 화면 UI 변경
현재 구조
┌─────────────────────────────────────────────────────────────────┐
│ Welcome Section │
│ {shopName} - Let's MAKITT Happen │
├─────────────────────────────────────────────────────────────────┤
│ Quick Actions Grid (2x2) │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ Customize │ │ Manage │ │
│ │ Your Shop │ │ Products │ │
│ └─────────────┘ └─────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ Get Paid │ │ Ship It │ │
│ │ Anywhere │ │ to World │ │
│ └─────────────┘ └─────────────┘ │
├─────────────────────────────────────────────────────────────────┤
│ Chat Section │
│ "Or Just Talk It" - ChatInterface │
└─────────────────────────────────────────────────────────────────┘
변경 후 구조
flowchart TB subgraph HomeLayout["/home 화면 레이아웃"] direction TB subgraph TopCTA["상단 CTA 배너 (NEW)"] CTATitle["10분만에 전세계 론칭하기"] CTAProgress["전체 진행률: 60%"] CTANextAction["다음 할 일: 결제 연동"] end subgraph WelcomeSection["Welcome Section"] ShopName["샵 이름"] Tagline["Let's MAKITT Happen"] end subgraph QuickActions["Quick Actions Grid 2x2"] Card1["Customize Your Shop"] Card2["Manage Products"] Card3["Get Paid Anywhere"] Card4["Ship It to World"] end subgraph MarketDashboard["국가별 온보딩 대시보드 (NEW)"] Market1["🇰🇷 한국 Primary 100%"] Market2["🇺🇸 미국 60%"] Market3["🇯🇵 일본 0%"] end TopCTA --> WelcomeSection WelcomeSection --> QuickActions QuickActions --> MarketDashboard end Removed["❌ 제거: Chat Section"]
와이어프레임
┌─────────────────────────────────────────────────────────────────┐
│ 🚀 10분만에 전세계 론칭하기 [시작→] │
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━░░░░░░░░░░░░░░░░░░░░░░░ 40% │
├─────────────────────────────────────────────────────────────────┤
│ Welcome Section │
│ {shopName} - Let's MAKITT Happen │
├─────────────────────────────────────────────────────────────────┤
│ Quick Actions Grid (2x2) │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ Customize │ │ Manage │ │
│ │ Your Shop │ │ Products │ │
│ └─────────────┘ └─────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ Get Paid │ │ Ship It │ │
│ │ Anywhere │ │ to World │ │
│ └─────────────┘ └─────────────┘ │
├─────────────────────────────────────────────────────────────────┤
│ 국가별 온보딩 진행도 │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ 🇰🇷 한국 (Primary) [설정 완료] ━━━━ 100%│
│ │ 🇺🇸 미국 [진행중] ━━░░ 60%│
│ │ 🇯🇵 일본 [설정 필요] ░░░░ 0%│
│ │ [+ 마켓 추가] │
│ └───────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
변경 사항
| 영역 | 변경 전 | 변경 후 |
|---|---|---|
| 상단 CTA | 없음 | "10분만에 전세계 론칭하기" 배너 + Progress Bar |
| Quick Links | 그대로 유지 | 그대로 유지 |
| 하단 Chat | ChatInterface 컴포넌트 | 제거 |
| 대시보드 | 없음 | 국가별 온보딩 진행도 위젯 |
온보딩 진행도 대시보드
5가지 설정 카테고리
flowchart LR subgraph Categories["5가지 설정 카테고리"] P[정책 및 약관<br/>필수] PR[상품등록<br/>필수] T[가격 및 세금<br/>마켓별] PAY[결제<br/>마켓별] L[물류<br/>선택] end Start((시작)) --> P --> PR --> T --> PAY --> L --> Complete((런칭))
| 카테고리 | 설명 | 디렉토리 (makitt-client) | 필수 여부 |
|---|---|---|---|
| 정책 및 약관 | 이용약관, 개인정보처리방침, 반품정책 | app/[locale]/home/shop/policies/ | 필수 |
| 상품등록 | 최소 1개 상품 등록 | app/[locale]/home/products/ | 필수 |
| 가격 및 세금 | 마켓별 세금 설정, 가격 정책 | app/[locale]/home/shop/preference/ | 마켓별 |
| 결제 | PG 연동 (Toss/Stripe) | app/[locale]/home/payment/settings/ | 마켓별 |
| 물류 | ARGO 연동 또는 자체처리 | app/[locale]/home/logistics/settings/ | 선택 |
카테고리별 상세 (서브카테고리)
1. 정책 및 약관
| 서브카테고리 | 필수 | 국가별 차이 |
|---|---|---|
| 이용약관 (Terms of Service) | O | 국가별 템플릿 제공 |
| 개인정보처리방침 (Privacy Policy) | O | GDPR/CCPA 등 반영 |
| 반품/환불 정책 (Returns Policy) | O | KR: 청약철회 7일 |
| 배송 정책 (Shipping Policy) | O | 마켓별 상이 |
디렉토리: app/[locale]/home/shop/policies/page.tsx
2. 상품등록
| 서브카테고리 | 필수 | 설명 |
|---|---|---|
| 기본 상품 정보 | O | 이름, 가격, 설명, 이미지 |
| 재고 관리 | O | SKU, 재고 수량 |
| 다국어 상품명 | 마켓별 | 번역 상품명/설명 |
| 마켓별 가격 | 마켓별 | 통화별 가격 설정 |
| HS Code | 국제배송 시 | 관세 분류 코드 |
디렉토리: app/[locale]/home/products/
3. 가격 및 세금
| 서브카테고리 | 마켓 | 설정 값 |
|---|---|---|
| 부가가치세 (VAT) | KR | 10% (포함) |
| 판매세 (Sales Tax) | US | 주별 0-10.25% (별도) |
| 소비세 | JP | 10% (포함) |
| GST | SG | 9% (별도) |
디렉토리: app/[locale]/home/shop/preference/page.tsx
4. 결제
| 서브카테고리 | 마켓 | PG사 | 결제수단 |
|---|---|---|---|
| 국내 결제 | KR | 토스페이먼츠 | 카카오페이, 네이버페이, 토스페이, 신용카드 |
| 해외 결제 | US/JP/SG | Stripe | Credit Card, Apple Pay, Google Pay |
| PayPal | SG | PayPal | PayPal Balance, Credit Card |
디렉토리: app/[locale]/home/payment/settings/page.tsx
5. 물류
| 서브카테고리 | 필수 | 설명 |
|---|---|---|
| ARGO 연동 | 선택 | Techtaka 물류 시스템 |
| 자체 처리 | 선택 | 직접 배송 처리 |
| 배송비 설정 | 마켓별 | 마켓별 기본 배송비 |
| 무료배송 기준 | 마켓별 | 주문금액 기준 |
디렉토리: app/[locale]/home/logistics/settings/page.tsx
진행도 위젯 UI 설계
전체 Progress Bar
┌─────────────────────────────────────────────────────────────────┐
│ 🚀 10분만에 전세계 론칭하기 예상 소요: 약 5분 │
│ │
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━░░░░░░░░░░░░░░░░░░░░░░░ 60% │
│ │
│ 📍 다음 할 일: 결제 연동 완료하기 │
│ US 마켓 Stripe 연동이 필요합니다. [계속하기 →] │
└─────────────────────────────────────────────────────────────────┘
국가별 진행도 카드
┌─────────────────────────────────────────────────────────────────┐
│ 🇰🇷 한국 (Primary) ✓ 완료 │
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 100% │
│ │
│ ✓ 정책 및 약관 ✓ 상품등록 ✓ 가격/세금 │
│ ✓ 결제 연동 ⊘ 물류 (건너뜀) │
├─────────────────────────────────────────────────────────────────┤
│ 🇺🇸 미국 ◐ 진행중 │
│ ━━━━━━━━━━━━━━━━━━━━━░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 40% │
│ │
│ ✓ 정책 및 약관 ✓ 상품등록 ○ 가격/세금 ← 필수 │
│ ○ 결제 연동 ○ 물류 │
│ [설정 →] │
├─────────────────────────────────────────────────────────────────┤
│ 🇯🇵 일본 🔒 잠김 │
│ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0% │
│ │
│ 선행 조건: 기본 샵 설정 완료 필요 │
│ [준비 중] │
└─────────────────────────────────────────────────────────────────┘
상태 아이콘
| 상태 | 아이콘 | 설명 |
|---|---|---|
| 완료 | ✓ | 해당 카테고리 설정 완료 |
| 진행 중 | ◐ | 일부 설정 완료 |
| 대기 | ○ | 아직 시작 안함 |
| 잠김 | 🔒 | 선행 조건 미충족 |
| 건너뜀 | ⊘ | 선택 항목 건너뜀 |
| 주의 | ⚠️ | 필수 항목 미완료 |
상태 컬러
| 상태 | 배경색 | 텍스트 |
|---|---|---|
| 완료 | #DCFCE7 | #22C55E (녹색) |
| 진행 중 | #DBEAFE | #3B82F6 (파랑) |
| 대기 | #F1F5F9 | #64748B (회색) |
| 잠김 | #F1F5F9 | #94A3B8 (연한회색) |
| 건너뜀 | #FEF3C7 | #F59E0B (노랑) |
| 주의 | #FEE2E2 | #EF4444 (빨강) |
서버 모델링: 진행상태 트래킹
데이터 모델 다이어그램
erDiagram SHOP ||--o{ ONBOARDING_PROGRESS : has ONBOARDING_PROGRESS ||--|{ CATEGORY_PROGRESS : contains CATEGORY_PROGRESS ||--|{ SUBCATEGORY_PROGRESS : contains SHOP { string shopId PK string shopName string shopUrl string primaryMarket string status } ONBOARDING_PROGRESS { string progressId PK string shopId FK string marketCode number overallProgress string status datetime createdAt datetime updatedAt } CATEGORY_PROGRESS { string categoryId PK string progressId FK string categoryName string status number progress boolean requiredForLaunch datetime completedAt } SUBCATEGORY_PROGRESS { string subCategoryId PK string categoryId FK string name string status boolean required datetime completedAt }
OnboardingProgress 엔티티
interface OnboardingProgress { progressId: string; // PK shopId: string; // 샵 ID marketCode: string; // 마켓 코드 (KR, US, JP, SG) // 대카테고리 진행상태 categories: { policies: CategoryProgress; products: CategoryProgress; pricing: CategoryProgress; payment: CategoryProgress; logistics: CategoryProgress; }; // 전체 진행률 overallProgress: number; // 0-100 status: 'NOT_STARTED' | 'IN_PROGRESS' | 'COMPLETED'; // 메타 정보 createdAt: string; updatedAt: string; } interface CategoryProgress { status: 'NOT_STARTED' | 'IN_PROGRESS' | 'COMPLETED' | 'SKIPPED'; progress: number; // 0-100 subCategories: SubCategoryProgress[]; requiredForLaunch: boolean; completedAt?: string; } interface SubCategoryProgress { id: string; name: string; status: 'PENDING' | 'COMPLETED' | 'SKIPPED'; required: boolean; completedAt?: string; }
API 엔드포인트
GET /api/v1/shops/:shopId/onboarding/progress
→ 전체 온보딩 진행상태 조회
GET /api/v1/shops/:shopId/onboarding/progress/:marketCode
→ 특정 마켓 진행상태 조회
PATCH /api/v1/shops/:shopId/onboarding/progress/:marketCode/:category
→ 카테고리 진행상태 업데이트
POST /api/v1/shops/:shopId/onboarding/progress/:marketCode/:category/skip
→ 선택 카테고리 건너뛰기
진행률 계산 로직
function calculateOverallProgress(categories: Categories): number { const weights = { policies: 20, // 필수 products: 25, // 필수 pricing: 20, // 마켓별 payment: 25, // 마켓별 logistics: 10 // 선택 }; let totalWeight = 0; let completedWeight = 0; for (const [category, progress] of Object.entries(categories)) { const weight = weights[category]; totalWeight += weight; if (progress.status === 'COMPLETED') { completedWeight += weight; } else if (progress.status === 'SKIPPED') { // 선택 항목 건너뛰면 해당 가중치 제외 if (!progress.requiredForLaunch) { totalWeight -= weight; } } else if (progress.status === 'IN_PROGRESS') { completedWeight += (weight * progress.progress / 100); } } return Math.round((completedWeight / totalWeight) * 100); }
단계별 의존성
1. 조직 설정 ─────────────┐
↓
2. 샵 기본 설정 ─────────┬──────────────────┐
↓ ↓
3. 상품 준비 ←─────→ 4. 마켓별 설정 ←──── 6. 물류 연동
│ ↓
│ 5. 결제 연동
│ │
└───────────────────┴──────→ 7. 콘텐츠 & 런칭
| 단계 | 선행 조건 | 병렬 가능 |
|---|---|---|
| 조직 설정 | 없음 | - |
| 샵 기본 설정 | 조직 설정 완료 | - |
| 상품 준비 | 샵 기본 설정 완료 | 마켓별 설정 |
| 마켓별 설정 | 샵 기본 설정 완료 | 상품 준비 |
| 결제 연동 | 마켓별 설정 완료 | 물류 연동 |
| 물류 연동 | 조직 설정 완료 | 결제 연동 |
| 콘텐츠 & 런칭 | 상품 + 결제 완료 | - |
구현 고려사항
상태 저장
- 서버: DynamoDB
onboarding_progress테이블 - 클라이언트: Zustand store에 캐싱
- 실시간 동기화: 설정 변경 시 자동 progress 업데이트
성능
- Progress 위젯은 대시보드 초기 로딩에 포함
- 상세 체크리스트는 lazy loading
- 국가별 상태는 캐싱하여 불필요한 API 호출 방지
접근성
- 키보드 네비게이션 지원 (Tab, Enter)
- 스크린 리더 호환 (ARIA labels)
- 고대비 모드 지원
관련 문서
- 글로벌 자사몰 온보딩 기능 명세 - 7단계 온보딩 상세