Skip to content

feat(mobile): 이메일 회원가입 화면 구현#104

Merged
hijjoy merged 22 commits intomainfrom
feature/email-sign-up
Feb 4, 2026
Merged

feat(mobile): 이메일 회원가입 화면 구현#104
hijjoy merged 22 commits intomainfrom
feature/email-sign-up

Conversation

@hijjoy
Copy link
Member

@hijjoy hijjoy commented Feb 4, 2026

📋 개요

이메일 회원가입 플로우 전체 구현

  • 닉네임 → 이메일 → 비밀번호 → 약관동의 → 인증코드 입력
스크린샷 2026-02-04 10 01 18

약관 동의가 끝나면 회원가입 요청이 가서 실제 회원가입이 완료되는데
이후 인증코드를 받지 않고 이탈하면 로그인할 수 없게 됩니다
따라서 로그인 시 해당 에러가 발생하면 이메일 인증 번호를 할 수 있는 페이지로 이동하였습니다.

🏷️ 변경 유형

  • feat - 새로운 기능 추가
  • ♻️ refactor - 코드 리팩토링

📦 영향 범위

  • apps/mobile - Expo 모바일 앱
  • packages/validators - Zod 스키마

📝 변경 내용

화면 구현

  • 회원가입 화면 (sign-up.tsx) - 3단계 스텝 폼
  • 이메일 로그인 화면에서 회원가입 링크 연결
  • 인증 코드 입력 화면 (6자리 OTP 스타일)

폼 컴포넌트

  • SignUpUserInfoForm - 닉네임, 이메일 입력 + 도메인 추천
  • SignUpPasswordForm - 비밀번호 설정 + 규칙 표시
  • SignUpVerificationForm - 인증 코드 입력
  • TermsBottomSheet - 약관 동의 바텀시트

API 연동

  • 회원가입 API (register)
  • 인증 코드 검증 API (verifyEmail)
  • 인증 코드 재발송 API (resendVerification)

유효성 검증 & UX

  • 이메일 형식 검증 (Zod)
  • 비밀번호 규칙 검증 (8자 이상, 영문+숫자)
  • 인증 코드 재발송 쿨다운 (useCooldown 훅)
  • 에러 핸들링 (이미 가입된 이메일 → 로그인 안내 토스트)

공통 컴포넌트

  • KeyboardAdaptiveButton - 키보드 대응 버튼
  • Input 컴포넌트 추가
  • useStepper 훅 추가

테스트 결과

  • 타입체크 통과
  • 빌드 성공
  • 수동 테스트 완료 (시뮬레이터)

✅ 체크리스트

작성자 확인

  • 코드가 프로젝트의 코딩 컨벤션을 따릅니다
  • pnpm check (Biome) 검사를 통과했습니다
  • 모든 테스트가 통과합니다 (pnpm test)
  • 빌드가 성공합니다 (pnpm build)
  • 커밋 메시지가 Conventional Commits 규칙을 따릅니다

🔗 관련 이슈

Closes #58

💬 추가 정보

Frame 2087331624 스크린샷 2026-02-04 14 41 21 바텀시트 변경 후 안드에서도 확인

⭐️ 구체적인 사용성은 추후 더 해결해 나가야할 예정 ⭐️

hijjoy and others added 14 commits February 3, 2026 21:21
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
키보드 상태에 따라 버튼 스타일 자동 조정

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Checkmark/Eye/EyeOff 아이콘 추가

Co-authored-by: Cursor <cursoragent@cursor.com>
PASSWORD_RULES에 HAS_LETTER, HAS_NUMBER 정규식 추가
- HAS_LETTER: 영문 포함 여부 검사 (/[A-Za-z]/)
- HAS_NUMBER: 숫자 포함 여부 검사 (/\d/)

회원가입 폼에서 실시간 비밀번호 유효성 피드백을 위해 사용

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
앱 루트에 KeyboardProvider 추가
KeyboardAdaptiveButton에 enabled prop 추가

enabled=false 시 KeyboardStickyView 비활성화되어
BottomSheet와 레이어 충돌 문제 해결

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
useStepper: 스텝 기반 폼 네비게이션 훅
ANIMATION: duration/delay 상수 (fast, normal, slow, short, medium, long)

