cherry2250 6331ab3fde Analytics API 프록시 라우트 구현 및 CORS 오류 해결
- Next.js API 프록시 라우트 8개 생성 (User/Event Analytics)
- analyticsClient baseURL을 프록시 경로로 변경
- analyticsApi 경로에서 /api/v1 접두사 제거
- 404/400 에러에 대한 사용자 친화적 에러 처리 추가
- Dashboard, Event Detail, Analytics 페이지 에러 핸들링 개선

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 00:34:20 +09:00

248 lines
11 KiB
Markdown

# 📍 KT 이벤트 마케팅 - 전체 페이지 라우트 목록
## 🔐 인증 라우트 (auth)
**Route Group**: `(auth)` - AuthGuard 미적용
| 라우트 | 파일 경로 | 설명 | 320px 최적화 |
|--------|-----------|------|-------------|
| `/login` | `(auth)/login/page.tsx` | 로그인 페이지 | ✅ 완료 |
| `/register` | `(auth)/register/page.tsx` | 회원가입 페이지 | ✅ 완료 |
| `/logout` | `(auth)/logout/page.tsx` | 로그아웃 페이지 | ✅ 완료 |
---
## 🏠 메인 애플리케이션 라우트 (main)
**Route Group**: `(main)` - AuthGuard 적용, BottomNavigation 포함
### 대시보드 & 분석
| 라우트 | 파일 경로 | 설명 | 320px 최적화 |
|--------|-----------|------|-------------|
| `/` | `(main)/page.tsx` | 메인 대시보드 | ✅ 완료 |
| `/analytics` | `(main)/analytics/page.tsx` | 전체 분석 페이지 | ✅ 완료 |
| `/profile` | `(main)/profile/page.tsx` | 사용자 프로필 | ✅ 완료 |
### 이벤트 관리
| 라우트 | 파일 경로 | 설명 | 320px 최적화 |
|--------|-----------|------|-------------|
| `/events` | `(main)/events/page.tsx` | 이벤트 목록 | ✅ 완료 |
| `/events/create` | `(main)/events/create/page.tsx` | 이벤트 생성 (Funnel 방식) | ✅ 완료 |
| `/events/create/content-test` | `(main)/events/create/content-test/page.tsx` | 콘텐츠 테스트 페이지 | ✅ 완료 |
### 이벤트 상세 (동적 라우트)
| 라우트 | 파일 경로 | 설명 | 320px 최적화 |
|--------|-----------|------|-------------|
| `/events/[eventId]` | `(main)/events/[eventId]/page.tsx` | 이벤트 상세 페이지 | ✅ 완료 |
| `/events/[eventId]/participate` | `(main)/events/[eventId]/participate/page.tsx` | 이벤트 참여 페이지 | ✅ 완료 |
| `/events/[eventId]/participants` | `(main)/events/[eventId]/participants/page.tsx` | 참여자 관리 페이지 | ✅ 완료 |
| `/events/[eventId]/draw` | `(main)/events/[eventId]/draw/page.tsx` | 추첨 페이지 | ✅ 완료 |
### 테스트 페이지
| 라우트 | 파일 경로 | 설명 | 320px 최적화 |
|--------|-----------|------|-------------|
| `/test/analytics/[eventId]` | `(main)/test/analytics/[eventId]/page.tsx` | 분석 테스트 페이지 | ✅ 완료 |
---
## 🔌 API 라우트
### User API (v1)
| 라우트 | 파일 경로 | HTTP Method |
|--------|-----------|-------------|
| `/api/v1/users/login` | `api/v1/users/login/route.ts` | POST |
| `/api/v1/users/logout` | `api/v1/users/logout/route.ts` | POST |
| `/api/v1/users/register` | `api/v1/users/register/route.ts` | POST |
| `/api/v1/users/profile` | `api/v1/users/profile/route.ts` | GET, PUT |
| `/api/v1/users/password` | `api/v1/users/password/route.ts` | PUT |
### Event API (v1)
| 라우트 | 파일 경로 | HTTP Method |
|--------|-----------|-------------|
| `/api/v1/events/objectives` | `api/v1/events/objectives/route.ts` | POST |
| `/api/v1/events/[eventId]/participate` | `api/v1/events/[eventId]/participate/route.ts` | POST |
| `/api/v1/events/[eventId]/participants` | `api/v1/events/[eventId]/participants/route.ts` | GET |
| `/api/v1/events/[eventId]/participants/[participantId]` | `api/v1/events/[eventId]/participants/[participantId]/route.ts` | GET, PATCH |
| `/api/v1/events/[eventId]/draw-winners` | `api/v1/events/[eventId]/draw-winners/route.ts` | POST |
| `/api/v1/events/[eventId]/winners` | `api/v1/events/[eventId]/winners/route.ts` | GET |
### Participation API (프록시)
백엔드 Participation Service로 프록시하는 API 라우트
| 라우트 | 파일 경로 | HTTP Method |
|--------|-----------|-------------|
| `/api/participations/[eventId]/participate` | `api/participations/[eventId]/participate/route.ts` | POST |
| `/api/participations/[eventId]/participants` | `api/participations/[eventId]/participants/route.ts` | GET |
| `/api/participations/[eventId]/participants/[participantId]` | `api/participations/[eventId]/participants/[participantId]/route.ts` | GET, PATCH |
| `/api/participations/[eventId]/draw-winners` | `api/participations/[eventId]/draw-winners/route.ts` | POST |
| `/api/participations/[eventId]/winners` | `api/participations/[eventId]/winners/route.ts` | GET |
### Distribution API
| 라우트 | 파일 경로 | HTTP Method |
|--------|-----------|-------------|
| `/api/distribution/[eventId]/status` | `api/distribution/[eventId]/status/route.ts` | GET |
---
## 📊 이벤트 생성 Funnel Steps
`/events/create` 페이지는 `@use-funnel/browser`를 사용한 Funnel 방식으로 다음 단계들을 포함합니다:
### Step 흐름
```
objective → recommendation → channel → contentPreview/contentEdit → approval
```
### 각 단계 상세
| Step | Component | URL Query | 설명 |
|------|-----------|-----------|------|
| 1 | `ObjectiveStep` | `?event-creation.step=objective` | 이벤트 목적 선택 (신규고객/재방문/매출/인지도) |
| 2 | `RecommendationStep` | `?event-creation.step=recommendation` | AI 추천 이벤트 3가지 옵션 제시 및 선택 |
| 3 | `ChannelStep` | `?event-creation.step=channel` | 배포 채널 선택 (우리동네TV, 지니TV, SNS 등) |
| 4a | `ContentPreviewStep` | `?event-creation.step=contentPreview` | 콘텐츠 미리보기 (채널에 콘텐츠 필요 시) |
| 4b | `ContentEditStep` | `?event-creation.step=contentEdit` | 콘텐츠 편집 (사용자가 수정 선택 시) |
| 5 | `ApprovalStep` | `?event-creation.step=approval` | 최종 이벤트 검토 및 승인 |
### Step 분기 로직
- **우리동네TV, 지니TV, SNS** 채널 선택 시 → `contentPreview` 단계로 이동
- 기타 채널만 선택 시 → `approval` 단계로 바로 이동
- `contentPreview`에서 "수정하기" 선택 시 → `contentEdit` 단계로 이동
---
## 🔒 인증 보호 정책
### AuthGuard 적용
- **(main)** Route Group: **AuthGuard 적용**
- 로그인 필수
- `isAuthenticated && user` 체크
- 미인증 시 자동으로 `/login`으로 리다이렉트
- BottomNavigation 포함
### AuthGuard 미적용
- **(auth)** Route Group: 인증 없이 접근 가능
- `/login`, `/register`, `/logout`
### 구현 위치
- AuthGuard 컴포넌트: `src/features/auth/ui/AuthGuard.tsx`
- Layout 적용: `src/app/(main)/layout.tsx`
---
## 🗂️ 프로젝트 구조
```
src/app/
├── (auth)/ # 인증 관련 페이지 (AuthGuard 미적용)
│ ├── login/
│ ├── register/
│ └── logout/
├── (main)/ # 메인 애플리케이션 (AuthGuard 적용)
│ ├── page.tsx # 대시보드
│ ├── layout.tsx # AuthGuard + BottomNavigation
│ ├── analytics/
│ ├── profile/
│ ├── events/
│ │ ├── page.tsx
│ │ ├── create/
│ │ │ ├── page.tsx # Funnel 메인
│ │ │ ├── steps/ # Funnel 각 단계 컴포넌트
│ │ │ └── content-test/
│ │ └── [eventId]/
│ │ ├── page.tsx
│ │ ├── participate/
│ │ ├── participants/
│ │ └── draw/
│ └── test/
│ └── analytics/[eventId]/
└── api/ # API 라우트 (프록시)
├── v1/
│ ├── users/
│ └── events/
├── participations/
└── distribution/
```
---
## 📝 참고사항
### Next.js 14 App Router 특징
- Route Groups: `(auth)`, `(main)` - URL에 포함되지 않는 논리적 그룹
- Dynamic Routes: `[eventId]`, `[participantId]` - 동적 세그먼트
- API Routes: `route.ts` 파일로 API 엔드포인트 구현
- Layouts: 각 라우트 그룹별 공통 레이아웃 적용
### 최근 변경사항
- ✅ AI 추천 로직 변경: Job 폴링 방식 → POST `/events/{eventId}/ai-recommendations` 직접 호출
- ✅ AuthGuard 적용: (main) 그룹 전체에 로그인 필수 적용
- ✅ 로그인 페이지: 지원하지 않는 기능 Toast → Modal 변경
- ✅ 320px 모바일 최적화: 모든 페이지 완료 (2025-10-30)
---
## 📱 320px 모바일 최적화 내역
### 최적화 내용
1. **Container Padding 조정**: `px: { xs: 6 }``px: { xs: 2 }`
- 320px 화면에서 좌우 패딩 48px → 16px로 줄여 콘텐츠 영역 확보
- 실제 콘텐츠 영역: 224px → 288px (29% 증가)
2. **Grid Spacing 조정**: 큰 spacing 값을 반응형으로 조정
- `spacing={6}``spacing={{ xs: 2, sm: 6 }}`
3. **Typography 크기 조정**: 작은 화면에서 적절한 폰트 크기 적용
- 제목: `fontSize: '2rem'``fontSize: { xs: '1.5rem', sm: '2rem' }`
- 본문: `fontSize: '1rem'``fontSize: { xs: '0.875rem', sm: '1rem' }`
4. **Vertical Spacing 대폭 축소**: 320px에서 과도한 상하 여백 문제 해결
- **Container Padding**: `pt: 8, pb: 8``pt: { xs: 4, sm: 8 }, pb: { xs: 4, sm: 8 }` (64px → 32px)
- **Box Padding Bottom**: `pb: 10``pb: { xs: 4, sm: 10 }` (80px → 32px)
- **Large Margin Bottom**: `mb: 10``mb: { xs: 4, sm: 10 }` (80px → 32px)
- **Medium Margin Bottom**: `mb: 8``mb: { xs: 3, sm: 8 }` (64px → 24px)
- **CardContent Padding**:
- `p: 8``p: { xs: 3, sm: 8 }` (64px → 24px)
- `p: 6``p: { xs: 3, sm: 6 }` (48px → 24px)
- `p: 5``p: { xs: 2.5, sm: 5 }` (40px → 20px)
- `py: 6``pt: { xs: 3, sm: 6 }, pb: { xs: 3, sm: 6 }` (상하 각 48px → 24px)
- `py: { xs: 4, sm: 6 }``pt: { xs: 2, sm: 6 }, pb: { xs: 2, sm: 6 }` (상하 각 32px → 16px)
- `py: { xs: 2, sm: 6 }``pt: { xs: 1.5, sm: 6 }, pb: { xs: 1.5, sm: 6 }` (상하 각 16px → 12px)
- **총 효과**: 상하 여백이 평균 50-60% 감소하여 320px 화면에서 콘텐츠 밀도 향상
5. **Margin/Gap 조정**: 불필요하게 큰 여백 줄임
- `gap: 3``gap: { xs: 2, sm: 3 }`
### 영향받은 페이지
- 모든 인증 페이지 (login, register, logout)
- 모든 이벤트 생성 단계 (ObjectiveStep, RecommendationStep, ChannelStep, ContentPreviewStep, ContentEditStep, ApprovalStep)
- 이벤트 상세 페이지들 (detail, participate, participants, draw)
- 대시보드 및 프로필 페이지
### 참여자 관리 페이지 추가 최적화 (2025-10-30)
**검색 및 필터 UI 최적화**:
- Search TextField: 아이콘 18px, 폰트 0.75rem, 패딩 8px
- FilterList 아이콘: 28px → 20px
- FormControl: minWidth 100px/90px, 폰트 0.75rem, 패딩 8px
- MenuItem: 폰트 0.75rem
**버튼 최적화**:
- 아이콘: 20px → 16px
- 폰트: 0.875rem → 0.7rem
- 패딩: px 4→1.5, py 1.5→0.75
- 텍스트 단축: "엑셀 다운로드"→"엑셀", "당첨자 추첨"→"추첨" (320px만)
**Pagination 최적화**:
- 폰트: 1rem → 0.75rem
- 버튼 크기: 32px → 26px
- 아이콘: 1.5rem → 1rem
- 여백: 4px → 2px
**통계 카드**:
- Grid: xs={6} → xs={4} (한 줄에 3개 표시)
- 카드 내부 요소 크기 축소 (아이콘, 폰트, 패딩)
### 빌드 확인
```bash
npm run build
# ✅ 빌드 성공 (2025-10-30)
```