mirror of
https://github.com/ktds-dg0501/kt-event-marketing-fe.git
synced 2025-12-06 18:06:24 +00:00
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
615 lines
21 KiB
Markdown
615 lines
21 KiB
Markdown
# 정보 아키텍처 설계서
|
|
|
|
## 목차
|
|
1. [사이트맵](#1-사이트맵)
|
|
2. [프로젝트 구조 설계](#2-프로젝트-구조-설계)
|
|
|
|
---
|
|
|
|
## 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** (루트 레이아웃)
|
|
```typescript
|
|
// 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** (메인 레이아웃)
|
|
```typescript
|
|
// Bottom Navigation 포함 레이아웃
|
|
// 인증 체크 미들웨어
|
|
export default function MainLayout({ children }) {
|
|
return (
|
|
<>
|
|
<Header />
|
|
<Container>{children}</Container>
|
|
<BottomNavigation />
|
|
</>
|
|
);
|
|
}
|
|
```
|
|
|
|
**app/(auth)/layout.tsx** (인증 레이아웃)
|
|
```typescript
|
|
// 로고 중심의 심플한 레이아웃
|
|
export default function AuthLayout({ children }) {
|
|
return (
|
|
<Container maxWidth="sm">
|
|
<Logo />
|
|
{children}
|
|
</Container>
|
|
);
|
|
}
|
|
```
|
|
|
|
#### 2.2.2 Funnel 구현
|
|
|
|
**app/(main)/events/create/page.tsx**
|
|
```typescript
|
|
'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**
|
|
```typescript
|
|
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 컴포넌트 커스터마이징
|
|
|
|
```typescript
|
|
// 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)
|
|
```typescript
|
|
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**
|
|
```javascript
|
|
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 개발 환경
|
|
```bash
|
|
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 반응형 브레이크포인트
|
|
```typescript
|
|
// 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
|