다단계 폼에서 재사용 가능한 스텝 관리 로직 분리
매직 넘버 제거를 위한 애니메이션 상수 중앙화

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
signUpFormSchema 및 SignUpFormData 타입 추가
register, verifyEmail, resendVerification 메서드 구현

verifyEmail 성공 시 토큰을 storage에 저장

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
registerMutationOptions: 회원가입 요청
verifyEmailMutationOptions: 이메일 인증 후 세션 설정
resendVerificationMutationOptions: 인증 코드 재발송
useCooldown: 재발송 버튼 쿨다운 타이머 관리

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
SignUpUserInfoForm: 닉네임/이메일 입력, 도메인 자동완성
SignUpPasswordForm: 비밀번호 설정, 실시간 규칙 검증 표시
SignUpVerificationForm: 6자리 OTP 입력, 자동 제출
TermsBottomSheet: 필수/선택 약관 동의

각 폼은 useStepper로 내부 스텝 관리
FormProvider로 폼 상태 공유

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
sign-up: 3단계 회원가입 (정보입력 → 비밀번호 → 인증)
verify-email: 독립 이메일 인증 화면

Stack.Screen에 sign-up, verify-email 추가
로그인 화면 회원가입 버튼 연결
이메일 로그인 시 미인증 사용자 verify-email로 리다이렉트

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- watch → useWatch 리팩토링 (react-hook-form 권장 패턴)
- useAppToast 네임스페이스 패턴 적용 (toast.error())
- 에러 코드 상수 사용 (ErrorCode.EMAIL_0501, EMAIL_0503)
- 이미 가입된 이메일 에러 시 로그인 화면 이동 액션 추가
- placeholder 문구 및 애니메이션 타이밍 개선

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@hijjoy hijjoy linked an issue Feb 4, 2026 that may be closed by this pull request
13 tasks
@hijjoy hijjoy self-assigned this Feb 4, 2026
@gemini-code-assist
Copy link

Summary of Changes

Hello @hijjoy, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 Pull Request는 모바일 앱에 이메일 기반의 회원가입 기능을 완전히 통합합니다. 사용자 경험을 고려하여 다단계 폼, 실시간 유효성 검증, 그리고 키보드에 반응하는 UI 요소를 포함하고 있습니다. 이를 통해 사용자는 앱 내에서 원활하게 계정을 생성하고 이메일 인증을 완료할 수 있습니다.

Highlights

  • 이메일 회원가입 플로우 구현: 닉네임, 이메일, 비밀번호 설정, 약관 동의, 인증 코드 입력의 5단계로 구성된 전체 이메일 회원가입 플로우가 구현되었습니다.
  • 새로운 화면 및 UI 컴포넌트 추가: 회원가입 화면(sign-up.tsx)과 이메일 인증 화면(verify-email.tsx)이 추가되었으며, KeyboardAdaptiveButton, Input, TermsBottomSheet 등 재사용 가능한 UI 컴포넌트들이 도입되었습니다.
  • API 연동 및 유효성 검증: 회원가입(register), 이메일 인증(verifyEmail), 인증 코드 재발송(resendVerification) API가 연동되었고, 이메일 형식, 비밀번호 규칙(8자 이상, 영문+숫자 포함) 유효성 검증 및 인증 코드 재발송 쿨다운 기능이 추가되었습니다.
  • 에러 핸들링 개선: 로그인 시 미인증 에러(EMAIL_0503) 발생 시 이메일 인증 화면으로 이동하도록 처리하고, 이미 가입된 이메일(EMAIL_0501)의 경우 로그인 안내 토스트 메시지를 표시하는 등 에러 핸들링이 강화되었습니다.
  • 공통 훅 및 유틸리티 추가: 다단계 폼 처리를 위한 useStepper 훅과 쿨다운 타이머를 위한 useCooldown 훅, 그리고 애니메이션 상수가 추가되어 개발 편의성이 향상되었습니다.
