mirror of
https://github.com/ktds-dg0501/kt-event-marketing-fe.git
synced 2025-12-06 08:16:23 +00:00
## 주요 변경사항 ### 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>
263 lines
6.8 KiB
Markdown
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
|
|
- ⏳ 이메일 인증 기능
|
|
- ⏳ 소셜 로그인 (카카오, 네이버 등)
|