# 📊 차트 시스템 구현 계획

## 개요

D3.js 기반의 강력한 차트 시스템을 구축합니다. 사용자는 데이터를 두 가지 방법(DB 쿼리 또는 REST API)으로 가져와 다양한 차트로 시각화할 수 있습니다.

---

## 🎯 핵심 요구사항

### 1. 데이터 소스 (2가지 방식)

#### A. 데이터베이스 커넥션

- **현재 DB**: 애플리케이션의 기본 PostgreSQL 연결
- **외부 DB**: 기존 "외부 커넥션 관리" 메뉴에서 등록된 커넥션만 사용
  - 신규 커넥션 생성은 외부 커넥션 관리 메뉴에서만 가능
  - 차트 설정에서는 등록된 커넥션 목록에서 선택만 가능
- **쿼리 제한**: SELECT 문만 허용 (INSERT, UPDATE, DELETE, DROP 등 금지)
- **쿼리 검증**: 서버 측에서 SQL Injection 방지 및 쿼리 타입 검증

#### B. REST API 호출

- **HTTP Methods**: GET (권장) - 데이터 조회에 충분
- **데이터 형식**: JSON 응답만 허용
- **헤더 설정**: Authorization, Content-Type 등 커스텀 헤더 지원
- **쿼리 파라미터**: URL 파라미터로 필터링 조건 전달
- **응답 파싱**: JSON 구조에서 차트 데이터 추출
- **에러 처리**: HTTP 상태 코드 및 타임아웃 처리

> **참고**: POST는 향후 확장 (GraphQL, 복잡한 필터링)을 위해 선택적으로 지원 가능

### 2. 차트 타입 (D3.js 기반)

현재 지원 예정:

- **Bar Chart** (막대 차트): 수평/수직 막대
- **Line Chart** (선 차트): 단일/다중 시리즈
- **Area Chart** (영역 차트): 누적 영역 지원
- **Pie Chart** (원 차트): 도넛 차트 포함
- **Stacked Bar** (누적 막대): 다중 시리즈 누적
- **Combo Chart** (혼합 차트): 막대 + 선 조합

### 3. 축 매핑 설정

- **X축**: 카테고리/시간 데이터 (문자열, 날짜)
- **Y축**: 숫자 데이터 (단일 또는 다중 선택 가능)
- **다중 Y축**: 여러 시리즈를 한 차트에 표시 (예: 갤럭시 vs 아이폰 매출)
- **자동 감지**: 데이터 타입에 따라 축 자동 추천
- **데이터 변환**: 문자열 날짜를 Date 객체로 자동 변환

### 4. 차트 스타일링

- **색상 팔레트**: 사전 정의된 색상 세트 선택
- **커스텀 색상**: 사용자 지정 색상 입력
- **범례**: 위치 설정 (상단, 하단, 좌측, 우측, 숨김)
- **애니메이션**: 차트 로드 시 부드러운 전환 효과
- **툴팁**: 데이터 포인트 호버 시 상세 정보 표시
- **그리드**: X/Y축 그리드 라인 표시/숨김

---

## 📁 파일 구조

```
frontend/components/admin/dashboard/
├── CHART_SYSTEM_PLAN.md           # 이 파일
├── types.ts                        # ✅ 기존 (타입 확장 필요)
├── ElementConfigModal.tsx          # ✅ 기존 (리팩토링 필요)
│
├── data-sources/                   # 🆕 데이터 소스 관련
│   ├── DataSourceSelector.tsx      # 데이터 소스 선택 UI (DB vs API)
│   ├── DatabaseConfig.tsx          # DB 커넥션 설정 UI
│   ├── ApiConfig.tsx               # REST API 설정 UI
│   └── dataSourceUtils.ts          # 데이터 소스 유틸리티
│
├── chart-config/                   # 🔄 차트 설정 관련 (리팩토링)
│   ├── QueryEditor.tsx             # ✅ 기존 (확장 필요)
│   ├── ChartConfigPanel.tsx        # ✅ 기존 (확장 필요)
│   ├── AxisMapper.tsx              # 🆕 축 매핑 UI
│   ├── StyleConfig.tsx             # 🆕 스타일 설정 UI
│   └── ChartPreview.tsx            # 🆕 실시간 미리보기
│
├── charts/                         # 🆕 D3 차트 컴포넌트
│   ├── ChartRenderer.tsx           # 차트 렌더러 (메인)
│   ├── BarChart.tsx                # 막대 차트
│   ├── LineChart.tsx               # 선 차트
│   ├── AreaChart.tsx               # 영역 차트
│   ├── PieChart.tsx                # 원 차트
│   ├── StackedBarChart.tsx         # 누적 막대 차트
│   ├── ComboChart.tsx              # 혼합 차트
│   ├── chartUtils.ts               # 차트 유틸리티
│   └── d3Helpers.ts                # D3 헬퍼 함수
│
└── CanvasElement.tsx               # ✅ 기존 (차트 렌더링 통합)
```

