kt-event-marketing-fe/docs/register-api-guide.md
cherry2250 10c728dbaf User API 전체 연동 완료 및 로그아웃 에러 처리 개선
## 주요 변경사항

### 1. FSD 아키텍처 기반 API 레이어 구축
- entities/user: User 엔티티 (타입, API)
- features/auth: 인증 기능 (useAuth, AuthProvider)
- shared/api: 공통 API 클라이언트 (Axios, 인터셉터)

### 2. 전체 User API 화면 연동 완료
-  POST /api/v1/users/login → login/page.tsx
-  POST /api/v1/users/register → register/page.tsx
-  POST /api/v1/users/logout → profile/page.tsx
-  GET /api/v1/users/profile → profile/page.tsx
-  PUT /api/v1/users/profile → profile/page.tsx
-  PUT /api/v1/users/password → profile/page.tsx

### 3. 로그인 페이지 API 연동
- useAuthStore → useAuthContext 변경
- 실제 로그인 API 호출
- 비밀번호 검증 완화 (API 스펙에 맞춤)
- 상세 로깅 추가

### 4. 프로필 페이지 API 연동
- 프로필 자동 로드 (GET /profile)
- 프로필 수정 (PUT /profile)
- 비밀번호 변경 (PUT /password)
- 로그아웃 (POST /logout)
- 전화번호 형식 변환 (01012345678 ↔ 010-1234-5678)

### 5. 로그아웃 에러 처리 개선
- 백엔드 500 에러 발생해도 로컬 상태 정리 후 로그아웃 진행
- 사용자 경험 우선: 정상 로그아웃으로 처리
- 개발자용 상세 에러 로그 출력

### 6. 문서화
- docs/api-integration-complete.md: 전체 연동 완료 보고서
- docs/api-server-issue.md: 백엔드 이슈 상세 보고 (회원가입 타임아웃, 로그아웃 500 에러)
- docs/user-api-integration.md: User API 통합 가이드
- docs/register-api-guide.md: 회원가입 API 가이드

### 7. 에러 처리 강화
- 서버 응답 에러 / 네트워크 에러 / 요청 설정 에러 구분
- 사용자 친화적 에러 메시지
- 전체 프로세스 상세 로깅

## 기술 스택
- FSD Architecture
- React Context API (AuthProvider)
- Axios (인터셉터, 90초 타임아웃)
- Zod (폼 검증)
- TypeScript (엄격한 타입)

## 테스트
-  빌드 성공
-  백엔드 안정화 후 전체 플로우 테스트 필요

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-28 13:18:23 +09:00

263 lines
6.8 KiB
Markdown

