Skip to content

Onboarding Redesign Specification

Status: Archived Last updated: 2026-03-28


Auth Providers (Korea launch)

ProviderPriorityWhy
KakaoPrimary49M Korean MAU, default identity
NaverSecondary30M Korean MAU, older demographics
EmailTertiaryUniversal fallback, no social account needed

Google and Apple deferred to international expansion phase.

Account Linking

Users can link multiple providers to one TwoMore account:

  • Sign up with Kakao → link Naver later → log in with either
  • Supabase linkIdentity() API handles this natively
  • Settings screen: "연결된 계정" (Linked Accounts) section

Login Screen

Layout

[Logo + brand]

[카카오로 시작하기]     ← yellow, primary
[네이버로 시작하기]     ← green, secondary
[이메일로 시작하기]     ← ghost link

[이용약관 동의 안내]
[Dev quick-login]       ← preview builds only

SDK: @react-native-seoul/naver-login (same maintainer as Kakao — crossplatformkorea)

  • login() → returns accessToken
  • Exchange for OIDC token or use Supabase OAuth browser flow
  • Supabase supports Naver as a provider (custom OIDC)

Onboarding Flow (5 screens, Toss one-action-per-screen)

Screen 1: Name

Headline: "반가워요! 이름을 알려 주세요" Subtitle: "코트에서 불릴 이름이에요"

  • Single TextInput, pre-filled from auth provider (if available)
  • If auth provider gives no name → empty field, required
  • Default avatar: initials from name (NO auto-pull from Kakao/Naver)
  • Users can add a photo later on profile screen
  • Validation: 2-20 chars, profanity filter (badwords-ko), inline error on blur
  • No duplicate check (nicknames can repeat)
  • CTA: "다음"

Screen 2: Skill Level

Headline: "테니스 실력이 어느 정도인가요?" Subtitle: "경기 결과에 따라 자동으로 조정돼요"

3 scenario cards (not labels):

CardDescriptionElo Seed
🎾 "공 넘기기에 집중해요""아직 랠리가 길게 이어지진 않아요"Bronze (1000)
🎾 "랠리하며 경기를 즐겨요""기본 스트로크와 서브로 게임해요"Gold (1300)
🎾 "전략적으로 경기를 운영해요""대회나 리그 경험이 있어요"Diamond (1700)

Below cards: NTRP/UTR reference in small text

  • "약 NTRP 2.0-2.5 / UTR 1-3"
  • "약 NTRP 3.0-3.5 / UTR 4.5-6"
  • "약 NTRP 4.0-4.5 / UTR 7.5-9"

CTA: "다음"

Screen 3: Gender

Headline: "성별을 알려 주세요" Subtitle: "혼합 복식 구성에 참고돼요"

2 large tappable cards: 남성 / 여성 Skip: "건너뛰기" text link at bottom CTA: "다음" (auto-advances on selection)

Screen 4: Region

Headline: "주로 어디에서 치세요?" Subtitle: "근처 모임과 코트를 추천해 드려요"

Chip grid of 17 Korean regions:

  • 서울, 경기, 인천, 부산, 대구, 대전, 광주, 울산, 세종
  • 강원, 충북, 충남, 전북, 전남, 경북, 경남, 제주

For 서울: show secondary 구 picker (25 districts) Skip: "건너뛰기" CTA: "다음"

Screen 5: Role + Start

Headline: "어떻게 시작할까요?"

2 cards:

  • 📢 "모임 만들기" — "직접 모임을 운영하고 싶어요"
  • 🎾 "모임 참가하기" — "초대코드나 검색으로 참가할래요"

CTA: "시작하기" (final)

Post-completion routing:

  • 총무 → routes.createClub
  • 회원 → routes.home (with onboarding checklist)

DB Migration

sql
ALTER TABLE profiles
  ADD COLUMN IF NOT EXISTS gender TEXT CHECK (gender IN ('male', 'female')),
  ADD COLUMN IF NOT EXISTS region TEXT,
  ADD COLUMN IF NOT EXISTS district TEXT;

Voice & Tone (applied throughout)

Per docs/design/voice-and-tone-guide.md:

  • 해요체 for all conversational UI
  • Suggestive over imperative ("~해 볼까요?" over "~하세요")
  • Pure Korean over 한자어 ("알려 주세요" over "입력해 주세요")
  • Button labels: "~하기" for primary actions ("시작하기", "가입하기")
  • Errors: "~지 못했어요" (not "~에 실패했어요")
  • Toasts: brief, action-oriented

Dependencies

  • badwords-ko — Korean profanity filter for nickname validation
  • @react-native-seoul/naver-login — Naver native SDK (future)
  • Profile entity update: add gender, region, district fields
  • Auth adapter: add Naver provider support
  • Settings screen: "연결된 계정" for provider linking

Implementation Phases

Phase 1 (this sprint)

  • Rewrite profile-setup-screen.tsx (5 screens)
  • Migration for gender/region/district
  • Install badwords-ko
  • Update i18n with voice guide compliance

Phase 2

  • Add Naver login provider
  • Account linking in settings
  • Email signup flow

Phase 3

  • Optional skill reassessment quiz (post 5+ matches)
  • Photo prompt on profile screen

Markdown remains the source of truth. Run yarn docs:check before handoff.