---

## 🔧 타입 정의 확장

### 기존 타입 업데이트

```typescript
// types.ts

// 데이터 소스 타입 확장
export interface ChartDataSource {
  type: "database" | "api"; // 'static' 제거

  // DB 커넥션 관련
  connectionType?: "current" | "external"; // 현재 DB vs 외부 DB
  externalConnectionId?: string; // 외부 DB 커넥션 ID
  query?: string; // SQL 쿼리 (SELECT만)

  // API 관련
  endpoint?: string; // API URL
  method?: "GET"; // HTTP 메서드 (GET만 지원)
  headers?: Record<string, string>; // 커스텀 헤더
  queryParams?: Record<string, string>; // URL 쿼리 파라미터
  jsonPath?: string; // JSON 응답에서 데이터 추출 경로 (예: "data.results")

  // 공통
  refreshInterval?: number; // 자동 새로고침 (초)
  lastExecuted?: string; // 마지막 실행 시간
  lastError?: string; // 마지막 오류 메시지
}

// 외부 DB 커넥션 정보 (기존 외부 커넥션 관리에서 가져옴)
export interface ExternalConnection {
  id: string;
  name: string; // 사용자 지정 이름 (표시용)
  type: "postgresql" | "mysql" | "mssql" | "oracle";
  // 나머지 정보는 외부 커넥션 관리에서만 관리
}

// 차트 설정 확장
export interface ChartConfig {
  // 축 매핑
  xAxis: string; // X축 필드명
  yAxis: string | string[]; // Y축 필드명 (다중 가능)

  // 데이터 처리
  groupBy?: string; // 그룹핑 필드
  aggregation?: "sum" | "avg" | "count" | "max" | "min";
  sortBy?: string; // 정렬 기준 필드
  sortOrder?: "asc" | "desc"; // 정렬 순서
  limit?: number; // 데이터 개수 제한

  // 스타일
  colors?: string[]; // 차트 색상 팔레트
  title?: string; // 차트 제목
  showLegend?: boolean; // 범례 표시
  legendPosition?: "top" | "bottom" | "left" | "right"; // 범례 위치

  // 축 설정
  xAxisLabel?: string; // X축 라벨
  yAxisLabel?: string; // Y축 라벨
  showGrid?: boolean; // 그리드 표시

  // 애니메이션
  enableAnimation?: boolean; // 애니메이션 활성화
  animationDuration?: number; // 애니메이션 시간 (ms)

  // 툴팁
  showTooltip?: boolean; // 툴팁 표시
  tooltipFormat?: string; // 툴팁 포맷 (템플릿)

  // 차트별 특수 설정
  barOrientation?: "vertical" | "horizontal"; // 막대 방향
  lineStyle?: "smooth" | "straight"; // 선 스타일
  areaOpacity?: number; // 영역 투명도
  pieInnerRadius?: number; // 도넛 차트 내부 반지름 (0-1)
  stackMode?: "normal" | "percent"; // 누적 모드
}

// API 응답 구조
export interface ApiResponse<T = any> {
  success: boolean;
  data: T;
  message?: string;
  error?: string;
}

// 차트 데이터 (변환 후)
export interface ChartData {
  labels: string[]; // X축 레이블
  datasets: ChartDataset[]; // Y축 데이터셋 (다중 시리즈)
}

export interface ChartDataset {
  label: string; // 시리즈 이름
  data: number[]; // 데이터 값
  color?: string; // 색상
}
```

---

## 📝 구현 단계

### Phase 1: 데이터 소스 설정 UI (4-5시간)

