mirror of
https://github.com/ktds-dg0501/kt-event-marketing-fe.git
synced 2025-12-06 20:06:24 +00:00
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
21 KiB
21 KiB
정보 아키텍처 설계서
목차
1. 사이트맵
1.1 전체 사이트 구조
KT 이벤트 마케팅 플랫폼
│
├── 🔐 인증 영역 (Public)
│ ├── /login - 로그인
│ ├── /register - 회원가입
│ └── /profile - 프로필 관리
│
├── 🏠 대시보드 영역 (Private)
│ ├── / - 메인 대시보드
│ │ ├── 진행중 이벤트 현황
│ │ ├── 최근 성과 요약
│ │ └── 빠른 작업 버튼
│ │
│ └── /events - 이벤트 목록
│ ├── 전체 이벤트 조회
│ ├── 상태별 필터링 (진행중/예정/종료)
│ └── 검색 기능
│
├── ✨ 이벤트 생성 플로우 (Private)
│ └── /events/create - 이벤트 생성 Funnel
│ ├── Step 1: /events/create?step=objective - 목적 선택
│ ├── Step 2: /events/create?step=recommendation - AI 추천 확인
│ ├── Step 3: /events/create?step=content - 콘텐츠 미리보기
│ ├── Step 4: /events/create?step=edit - 콘텐츠 편집
│ ├── Step 5: /events/create?step=channels - 배포 채널 선택
│ └── Step 6: /events/create?step=publish - 최종 승인
│
└── 📊 이벤트 관리 영역 (Private)
└── /events/[eventId]
├── /events/[eventId] - 이벤트 상세
├── /events/[eventId]/participants - 참여자 목록
├── /events/[eventId]/participate - 고객 참여 화면 (Public)
├── /events/[eventId]/draw - 당첨자 추첨
└── /events/[eventId]/analytics - 성과 분석
1.2 네비게이션 흐름
Bottom Navigation (인증 후 모든 화면)
┌─────────────────────────────────────────────────┐
│ 홈 이벤트 분석 프로필 │
│ / /events /analytics /profile │
└─────────────────────────────────────────────────┘
주요 사용자 여정
여정 1: 신규 이벤트 생성
/ (대시보드)
→ [+ 새 이벤트 생성] 버튼 클릭
→ /events/create?step=objective (목적 선택)
→ /events/create?step=recommendation (AI 추천)
→ /events/create?step=content (미리보기)
→ /events/create?step=edit (편집)
→ /events/create?step=channels (채널 선택)
→ /events/create?step=publish (승인)
→ /events/[eventId] (생성 완료, 상세 페이지)
여정 2: 이벤트 관리 및 분석
/events (이벤트 목록)
→ [이벤트 카드] 클릭
→ /events/[eventId] (상세)
├── [참여자 관리] → /events/[eventId]/participants
├── [당첨자 추첨] → /events/[eventId]/draw
└── [성과 분석] → /events/[eventId]/analytics
여정 3: 고객 참여
QR 코드 스캔 또는 링크 접속
→ /events/[eventId]/participate (참여 화면)
→ 참여 정보 입력
→ 참여 완료
1.3 접근 권한 설정
| 페이지 경로 | 접근 권한 | 인증 필요 | 설명 |
|---|---|---|---|
/login |
Public | ❌ | 로그인 페이지 |
/register |
Public | ❌ | 회원가입 페이지 |
/ |
Private | ✅ | 메인 대시보드 |
/events |
Private | ✅ | 이벤트 목록 |
/events/create |
Private | ✅ | 이벤트 생성 플로우 |
/events/[eventId] |
Private | ✅ | 이벤트 상세 |
/events/[eventId]/participants |
Private | ✅ | 참여자 관리 |
/events/[eventId]/draw |
Private | ✅ | 당첨자 추첨 |
/events/[eventId]/analytics |
Private | ✅ | 성과 분석 |
/events/[eventId]/participate |
Public | ❌ | 고객 참여 화면 |
/profile |
Private | ✅ | 프로필 관리 |
2. 프로젝트 구조 설계
2.1 Next.js 14 App Router 기반 디렉토리 구조
fe-kt-event-marketing/
│
├── 📁 app/ # Next.js 14 App Router
│ ├── (auth)/ # 인증 레이아웃 그룹
│ │ ├── login/
│ │ │ └── page.tsx # 로그인 페이지
│ │ ├── register/
│ │ │ └── page.tsx # 회원가입 페이지
│ │ └── layout.tsx # 인증 전용 레이아웃
│ │
│ ├── (main)/ # 메인 레이아웃 그룹 (인증 필요)
│ │ ├── page.tsx # 대시보드 (/)
│ │ ├── events/
│ │ │ ├── page.tsx # 이벤트 목록
│ │ │ ├── create/
│ │ │ │ └── page.tsx # 이벤트 생성 Funnel
│ │ │ └── [eventId]/
│ │ │ ├── page.tsx # 이벤트 상세
│ │ │ ├── participants/
│ │ │ │ └── page.tsx # 참여자 목록
│ │ │ ├── draw/
│ │ │ │ └── page.tsx # 당첨자 추첨
│ │ │ └── analytics/
│ │ │ └── page.tsx # 성과 분석
│ │ ├── profile/
│ │ │ └── page.tsx # 프로필 관리
│ │ └── layout.tsx # 메인 레이아웃 (Bottom Nav 포함)
│ │
│ ├── events/ # Public 이벤트 경로
│ │ └── [eventId]/
│ │ └── participate/
│ │ └── page.tsx # 고객 참여 화면 (인증 불필요)
│ │
│ ├── api/ # API Routes (서버 컴포넌트)
│ │ └── auth/
│ │ └── [...nextauth]/
│ │ └── route.ts # NextAuth API 라우트
│ │
│ ├── layout.tsx # 루트 레이아웃
│ ├── error.tsx # 전역 에러 핸들링
│ ├── loading.tsx # 전역 로딩 상태
│ └── not-found.tsx # 404 페이지
│
├── 📁 src/
│ ├── components/ # React 컴포넌트
│ │ ├── common/ # 공통 컴포넌트
│ │ │ ├── Button/
│ │ │ │ ├── Button.tsx
│ │ │ │ └── Button.test.tsx
│ │ │ ├── Card/
│ │ │ │ └── Card.tsx
│ │ │ ├── Input/
│ │ │ │ └── Input.tsx
│ │ │ ├── Layout/
│ │ │ │ ├── BottomNavigation.tsx
│ │ │ │ ├── Header.tsx
│ │ │ │ └── Container.tsx
│ │ │ └── Loading/
│ │ │ └── Loading.tsx
│ │ │
│ │ ├── auth/ # 인증 관련 컴포넌트
│ │ │ ├── LoginForm.tsx
│ │ │ ├── RegisterForm.tsx
│ │ │ └── ProfileForm.tsx
│ │ │
│ │ ├── dashboard/ # 대시보드 컴포넌트
│ │ │ ├── EventSummaryCard.tsx
│ │ │ ├── PerformanceChart.tsx
│ │ │ └── QuickActions.tsx
│ │ │
│ │ ├── event/ # 이벤트 관련 컴포넌트
│ │ │ ├── EventCard.tsx
│ │ │ ├── EventList.tsx
│ │ │ ├── EventDetail.tsx
│ │ │ ├── ParticipantTable.tsx
│ │ │ └── WinnerDrawModal.tsx
│ │ │
│ │ └── funnel/ # Funnel 관련 컴포넌트
│ │ ├── ObjectiveStep.tsx
│ │ ├── RecommendationStep.tsx
│ │ ├── ContentStep.tsx
│ │ ├── EditStep.tsx
│ │ ├── ChannelsStep.tsx
│ │ ├── PublishStep.tsx
│ │ └── FunnelLayout.tsx
│ │
│ ├── hooks/ # Custom React Hooks
│ │ ├── useAuth.ts # 인증 상태 관리
│ │ ├── useEvent.ts # 이벤트 CRUD
│ │ ├── useEventList.ts # 이벤트 목록
│ │ ├── useParticipants.ts # 참여자 관리
│ │ ├── useJobPolling.ts # Job 상태 폴링
│ │ └── useToast.ts # Toast 알림
│ │
│ ├── lib/ # 라이브러리 및 유틸리티
│ │ ├── api/ # API 클라이언트
│ │ │ ├── client.ts # Axios 인스턴스
│ │ │ ├── auth.ts # 인증 API
│ │ │ ├── events.ts # 이벤트 API
│ │ │ └── participants.ts # 참여 API
│ │ │
│ │ ├── utils/ # 유틸리티 함수
│ │ │ ├── format.ts # 날짜/숫자 포맷팅
│ │ │ ├── validation.ts # 폼 검증 헬퍼
│ │ │ └── storage.ts # localStorage 헬퍼
│ │ │
│ │ └── constants/ # 상수 정의
│ │ ├── api.ts # API 엔드포인트
│ │ ├── routes.ts # 라우트 경로
│ │ └── event.ts # 이벤트 상수
│ │
│ ├── store/ # 상태 관리 (Zustand)
│ │ ├── authStore.ts # 인증 상태
│ │ ├── funnelStore.ts # Funnel 임시 저장
│ │ └── uiStore.ts # UI 상태 (Toast, Modal 등)
│ │
│ ├── styles/ # 스타일
│ │ ├── globals.css # 전역 스타일
│ │ └── theme.ts # MUI 테마 설정
│ │
│ └── types/ # TypeScript 타입 정의
│ ├── auth.ts # 인증 관련 타입
│ ├── event.ts # 이벤트 타입
│ ├── participant.ts # 참여자 타입
│ └── api.ts # API 응답 타입
│
├── 📁 public/ # 정적 파일
│ ├── images/ # 이미지 파일
│ ├── icons/ # 아이콘 파일
│ └── runtime-env.js # 런타임 환경 변수
│
├── 📁 tests/ # 테스트 파일
│ ├── unit/ # 단위 테스트
│ ├── integration/ # 통합 테스트
│ └── e2e/ # E2E 테스트 (Playwright)
│
├── .env.local # 로컬 환경 변수
├── .env.development # 개발 환경 변수
├── .env.production # 프로덕션 환경 변수
├── next.config.js # Next.js 설정
├── tsconfig.json # TypeScript 설정
├── package.json # 의존성 관리
└── README.md # 프로젝트 문서
2.2 주요 파일 설명
2.2.1 레이아웃 구조
app/layout.tsx (루트 레이아웃)
// React Query Provider, MUI ThemeProvider, Toast Provider 설정
export default function RootLayout({ children }) {
return (
<html lang="ko">
<body>
<QueryClientProvider>
<ThemeProvider theme={theme}>
<CssBaseline />
{children}
</ThemeProvider>
</QueryClientProvider>
</body>
</html>
);
}
app/(main)/layout.tsx (메인 레이아웃)
// Bottom Navigation 포함 레이아웃
// 인증 체크 미들웨어
export default function MainLayout({ children }) {
return (
<>
<Header />
<Container>{children}</Container>
<BottomNavigation />
</>
);
}
app/(auth)/layout.tsx (인증 레이아웃)
// 로고 중심의 심플한 레이아웃
export default function AuthLayout({ children }) {
return (
<Container maxWidth="sm">
<Logo />
{children}
</Container>
);
}
2.2.2 Funnel 구현
app/(main)/events/create/page.tsx
'use client';
import { useFunnel } from '@use-funnel/next';
import { ObjectiveStep, RecommendationStep, ... } from '@/components/funnel';
export default function EventCreatePage() {
const [Funnel, state, setStep] = useFunnel({
id: 'event-creation',
initial: 'objective',
});
return (
<Funnel>
<Funnel.Step name="objective">
<ObjectiveStep onNext={() => setStep('recommendation')} />
</Funnel.Step>
<Funnel.Step name="recommendation">
<RecommendationStep
onNext={() => setStep('content')}
onBack={() => setStep('objective')}
/>
</Funnel.Step>
{/* ... 나머지 Step들 */}
</Funnel>
);
}
2.2.3 API 클라이언트
src/lib/api/client.ts
import axios from 'axios';
// runtime-env.js에서 환경 변수 로드
declare global {
interface Window {
__runtime_config__: {
API_GROUP: string;
USER_HOST: string;
EVENT_HOST: string;
CONTENT_HOST: string;
AI_HOST: string;
PARTICIPATION_HOST: string;
DISTRIBUTION_HOST: string;
ANALYTICS_HOST: string;
};
}
}
const config = window.__runtime_config__;
// 1. User Service API Client (인증, 프로필)
export const userClient = axios.create({
baseURL: `${config.USER_HOST}${config.API_GROUP}`,
timeout: 10000,
});
// 2. Event Service API Client (이벤트 생명주기 관리)
export const eventClient = axios.create({
baseURL: `${config.EVENT_HOST}${config.API_GROUP}`,
timeout: 30000, // AI/이미지 생성 Job 폴링 고려
});
// 3. Content Service API Client (이미지 생성 및 편집)
export const contentClient = axios.create({
baseURL: `${config.CONTENT_HOST}${config.API_GROUP}`,
timeout: 30000, // 이미지 생성 Job 폴링
});
// 4. AI Service API Client (AI 추천 생성)
export const aiClient = axios.create({
baseURL: `${config.AI_HOST}${config.API_GROUP}`,
timeout: 30000, // AI 생성 Job 폴링
});
// 5. Participation Service API Client (참여자/당첨자 관리)
export const participationClient = axios.create({
baseURL: `${config.PARTICIPATION_HOST}${config.API_GROUP}`,
timeout: 10000,
});
// 6. Distribution Service API Client (다중 채널 배포)
export const distributionClient = axios.create({
baseURL: `${config.DISTRIBUTION_HOST}${config.API_GROUP}`,
timeout: 20000, // 다중 채널 배포 시간 고려
});
// 7. Analytics Service API Client (성과 분석 및 대시보드)
export const analyticsClient = axios.create({
baseURL: `${config.ANALYTICS_HOST}${config.API_GROUP}`,
timeout: 10000,
});
2.3 컴포넌트 재사용 전략
Atomic Design 기반 컴포넌트 계층
Atoms (원자)
└── Button, Input, Icon, Typography
↓
Molecules (분자)
└── SearchBar, EventCard, ParticipantRow
↓
Organisms (유기체)
└── EventList, ParticipantTable, Dashboard
↓
Templates (템플릿)
└── MainLayout, AuthLayout, FunnelLayout
↓
Pages (페이지)
└── HomePage, EventListPage, EventCreatePage
MUI 컴포넌트 커스터마이징
// src/components/common/Button/Button.tsx
import { Button as MuiButton, ButtonProps } from '@mui/material';
export const Button: React.FC<ButtonProps> = (props) => {
return (
<MuiButton
variant="contained"
color="primary"
sx={{
borderRadius: '8px',
textTransform: 'none',
fontWeight: 600,
...props.sx,
}}
{...props}
/>
);
};
2.4 상태 관리 전략
| 상태 유형 | 관리 도구 | 사용 사례 |
|---|---|---|
| 서버 상태 | React Query v5 | API 데이터 캐싱, 자동 재검증 |
| 전역 클라이언트 상태 | Zustand | 인증 상태, UI 상태 (Toast, Modal) |
| 로컬 상태 | useState | 컴포넌트 내부 상태 |
| 폼 상태 | React Hook Form | 폼 입력, 검증 |
| Funnel 상태 | @use-funnel/next | Step 전환, 데이터 임시 저장 |
2.5 라우팅 및 미들웨어
middleware.ts (Next.js Middleware)
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const token = request.cookies.get('accessToken');
const { pathname } = request.nextUrl;
// 인증이 필요한 경로
const protectedRoutes = ['/', '/events', '/profile'];
const isProtectedRoute = protectedRoutes.some(route =>
pathname.startsWith(route)
);
// 인증되지 않은 사용자가 보호된 경로 접근 시 로그인으로 리다이렉트
if (isProtectedRoute && !token) {
return NextResponse.redirect(new URL('/login', request.url));
}
// 인증된 사용자가 로그인/회원가입 접근 시 대시보드로 리다이렉트
if ((pathname === '/login' || pathname === '/register') && token) {
return NextResponse.redirect(new URL('/', request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
};
2.6 환경 변수 관리
.env.local
# 로컬 개발 환경
NEXT_PUBLIC_USER_HOST=http://localhost:8081
NEXT_PUBLIC_EVENT_HOST=http://localhost:8080
NEXT_PUBLIC_CONTENT_HOST=http://localhost:8082
NEXT_PUBLIC_AI_HOST=http://localhost:8083
NEXT_PUBLIC_PARTICIPATION_HOST=http://localhost:8084
NEXT_PUBLIC_DISTRIBUTION_HOST=http://localhost:8085
NEXT_PUBLIC_ANALYTICS_HOST=http://localhost:8086
NEXT_PUBLIC_API_VERSION=v1
.env.production
# 프로덕션 환경
NEXT_PUBLIC_USER_HOST=https://api.kt-event-marketing.com/user/v1
NEXT_PUBLIC_EVENT_HOST=https://api.kt-event-marketing.com/event/v1
NEXT_PUBLIC_CONTENT_HOST=https://api.kt-event-marketing.com/content/v1
NEXT_PUBLIC_AI_HOST=https://api.kt-event-marketing.com/ai/v1
NEXT_PUBLIC_PARTICIPATION_HOST=https://api.kt-event-marketing.com/participation/v1
NEXT_PUBLIC_DISTRIBUTION_HOST=https://api.kt-event-marketing.com/distribution/v1
NEXT_PUBLIC_ANALYTICS_HOST=https://api.kt-event-marketing.com/analytics/v1
NEXT_PUBLIC_API_VERSION=v1
public/runtime-env.js
window.__runtime_config__ = {
API_GROUP: "/api/v1",
// 7개 마이크로서비스 호스트
USER_HOST: process.env.NEXT_PUBLIC_USER_HOST || "http://localhost:8081",
EVENT_HOST: process.env.NEXT_PUBLIC_EVENT_HOST || "http://localhost:8080",
CONTENT_HOST: process.env.NEXT_PUBLIC_CONTENT_HOST || "http://localhost:8082",
AI_HOST: process.env.NEXT_PUBLIC_AI_HOST || "http://localhost:8083",
PARTICIPATION_HOST: process.env.NEXT_PUBLIC_PARTICIPATION_HOST || "http://localhost:8084",
DISTRIBUTION_HOST: process.env.NEXT_PUBLIC_DISTRIBUTION_HOST || "http://localhost:8085",
ANALYTICS_HOST: process.env.NEXT_PUBLIC_ANALYTICS_HOST || "http://localhost:8086",
};
3. 기술 스택 정리
| 카테고리 | 기술 | 버전 | 용도 |
|---|---|---|---|
| Framework | Next.js | 14.x | App Router, SSR, SSG |
| Library | React | 18.x | UI 라이브러리 |
| Language | TypeScript | 5.x | 정적 타입 검사 |
| UI Framework | Material-UI (MUI) | 6.x | UI 컴포넌트 |
| State (Server) | React Query | 5.x | 서버 상태 관리 |
| State (Client) | Zustand | 4.x | 전역 상태 관리 |
| Form | React Hook Form | 7.x | 폼 관리 |
| Validation | Zod | 3.x | 스키마 검증 |
| Funnel | @use-funnel/next | 1.x | Funnel 상태 관리 |
| HTTP Client | Axios | 1.x | API 통신 |
| Charts | Chart.js | 4.x | 데이터 시각화 |
| Testing | Jest, Playwright | - | 단위/E2E 테스트 |
4. 배포 및 환경 설정
4.1 개발 환경
npm run dev # 개발 서버 실행 (localhost:3000)
npm run build # 프로덕션 빌드
npm run start # 프로덕션 서버 실행
npm run lint # ESLint 검사
npm run test # Jest 단위 테스트
npm run test:e2e # Playwright E2E 테스트
4.2 빌드 최적화
- Code Splitting: 동적 import로 번들 크기 최적화
- Image Optimization: Next.js Image 컴포넌트 사용
- Font Optimization: next/font로 웹폰트 최적화
- Tree Shaking: 사용하지 않는 코드 제거
4.3 성능 모니터링
- Lighthouse: 성능, 접근성, SEO 점수
- Web Vitals: LCP, FID, CLS 측정
- Bundle Analyzer: 번들 크기 분석
5. 접근성 및 반응형 설계
5.1 반응형 브레이크포인트
// src/styles/theme.ts
const breakpoints = {
xs: 0, // Mobile: 320px ~ 599px
sm: 600, // Tablet: 600px ~ 1023px
md: 1024, // Desktop: 1024px ~ 1439px
lg: 1440, // Large Desktop: 1440px+
};
5.2 접근성 준수 (WCAG 2.1 AA)
- 키보드 네비게이션: Tab, Enter, Space 지원
- 스크린 리더: aria-label, role 속성
- 색상 대비: 최소 4.5:1 비율
- 포커스 표시: 명확한 focus 상태
- 대체 텍스트: 모든 이미지에 alt 속성
문서 버전: 1.0 작성일: 2025-01-24 작성자: Frontend Design Team