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

11 KiB

📍 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: 8pt: { xs: 4, sm: 8 }, pb: { xs: 4, sm: 8 } (64px → 32px)
    • Box Padding Bottom: pb: 10pb: { xs: 4, sm: 10 } (80px → 32px)
    • Large Margin Bottom: mb: 10mb: { xs: 4, sm: 10 } (80px → 32px)
    • Medium Margin Bottom: mb: 8mb: { xs: 3, sm: 8 } (64px → 24px)
    • CardContent Padding:
      • p: 8p: { xs: 3, sm: 8 } (64px → 24px)
      • p: 6p: { xs: 3, sm: 6 } (48px → 24px)
      • p: 5p: { xs: 2.5, sm: 5 } (40px → 20px)
      • py: 6pt: { 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: 3gap: { 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개 표시)
  • 카드 내부 요소 크기 축소 (아이콘, 폰트, 패딩)

빌드 확인

npm run build
# ✅ 빌드 성공 (2025-10-30)