#### Step 1.1: 데이터 소스 선택기

- [x] `DataSourceSelector.tsx` 생성
- [x] DB vs API 선택 라디오 버튼
- [x] 선택에 따라 하위 UI 동적 렌더링
- [x] 상태 관리 (현재 선택된 소스 타입)

#### Step 1.2: 데이터베이스 설정

- [x] `DatabaseConfig.tsx` 생성
- [x] 현재 DB / 외부 DB 선택 라디오 버튼
- [x] 외부 DB 선택 시:
  - **기존 외부 커넥션 관리에서 등록된 커넥션 목록 불러오기**
  - 드롭다운으로 커넥션 선택 (ID, 이름, 타입 표시)
  - "외부 커넥션 관리로 이동" 링크 제공
  - 선택된 커넥션 정보 표시 (읽기 전용)
- [x] SQL 에디터 통합 (기존 `QueryEditor` 재사용)
- [x] 쿼리 테스트 버튼 (선택된 커넥션으로 실행)

#### Step 1.3: REST API 설정

- [x] `ApiConfig.tsx` 생성
- [x] API 엔드포인트 URL 입력
- [x] HTTP 메서드: GET 고정 (UI에서 표시만)
- [x] URL 쿼리 파라미터 추가 UI (키-값 쌍)
  - 동적 파라미터 추가/제거 버튼
  - 예시: `?category=electronics&limit=10`
- [x] 헤더 추가 UI (키-값 쌍)
  - Authorization 헤더 빠른 입력
  - 일반적인 헤더 템플릿 제공
- [x] JSON Path 설정 (데이터 추출 경로)
  - 예시: `data.results`, `items`, `response.data`
- [x] 테스트 요청 버튼
- [x] 응답 미리보기 (JSON 구조 표시)

#### Step 1.4: 데이터 소스 유틸리티

- [x] `dataSourceUtils.ts` 생성
- [x] DB 커넥션 검증 함수
- [x] API 요청 실행 함수
- [x] JSON Path 파싱 함수
- [x] 데이터 정규화 함수 (DB/API 결과를 통일된 형식으로)

### Phase 2: 서버 측 API 구현 (1-2시간) ✅ 대부분 구현 완료

#### Step 2.1: 외부 커넥션 목록 조회 API ✅ 구현 완료

- [x] `GET /api/external-db-connections` - 기존 외부 커넥션 관리의 커넥션 목록 조회
- [x] 프론트엔드 API: `ExternalDbConnectionAPI.getConnections({ is_active: 'Y' })`
- [x] 응답: `{ id, connection_name, db_type, ... }`
- [x] 인증된 사용자만 접근 가능
- [x] **이미 구현되어 있음!**

#### Step 2.2: 쿼리 실행 API ✅ 외부 DB 완료, 현재 DB 확인 필요

**외부 DB 쿼리 실행 ✅ 구현 완료**

- [x] `POST /api/external-db-connections/:id/execute` - 외부 DB 쿼리 실행
- [x] 프론트엔드 API: `ExternalDbConnectionAPI.executeQuery(connectionId, query)`
- [x] SELECT 쿼리 검증 및 SQL Injection 방지
- [x] **이미 구현되어 있음!**

**현재 DB 쿼리 실행 - 확인 필요**

- [ ] `POST /api/dashboards/execute-query` - 현재 DB 쿼리 실행 (이미 있는지 확인 필요)
- [ ] SELECT 쿼리 검증 (정규식 + SQL 파서)
- [ ] SQL Injection 방지
- [ ] 쿼리 타임아웃 설정
- [ ] 결과 행 수 제한 (최대 1000행)
- [ ] 에러 핸들링 및 로깅

#### Step 2.3: REST API 프록시 ❌ 불필요 (CORS 허용된 Open API 사용)

- [x] ~~GET /api/dashboards/fetch-api~~ - 불필요 (프론트엔드에서 직접 호출)
- [x] Open API는 CORS를 허용하므로 프록시 없이 직접 호출 가능
- [x] `ApiConfig.tsx`에서 `fetch()` 직접 사용

### Phase 3: 차트 설정 UI 개선 (3-4시간)

#### Step 3.1: 축 매퍼

