Onboarding Redesign Specification
Status: Archived Last updated: 2026-03-28
Auth Providers (Korea launch)
| Provider | Priority | Why |
|---|---|---|
| Kakao | Primary | 49M Korean MAU, default identity |
| Naver | Secondary | 30M Korean MAU, older demographics |
| Tertiary | Universal 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 onlyNaver Login
SDK: @react-native-seoul/naver-login (same maintainer as Kakao — crossplatformkorea)
login()→ returnsaccessToken- Exchange for OIDC token or use Supabase OAuth browser flow
- Supabase supports Naver as a provider (custom OIDC)
Naver Developer Console
- Create application at https://developers.naver.com
- Service URL + callback URL
- Required scopes:
name,profile_image,email
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):
| Card | Description | Elo 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
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