Changelog
  • apps/mobile/.claude/ui-components.md
    • KeyboardAdaptiveButtonInput 컴포넌트 문서가 추가되었습니다.
  • apps/mobile/app/(app)/notifications/notification-list-item.tsx
    • 파일이 apps/mobile/src/features/notification/presentations/components/NotificationListItem.tsx로 이름 변경되었습니다.
  • apps/mobile/app/(auth)/_layout.tsx
    • 새로운 인증 관련 화면인 sign-upverify-email이 스택 내비게이터에 추가되었습니다.
  • apps/mobile/app/(auth)/email-login.tsx
    • 로그인 실패 시 EMAIL_0503 에러 코드가 발생하면 verify-email 화면으로 리다이렉트하는 로직이 추가되었습니다.
    • 회원가입 링크가 /sign-up 경로로 연결되도록 업데이트되었습니다.
  • apps/mobile/app/(auth)/login.tsx
    • 회원가입 버튼이 /sign-up 경로로 연결되도록 업데이트되었습니다.
  • apps/mobile/app/(auth)/sign-up.tsx
    • 이메일 회원가입의 다단계 폼을 처리하는 새로운 화면이 추가되었습니다. (닉네임 -> 비밀번호 -> 이메일 인증)
  • apps/mobile/app/(auth)/verify-email.tsx
    • 이메일 인증 코드를 입력하고 재발송하는 독립적인 화면이 추가되었습니다.
  • apps/mobile/app/_layout.tsx
    • 키보드 이벤트를 처리하기 위해 react-native-keyboard-controllerKeyboardProvider가 최상위 컴포넌트에 추가되었습니다.
  • apps/mobile/assets/icons/ic_checkmark.svg
    • 체크마크 아이콘 SVG 에셋이 추가되었습니다.
  • apps/mobile/assets/icons/ic_eye.svg
    • 눈 아이콘 SVG 에셋이 추가되었습니다.
  • apps/mobile/assets/icons/ic_eye_off.svg
    • 눈 감은 아이콘 SVG 에셋이 추가되었습니다.
  • apps/mobile/src/features/auth/models/auth.model.ts
    • 회원가입 폼 데이터 유효성 검증을 위한 signUpFormSchemaSignUpFormData 타입이 추가되었습니다.
  • apps/mobile/src/features/auth/presentations/components/SignUpPasswordForm.tsx
    • 비밀번호 설정 및 확인, 비밀번호 규칙 표시, 약관 동의 바텀시트 연동을 위한 컴포넌트가 추가되었습니다.
  • apps/mobile/src/features/auth/presentations/components/SignUpUserInfoForm.tsx
    • 닉네임 및 이메일 입력을 위한 컴포넌트가 추가되었으며, 이메일 도메인 추천 기능이 포함되었습니다.
  • apps/mobile/src/features/auth/presentations/components/SignUpVerificationForm.tsx
    • 이메일 인증 코드 입력을 위한 컴포넌트가 추가되었습니다.
  • apps/mobile/src/features/auth/presentations/components/TermsBottomSheet.tsx
    • 회원가입 약관 동의를 처리하는 바텀시트 컴포넌트가 추가되었습니다.
  • apps/mobile/src/features/auth/presentations/hooks/useCooldown.ts
    • 쿨다운 타이머 기능을 제공하는 useCooldown 훅이 추가되었습니다.
  • apps/mobile/src/features/auth/presentations/queries/register-mutation-options.ts
    • 회원가입 API 호출을 위한 TanStack Query 뮤테이션 옵션이 추가되었습니다.
  • apps/mobile/src/features/auth/presentations/queries/resend-verification-mutation-options.ts
    • 인증 코드 재발송 API 호출을 위한 TanStack Query 뮤테이션 옵션이 추가되었습니다.
  • apps/mobile/src/features/auth/presentations/queries/verify-email-mutation-options.ts
    • 이메일 인증 API 호출을 위한 TanStack Query 뮤테이션 옵션이 추가되었습니다.
  • apps/mobile/src/features/auth/repositories/auth.repository.impl.ts
    • register, verifyEmail, resendVerification 메서드가 AuthRepositoryImpl에 구현되었습니다.
  • apps/mobile/src/features/auth/repositories/auth.repository.ts
    • AuthRepository 인터페이스에 register, verifyEmail, resendVerification 메서드가 추가되었습니다.
  • apps/mobile/src/features/auth/services/auth.service.ts
    • AuthServiceregister, verifyEmail, resendVerification 메서드가 추가되었습니다.
  • apps/mobile/src/shared/constants/animation.constants.ts
    • React Native Reanimated 애니메이션에 사용될 durationdelay 상수가 정의된 파일이 추가되었습니다.
  • apps/mobile/src/shared/hooks/useStepper.ts
    • 다단계 폼 또는 스텝 진행 관리를 위한 useStepper 훅이 추가되었습니다.
  • apps/mobile/src/shared/infra/http/error-handler.ts
    • 공개 API 클라이언트용 handlePublicApiErrors가 추가되었으며, handleApiErrors의 주석이 명확해졌습니다.
  • apps/mobile/src/shared/infra/http/public-client.ts
    • 공개 API 클라이언트가 handlePublicApiErrors를 사용하도록 변경되었습니다.
  • apps/mobile/src/shared/ui/Button/Button.md
    • KeyboardAdaptiveButton 컴포넌트에 대한 문서가 추가되었습니다.
  • apps/mobile/src/shared/ui/Button/KeyboardAdaptiveButton.tsx
    • 키보드 상태에 따라 스타일이 동적으로 변하는 KeyboardAdaptiveButton 컴포넌트가 추가되었습니다.
  • apps/mobile/src/shared/ui/Button/index.ts
    • KeyboardAdaptiveButton이 익스포트 목록에 추가되었습니다.
  • apps/mobile/src/shared/ui/Icon/icons.ts
    • CheckmarkIcon, EyeIcon, EyeOffIcon이 아이콘 목록에 추가되었습니다.
  • apps/mobile/src/shared/ui/Input/Input.md
    • 새로운 Input 컴포넌트에 대한 문서가 추가되었습니다.
  • apps/mobile/src/shared/ui/Input/Input.tsx
    • 라벨, 에러 메시지, 좌우 콘텐츠를 지원하는 재사용 가능한 Input 컴포넌트가 추가되었습니다.
  • apps/mobile/src/shared/ui/Input/Input.types.ts
    • Input 컴포넌트의 Props 타입을 정의하는 파일이 추가되었습니다.
  • apps/mobile/src/shared/ui/Input/Input.variants.ts
    • Input 컴포넌트의 Tailwind Variants 스타일을 정의하는 파일이 추가되었습니다.
  • apps/mobile/src/shared/ui/Input/index.ts
    • Input 컴포넌트 및 관련 타입이 익스포트 목록에 추가되었습니다.
  • packages/validators/src/domains/auth/auth.constants.ts
    • 비밀번호 규칙에 영문 포함(HAS_LETTER) 및 숫자 포함(HAS_NUMBER) 여부 검사 정규식이 추가되었습니다.