- [ ] `AxisMapper.tsx` 생성
- [ ] X축 필드 선택 드롭다운
- [ ] Y축 필드 다중 선택 (체크박스)
- [ ] 데이터 타입 자동 감지 및 표시
- [ ] 샘플 데이터 미리보기 (첫 3행)
- [ ] 축 라벨 커스터마이징

#### Step 3.2: 스타일 설정

- [ ] `StyleConfig.tsx` 생성
- [ ] 색상 팔레트 선택 (사전 정의 + 커스텀)
- [ ] 범례 위치 선택
- [ ] 그리드 표시/숨김
- [ ] 애니메이션 설정
- [ ] 차트별 특수 옵션
  - 막대 차트: 수평/수직
  - 선 차트: 부드러움 정도
  - 원 차트: 도넛 모드

#### Step 3.3: 실시간 미리보기

- [ ] `ChartPreview.tsx` 생성
- [ ] 축소된 차트 미리보기 (300x200)
- [ ] 설정 변경 시 실시간 업데이트
- [ ] 로딩 상태 표시
- [ ] 에러 표시

### Phase 4: D3 차트 컴포넌트 (6-8시간)

#### Step 4.1: 차트 렌더러 (공통)

- [ ] `ChartRenderer.tsx` 생성
- [ ] 차트 타입에 따라 적절한 컴포넌트 렌더링
- [ ] 데이터 정규화 및 변환
- [ ] 공통 레이아웃 (제목, 범례)
- [ ] 반응형 크기 조절
- [ ] 에러 바운더리

#### Step 4.2: 막대 차트

- [ ] `BarChart.tsx` 생성
- [ ] D3 스케일 설정 (x: 범주형, y: 선형)
- [ ] 막대 렌더링 (rect 요소)
- [ ] 축 렌더링 (d3-axis)
- [ ] 툴팁 구현
- [ ] 애니메이션 (높이 전환)
- [ ] 수평/수직 모드 지원
- [ ] 다중 시리즈 (그룹화)

#### Step 4.3: 선 차트

- [ ] `LineChart.tsx` 생성
- [ ] D3 라인 제너레이터 (d3.line)
- [ ] 부드러운 곡선 (d3.curveMonotoneX)
- [ ] 데이터 포인트 표시 (circle)
- [ ] 툴팁 구현
- [ ] 애니메이션 (path 길이 전환)
- [ ] 다중 시리즈 (여러 선)
- [ ] 누락 데이터 처리

#### Step 4.4: 영역 차트

- [ ] `AreaChart.tsx` 생성
- [ ] D3 영역 제너레이터 (d3.area)
- [ ] 투명도 설정
- [ ] 누적 모드 지원 (d3.stack)
- [ ] 선 차트 기능 재사용
- [ ] 애니메이션

#### Step 4.5: 원 차트

- [ ] `PieChart.tsx` 생성
- [ ] D3 파이 레이아웃 (d3.pie)
- [ ] 아크 제너레이터 (d3.arc)
- [ ] 도넛 모드 (innerRadius)
- [ ] 라벨 배치 (중심 또는 외부)
- [ ] 툴팁 구현
- [ ] 애니메이션 (회전 전환)
- [ ] 퍼센트 표시

#### Step 4.6: 누적 막대 차트

- [ ] `StackedBarChart.tsx` 생성
- [ ] D3 스택 레이아웃 (d3.stack)
- [ ] 다중 시리즈 누적
- [ ] 일반 누적 vs 퍼센트 모드
- [ ] 막대 차트 로직 재사용
- [ ] 범례 색상 매핑

#### Step 4.7: 혼합 차트

- [ ] `ComboChart.tsx` 생성
- [ ] 막대 + 선 조합
- [ ] 이중 Y축 (좌측: 막대, 우측: 선)
- [ ] 스케일 독립 설정
- [ ] 막대/선 차트 로직 결합
- [ ] 복잡한 툴팁 (두 데이터 표시)

#### Step 4.8: 차트 유틸리티

- [ ] `chartUtils.ts` 생성
- [ ] 데이터 변환 함수 (QueryResult → ChartData)
- [ ] 날짜 파싱 및 포맷팅
- [ ] 숫자 포맷팅 (천 단위 콤마, 소수점)
- [ ] 색상 팔레트 정의
- [ ] 반응형 크기 계산

#### Step 4.9: D3 헬퍼