# 회원가입 API 연동 가이드
## 개요
회원가입 페이지(`/register`)가 User Service API와 연동되었습니다.
## API 스펙
### 엔드포인트
- **URL**: `POST /api/v1/users/register`
- **Base URL**: `http://20.196.65.160:8081`
### 요청 데이터
```typescript
interface RegisterRequest {
name: string; // 이름 (2-50자)
phoneNumber: string; // 휴대폰 번호 (010으로 시작하는 11자리 숫자)
email: string; // 이메일 (최대 100자)
password: string; // 비밀번호 (8-100자, 영문+숫자 조합)
storeName: string; // 상호명 (최대 100자)
industry?: string; // 업종 (최대 50자, 선택)
address: string; // 주소 (최대 255자)
businessHours?: string; // 영업시간 (최대 255자, 선택)
}
```
### 요청 예시
```json
{
"name": "홍길동",
"phoneNumber": "01012345678",
"email": "hong@example.com",
"password": "password123",
"storeName": "홍길동 고깃집",
"industry": "restaurant",
"address": "서울특별시 강남구 테헤란로 123",
"businessHours": "평일 09:00-18:00, 주말 휴무"
}
```
### 응답 데이터
```typescript
interface RegisterResponse {
token: string; // JWT 토큰
userId: number; // 사용자 ID
userName: string; // 사용자 이름
storeId: number; // 가게 ID
storeName: string; // 가게명
}
```
## 회원가입 페이지 구조
### 3단계 회원가입 프로세스
#### 1단계: 계정 정보
- 이메일
- 비밀번호
- 비밀번호 확인
#### 2단계: 개인 정보
- 이름 (2-50자)
- 휴대폰 번호 (010-1234-5678 형식)
#### 3단계: 사업장 정보
- 상호명 (2-100자)
- 사업자 번호 (123-45-67890 형식) + 인증
- 업종 선택
- 음식점 (restaurant)
- 카페/베이커리 (cafe)
- 소매/편의점 (retail)
- 미용/뷰티 (beauty)
- 헬스/피트니스 (fitness)
- 학원/교육 (education)
- 서비스업 (service)
- 기타 (other)
- 주소 (최대 255자)
- 영업시간 (최대 255자, 선택)
- 약관 동의
- [필수] 이용약관
- [필수] 개인정보 처리방침
- [선택] 마케팅 정보 수신
## 데이터 변환
### 전화번호 형식
- **UI 입력**: `010-1234-5678` (하이픈 포함)
- **API 전송**: `01012345678` (하이픈 제거)
```typescript
const phoneNumber = formData.phone!.replace(/-/g, '');
```
### 업종 코드 매핑
| UI 표시 | API 값 |
|---------|--------|
| 음식점 | restaurant |
| 카페/베이커리 | cafe |
| 소매/편의점 | retail |
| 미용/뷰티 | beauty |
| 헬스/피트니스 | fitness |
| 학원/교육 | education |
| 서비스업 | service |
| 기타 | other |
## 유효성 검증
### 1단계 검증
```typescript
- 이메일: 올바른 이메일 형식
- 비밀번호: 최소 8, 영문+숫자 조합
- 비밀번호 확인: 비밀번호와 일치
```
### 2단계 검증
```typescript
- 이름: 2-50
- 휴대폰: 010-####-#### 형식
```
### 3단계 검증
```typescript
- 상호명: 2-100
- 사업자 번호: ###-##-##### 형식
- 업종: 필수 선택
- 주소: 최대 255
- 영업시간: 최대 255 (선택)
- 이용약관: 필수 동의
- 개인정보 처리방침: 필수 동의
```
## 회원가입 흐름
```mermaid
sequenceDiagram
participant User
participant UI
participant Auth
participant API
User->>UI: 회원정보 입력
UI->>UI: 유효성 검증
UI->>Auth: registerUser(data)
Auth->>API: POST /api/v1/users/register
API-->>Auth: RegisterResponse
Auth-->>UI: { success: true, user }
UI->>UI: 토큰 저장 (localStorage)
UI->>UI: 사용자 정보 저장
UI->>UI: 성공 다이얼로그 표시
User->>UI: "시작하기" 클릭
UI->>User: 메인 페이지로 이동
```
## 에러 처리
### 클라이언트 에러
- 유효성 검증 실패: Toast 메시지로 첫 번째 에러 표시
- 필수 항목 누락: 해당 필드에 에러 메시지 표시
### 서버 에러
- 네트워크 오류: "회원가입 중 오류가 발생했습니다" 메시지
- API 오류: 서버 응답 에러 메시지 또는 기본 메시지
```typescript
try {
const result = await registerUser(registerData);
if (result.success) {
showToast('회원가입이 완료되었습니다!', 'success');
setSuccessDialogOpen(true);
} else {
showToast(result.error || '회원가입에 실패했습니다.', 'error');
}
} catch (error) {
console.error('회원가입 오류:', error);
showToast('회원가입 중 오류가 발생했습니다.', 'error');
}
```
## 회원가입 성공 후
1. **JWT 토큰 저장**: `localStorage.setItem('accessToken', token)`
2. **사용자 정보 저장**: `localStorage.setItem('user', JSON.stringify(user))`
3. **인증 상태 업데이트**: AuthContext의 `isAuthenticated: true`
4. **성공 다이얼로그 표시**: 환영 메시지
5. **메인 페이지 이동**: `/` 경로로 리다이렉트
## 테스트 방법
### 개발 서버 실행
```bash
npm run dev
```
### 테스트 시나리오
#### 정상 케이스
1. `/register` 접속
2. 1단계: 이메일, 비밀번호 입력
3. 2단계: 이름, 휴대폰 번호 입력
4. 3단계: 사업장 정보 입력 및 약관 동의
5. "가입완료" 버튼 클릭
6. 성공 다이얼로그 확인
7. 메인 페이지 이동 확인
#### 에러 케이스
1. **유효성 검증 실패**
- 잘못된 이메일 형식 입력
- 8자 미만 비밀번호
- 비밀번호 불일치
- 잘못된 전화번호 형식
2. **필수 항목 누락**
- 이름 미입력
- 업종 미선택
- 약관 미동의
3. **API 오류 시뮬레이션**
- 네트워크 연결 끊기
- 중복 이메일 사용
## 코드 위치
- **회원가입 페이지**: `src/app/(auth)/register/page.tsx`
- **인증 훅**: `src/features/auth/model/useAuth.ts`
- **User API**: `src/entities/user/api/userApi.ts`
- **타입 정의**: `src/entities/user/model/types.ts`
## 주의사항
1. **전화번호 형식**: UI는 하이픈 포함, API는 하이픈 제거
2. **비밀번호**: 최소 8자 이상, 영문+숫자 조합 필수
3. **이메일**: 로그인 시 사용되므로 정확한 이메일 필요
4. **토큰 관리**: 회원가입 성공 시 자동으로 로그인 처리됨
5. **사업자 번호 인증**: 현재는 클라이언트에서만 검증 (추후 API 연동 필요)
## 환경 변수
`.env.local`에 다음 환경 변수가 설정되어 있어야 합니다:
```env
NEXT_PUBLIC_API_BASE_URL=http://20.196.65.160:8081
NEXT_PUBLIC_USER_HOST=http://20.196.65.160:8081
```
## 개선 사항
### 현재 구현
- ✅ User API 연동
- ✅ 3단계 회원가입 프로세스
- ✅ 실시간 유효성 검증
- ✅ 자동 로그인 처리
- ✅ 성공 다이얼로그
### 향후 개선
- ⏳ 사업자 번호 실제 API 인증
- ⏳ 이메일 중복 확인 API
- ⏳ 이메일 인증 기능
- ⏳ 소셜 로그인 (카카오, 네이버 등)