Activity
  • hijjoy님이 이메일 회원가입 플로우 전체 구현을 목표로 PR을 생성했습니다.
  • 닉네임, 이메일, 비밀번호, 약관 동의, 인증 코드 입력의 5단계 플로우가 구현되었습니다.
  • 새로운 화면 및 UI 컴포넌트들이 추가되고 기존 인증 관련 화면에 회원가입 링크가 연결되었습니다.
  • 회원가입, 이메일 인증, 인증 코드 재발송 API 연동 및 관련 유효성 검증 로직이 추가되었습니다.
  • 타입체크 및 빌드 성공, 시뮬레이터 수동 테스트를 통해 기능이 검증되었습니다.
  • 코드 컨벤션 및 Conventional Commits 규칙을 준수하여 작성되었습니다.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@hijjoy hijjoy added type: feat 🚀 신규 기능 - 사용자에게 새로운 비즈니스 가치를 제공하는 작업 scope: mobile 📱 모바일 - Expo 기반 모바일 앱 UI/UX 및 클라이언트 로직 관련 labels Feb 4, 2026
Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

이메일 회원가입 기능 구현을 위한 PR 잘 보았습니다. 전반적으로 새로운 기능들이 체계적으로 구현되었고, 컴포넌트 분리와 상태 관리, 에러 핸들링 등 좋은 패턴들이 많이 적용되었습니다. 몇 가지 코드 개선점을 제안드립니다. SignUpUserInfoForm의 이메일 도메인 추천 로직에서 발생할 수 있는 버그를 수정하고, Input 컴포넌트의 스타일링을 프로젝트 컨벤션에 맞게 개선하는 것을 제안합니다. 또한 sign-up 화면의 헤더 제목 로직을 더 간결하게 만들 수 있는 방법도 포함했습니다. 코드 리뷰를 확인해주세요.