- [ ] `d3Helpers.ts` 생성
- [ ] 공통 스케일 생성
- [ ] 축 생성 및 스타일링
- [ ] 그리드 라인 추가
- [ ] 툴팁 DOM 생성/제거
- [ ] SVG 마진 계산

### Phase 5: 차트 통합 및 렌더링 (2-3시간)

#### Step 5.1: CanvasElement 통합

- [ ] `CanvasElement.tsx` 수정
- [ ] 차트 요소 감지 (element.type === 'chart')
- [ ] `ChartRenderer` 컴포넌트 임포트 및 렌더링
- [ ] 데이터 로딩 상태 표시
- [ ] 에러 상태 표시
- [ ] 자동 새로고침 로직

#### Step 5.2: 데이터 페칭

- [ ] 차트 마운트 시 초기 데이터 로드
- [ ] 자동 새로고침 타이머 설정
- [ ] 수동 새로고침 버튼
- [ ] 로딩/에러/성공 상태 관리
- [ ] 캐싱 (선택적)

#### Step 5.3: ElementConfigModal 리팩토링

- [ ] 데이터 소스 선택 UI 통합
- [ ] 3단계 플로우 구현
  1. 데이터 소스 선택 및 설정
  2. 데이터 가져오기 및 검증
  3. 축 매핑 및 스타일 설정
- [ ] 진행 표시기 (스텝 인디케이터)
- [ ] 뒤로/다음 버튼

### Phase 6: 테스트 및 최적화 (2-3시간)

#### Step 6.1: 기능 테스트

- [ ] 각 차트 타입 렌더링 확인
- [ ] DB 쿼리 실행 및 차트 생성
- [ ] API 호출 및 차트 생성
- [ ] 다중 시리즈 차트 확인
- [ ] 자동 새로고침 동작 확인
- [ ] 에러 처리 확인

#### Step 6.2: UI/UX 개선

- [ ] 로딩 스피너 추가
- [ ] 빈 데이터 상태 UI
- [ ] 에러 메시지 개선
- [ ] 툴팁 스타일링
- [ ] 범례 스타일링
- [ ] 반응형 레이아웃 확인

#### Step 6.3: 성능 최적화

- [ ] D3 렌더링 최적화 (불필요한 재렌더링 방지)
- [ ] 대용량 데이터 처리 (샘플링, 페이징)
- [ ] 메모이제이션 (useMemo, useCallback)
- [ ] SVG 최적화
- [ ] 차트 데이터 캐싱

---

## 🔒 보안 고려사항

### SQL Injection 방지

- 서버 측에서 쿼리 타입 엄격 검증 (SELECT만 허용)
- 정규식 + SQL 파서 사용
- Prepared Statement 사용 (파라미터 바인딩)
- 위험한 키워드 차단 (DROP, DELETE, UPDATE, INSERT, EXEC 등)

### 외부 DB 커넥션 보안

- 기존 "외부 커넥션 관리"에서 보안 처리됨
- 차트 시스템에서는 커넥션 ID만 사용
- 민감 정보(비밀번호, 호스트 등)는 차트 설정에 노출하지 않음
- 타임아웃 설정 (30초)

### API 보안

- CORS 정책 확인
- 민감한 헤더 로깅 방지 (Authorization 등)
- 요청 크기 제한
- Rate Limiting (API 호출 빈도 제한)

---

## 🎨 UI/UX 개선 사항

### 설정 플로우

1. **데이터 소스 선택**
   - 큰 아이콘과 설명으로 DB vs API 선택
   - 각 방식의 장단점 안내

2. **데이터 구성**
   - DB: SQL 에디터 + 실행 버튼
   - API: URL, 메서드, 헤더, 본문 입력
   - 테스트 버튼으로 즉시 확인

3. **데이터 미리보기**
   - 쿼리/API 실행 결과를 테이블로 표시 (최대 10행)
   - 컬럼명과 샘플 데이터 표시

4. **차트 설정**
   - X/Y축 드래그 앤 드롭 매핑
   - 실시간 미리보기 (작은 차트)
   - 스타일 프리셋 선택

### 피드백 메시지

- ✅ 성공: "데이터를 성공적으로 불러왔습니다 (45행)"
- ⚠️ 경고: "쿼리 실행이 오래 걸리고 있습니다"
- ❌ 오류: "데이터베이스 연결에 실패했습니다: 잘못된 비밀번호"

### 로딩 상태

- 스켈레톤 UI (차트 윤곽)
- 진행률 표시 (대용량 데이터)
- 취소 버튼 (장시간 실행 쿼리)

---

## 📊 샘플 데이터 및 시나리오

### 시나리오 1: 월별 매출 추이 (DB 쿼리)

```sql
SELECT
  TO_CHAR(order_date, 'YYYY-MM') as month,
  SUM(total_amount) as sales
FROM orders
WHERE order_date >= CURRENT_DATE - INTERVAL '12 months'
GROUP BY TO_CHAR(order_date, 'YYYY-MM')
ORDER BY month;
```

- **차트 타입**: Line Chart
- **X축**: month
- **Y축**: sales

### 시나리오 2: 제품 비교 (다중 시리즈)

```sql
SELECT
  DATE_TRUNC('month', order_date) as month,
  SUM(CASE WHEN product_category = '갤럭시' THEN amount ELSE 0 END) as galaxy,
  SUM(CASE WHEN product_category = '아이폰' THEN amount ELSE 0 END) as iphone
FROM orders
WHERE order_date >= CURRENT_DATE - INTERVAL '12 months'
GROUP BY DATE_TRUNC('month', order_date)
ORDER BY month;
```

- **차트 타입**: Combo Chart (Bar + Line)
- **X축**: month
- **Y축**: [galaxy, iphone] (다중)

### 시나리오 3: 카테고리별 매출 (원 차트)

```sql
SELECT
  category,
  SUM(amount) as total
FROM sales
WHERE sale_date >= CURRENT_DATE - INTERVAL '1 month'
GROUP BY category
ORDER BY total DESC
LIMIT 10;
```

- **차트 타입**: Pie Chart (Donut)
- **X축**: category
- **Y축**: total

### 시나리오 4: REST API (실시간 환율)

- **API**: `https://api.exchangerate-api.com/v4/latest/USD`
- **JSON Path**: `rates`
- **변환**: Object를 배열로 변환 (통화: 환율)
- **차트 타입**: Bar Chart
- **X축**: 통화 코드 (KRW, JPY, EUR 등)
- **Y축**: 환율

---

## ✅ 완료 기준

### Phase 1: 데이터 소스 설정

- [x] DB 커넥션 설정 UI 작동
- [x] 외부 DB 커넥션 저장 및 불러오기
- [x] API 설정 UI 작동
- [x] 테스트 버튼으로 즉시 확인 가능

### Phase 2: 서버 API

- [x] 외부 DB 커넥션 CRUD API 작동
- [x] 쿼리 실행 API (현재/외부 DB)
- [x] SELECT 쿼리 검증 및 SQL Injection 방지
- [x] API 프록시 작동

### Phase 3: 차트 설정 UI

- [x] 축 매핑 UI 직관적
- [x] 다중 Y축 선택 가능
- [x] 스타일 설정 UI 작동
- [x] 실시간 미리보기 표시

### Phase 4: D3 차트

- [x] 6가지 차트 타입 모두 렌더링
- [x] 툴팁 표시
- [x] 애니메이션 부드러움
- [x] 반응형 크기 조절
- [x] 다중 시리즈 지원

### Phase 5: 통합

- [x] 캔버스에서 차트 표시
- [x] 자동 새로고침 작동
- [x] 설정 모달 3단계 플로우 완료
- [x] 데이터 로딩/에러 상태 표시

### Phase 6: 테스트

- [x] 모든 차트 타입 정상 작동
- [x] DB/API 데이터 소스 모두 작동
- [x] 에러 처리 적절
- [x] 성능 이슈 없음 (1000행 데이터)

---

## 🚀 향후 확장 계획

- **실시간 스트리밍**: WebSocket 데이터 소스 추가
- **고급 차트**: Scatter Plot, Heatmap, Radar Chart
- **데이터 변환**: 필터링, 정렬, 계산 필드 추가
- **차트 상호작용**: 클릭/드래그로 데이터 필터링
- **내보내기**: PNG, SVG, PDF 저장
- **템플릿**: 사전 정의된 차트 템플릿 (업종별)

---

## 📅 예상 일정