hijjoy and others added 5 commits February 4, 2026 10:13
- getHeaderTitle() 함수를 SIGN_UP_STEP_TITLES 상수 객체로 변경
- satisfies Record<SignUpStep, string>으로 누락 방지

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@hijjoy hijjoy requested a review from dydals3440 February 4, 2026 05:45
Copy link
Contributor

@dydals3440 dydals3440 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

몇가지 코멘트랑 궁금점을 남겨보았습니다~!!!!! 확인하시구 이상없으시면 머지해주세요!!


export const signUpFormSchema = z
.object({
email: emailSchema,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

프론트엔드의 도메인 모델링을 하기 위해서 *.model.ts파일을 만들어 뒀는데 서버 계약(@aido/validators)은 repository에서 요청과 응답에 대한 검증으로만 끝내야 할 것 같습니다!

  흐름 요약                                                                                   
                                                                                              
  Repository          Service             Model                                               
      │                   │                  │                                                
      │  DTO (서버 계약)   │                  │                                               
      ├──────────────────→│                  │                                                
      │                   │  Mapper          │                                                
      │                   ├─────────────────→│                                                
      │                   │                  │ Domain (순수)                                  
                                                                                              
  @aido/validators → Repository에서만 사용                                                    
  Domain Model → 서버 의존 없음           

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

폼 검증이 서버 규칙과 동일하게 관리되면 좋겠다고 생각해서 해당 부분을 계속 이렇게 짰던 것 같습니다 .. 😢

  1. 프론트 앱은 빌드된 코드라서, 서버가 규칙을 바꿔도 앱이 업데이트되지 않으면 그 규칙은 바뀌지 않음
  2. 어짜피 UI에 “8자리”가 하드코딩된 부분은 모두 수동으로 변경해야 함

제가 위 2가지를 생각하지 못했던 것 같습니다. 2번이 해결될 것 이라 생각했는데 그러려면
차라리 프론트에서 MIN_PASSWORD_LENGTH 같은 값을 한 곳에서 공유하고 스키마도 이것을 참조해서 프론트에서 만드는 것이 한번에 수정할 수 있는 방향인 것 같아요
수정해보겠습니다 ! 🧹🫧

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

너무 오버 엔지니어링 같긴한데.. 사실 요런 폼 검증은 진짜 같이 쓸때 더 좋다고 생각해서..! 이부분은 한번 더 고민해보는걸로 해서 결정하면 될 것 같습니다!!

Copy link
Member Author

@hijjoy hijjoy Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

일단 아래 제안해주신 model 파일에서 스키마는 분리하였습니다! (폼 검증은 presentation레이어이기 때문)
@aido/validators를 presentation 폼 검증에서 사용하는 것을 조금 더 고민해보고있는데,.....
공유해도/안해도 둘다 뭔가 서버에서 변경될 경우 문제는 동일하게 발생하지만 문제가 발생했을때 문제의 원인을 찾고 해결하는 방식이 다를 것 같기도해서
이 부분은 조금 더 고민해보고싶어서 일단은 남겨두겠습니다!

@@ -0,0 +1,10 @@
import { type Dispatch, type SetStateAction, useState } from 'react';

export const useStepper = <T extends readonly string[]>(steps: T) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

조금 더 type-safe하게 관리할 수 있게 아래처럼 써보는건 어떨까요??

export const useStepper = <T extends readonly string[]>(steps: T) => {
  const initialStep = steps[0];
  const [step, setStep] = useState<T[number]>(initialStep);

  const Step = React.memo((props: StepProps<T[number]>): ReactNode => {
    return React.createElement(React.Fragment, null, props.children);
  });

  const Stepper = React.memo(({ children }: StepperProps<T[number]>) => {
    const targetStep = children.find(
      (childStep) => childStep.props.name === step,
    );

    return React.createElement(React.Fragment, null, targetStep);
  });

  return { Stepper, Step, setStep, step };
};

지금도 괜찮지만 단계가 많아지고 단계 이름과 UI를 한 곳에서 선언적으로 관리하고 싶다면 살짝 다듬어 본다면, 요게 조금 더 좋을 수 있을 것 같아요!

  export type StepType = typeof SIGNUP_REGISTRATION_STEPS;
 
  const SIGNUP_REGISTRATION_STEPS = ["이름_입력", "이메일_입력", "비밀번호_입력", "비밀번호_확인", "전화번호_입력"] as const;
 
  const { Stepper, Step, setStep, step } = useStepper<StepType>(SIGNUP_REGISTRATION_STEPS);
 
  return (
    <Stepper>
      <Step name="이름_입력">이름_입력</Step>
      <Step name="이메일_입력">이메일_입력</Step>
      <Step name="비밀번호_입력">비밀번호_입력</Step>
      <Step name="비밀번호_확인">비밀번호_확인</Step>
      <Step name="전화번호_입력">전화번호_입력</Step>
    </Stepper>
 );

Copy link
Member Author

@hijjoy hijjoy Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{match(step)
  .with('정보_입력', () => <SignUpUserInfoForm ... />)
  .with('비밀번호_설정', () => <SignUpPasswordForm ... />)
  .with('이메일_인증', () => <SignUpVerificationForm />)
  .exhaustive()}
<Stepper>
  <Step name="정보_입력"><SignUpUserInfoForm ... /></Step>
  <Step name="비밀번호_설정"><SignUpPasswordForm ... /></Step>
  <Step name="이메일_인증"><SignUpVerificationForm /></Step>
</Stepper>

Stepper/Step는 UI를 선언적으로 나열하는 장점은 있지만, 모든 step을 다 처리했는지까지 타입으로 강제하진 못한다고생각합니다!
반대로 ts-pattern exhaustive 으로만 처리한 것은 모든 스탭이 처리되었는지 확인은 가능하지만 선언적으로 보이지 않고 조건문느낌이 큽니다

title부분을 ts-pattern으로 하고 Stepper/Step를 쓰는 방법으로는 가능하겠지만 이전 제미나이 리뷰에서 렌더링 시마다 함수를 호출하고 match 표현식을 평가하는 비용을 줄이기 위해 상수로 선언할 것을 제안하여 title은 Record<SignUpStep, string>로 정의했었어요.

회원가입부분은 나중에 새롭게 스탭이 생기거나 할 확률도 적기에 사실 스탭을 놓치거나 할 확률이 적지만
어떻게 step을 관리할까 조금 더 고민해볼 여지가 있다고생각하여 이 부분은 todo에 남겨두도록하겠습니다!

hijjoy and others added 3 commits February 4, 2026 16:07
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- 이벤트 핸들러 내부 setTimeout을 useEffect로 이동
- 클린업 함수로 타이머 정리 보장

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- auth.model.ts → user.model.ts, auth-tokens.model.ts, auth.policy.ts
- SignUpFormData 스키마를 presentations/schemas로 이동
- 도메인 모델과 프레젠테이션 레이어 관심사 분리

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@hijjoy hijjoy merged commit 6cdf38e into main Feb 4, 2026
3 checks passed
@hijjoy hijjoy deleted the feature/email-sign-up branch February 4, 2026 11:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: mobile 📱 모바일 - Expo 기반 모바일 앱 UI/UX 및 클라이언트 로직 관련 type: feat 🚀 신규 기능 - 사용자에게 새로운 비즈니스 가치를 제공하는 작업

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: 이메일 회원가입 화면 구현 (Mobile)

2 participants