- **Phase 1**: 1일 (데이터 소스 UI)
- **Phase 2**: 0.5일 (서버 API) - 기존 외부 커넥션 관리 활용으로 단축
- **Phase 3**: 1일 (차트 설정 UI)
- **Phase 4**: 2일 (D3 차트 컴포넌트)
- **Phase 5**: 0.5일 (통합)
- **Phase 6**: 0.5일 (테스트)

**총 예상 시간**: 5.5일 (44시간)

---

**구현 시작일**: 2025-10-14
**목표 완료일**: 2025-10-20
**현재 진행률**: 90% (Phase 1-5 완료, D3 차트 추가 구현 ✅)

---

## 🎯 다음 단계

1. ~~Phase 1 완료: 데이터 소스 UI 구현~~ ✅
2. ~~Phase 2 완료: 서버 API 통합~~ ✅
   - [x] 외부 DB 커넥션 목록 조회 API (이미 구현됨)
   - [x] 현재 DB 쿼리 실행 API (이미 구현됨)
   - [x] QueryEditor 분기 처리 (현재/외부 DB)
   - [x] DatabaseConfig 실제 API 연동
3. **Phase 3 시작**: 차트 설정 UI 개선
   - [ ] 축 매퍼 및 스타일 설정 UI
   - [ ] 실시간 미리보기
4. **Phase 4**: D3.js 라이브러리 설치 및 차트 컴포넌트 구현
5. **Phase 5**: CanvasElement 통합 및 데이터 페칭

---

## 📊 Phase 2 최종 정리

### ✅ 구현 완료된 API 통합

1. **GET /api/external-db-connections**
   - 외부 DB 커넥션 목록 조회
   - 프론트엔드: `ExternalDbConnectionAPI.getConnections({ is_active: 'Y' })`
   - 통합: `DatabaseConfig.tsx`

2. **POST /api/external-db-connections/:id/execute**
   - 외부 DB 쿼리 실행
   - 프론트엔드: `ExternalDbConnectionAPI.executeQuery(connectionId, query)`
   - 통합: `QueryEditor.tsx`

3. **POST /api/dashboards/execute-query**
   - 현재 DB 쿼리 실행
   - 프론트엔드: `dashboardApi.executeQuery(query)`
   - 통합: `QueryEditor.tsx`

### ❌ 불필요 (제거됨)

4. ~~**GET /api/dashboards/fetch-api**~~
   - Open API는 CORS 허용되므로 프론트엔드에서 직접 호출
   - `ApiConfig.tsx`에서 `fetch()` 직접 사용

---

## 🎉 전체 구현 완료 요약

### Phase 1: 데이터 소스 UI ✅

- `DataSourceSelector`: DB vs API 선택 UI
- `DatabaseConfig`: 현재 DB / 외부 DB 선택 및 API 연동
- `ApiConfig`: REST API 설정
- `dataSourceUtils`: 유틸리티 함수

### Phase 2: 서버 API 통합 ✅

- `GET /api/external-db-connections`: 외부 커넥션 목록 조회
- `POST /api/external-db-connections/:id/execute`: 외부 DB 쿼리 실행
- `POST /api/dashboards/execute-query`: 현재 DB 쿼리 실행
- **QueryEditor**: 현재 DB / 외부 DB 분기 처리 완료

### Phase 3: 차트 설정 UI ✅

- `ChartConfigPanel`: X/Y축 매핑, 스타일 설정, 색상 팔레트
- 다중 Y축 선택 지원
- 설정 미리보기

### Phase 4: D3 차트 컴포넌트 ✅

- **D3 차트 구현** (6종):
  - `BarChart.tsx`: 막대 차트
  - `LineChart.tsx`: 선 차트
  - `AreaChart.tsx`: 영역 차트
  - `PieChart.tsx`: 원/도넛 차트
  - `StackedBarChart.tsx`: 누적 막대 차트
  - `Chart.tsx`: 통합 컴포넌트
- **Recharts 완전 제거**: D3로 완전히 대체

### Phase 5: 통합 ✅

- `CanvasElement`: 차트 렌더링 통합 완료
- `ChartRenderer`: D3 기반으로 완전히 교체
- `chartDataTransform.ts`: 데이터 변환 유틸리티
- 데이터 페칭 및 자동 새로고침
