# task-1035.1 완료 보고서: 대시보드 캠페인뷰 UI 수정 — 채널+예산 통합 표시

## SCQA

**S**: 대시보드 CampaignView.js에서 채널별 현황(Section 2)과 예산 집행 현황이 별도 섹션 2개로 분리되어 있으며, 금액 포맷이 "90만원" 같은 정수 단위만 지원한다.

**C**: 제이회장님 피드백 — "채널별현황이랑 예산 집행현황은 하나로 합해서 보여주면 됨. 바 게이지에 금액(원)+퍼센트 형태로." 현재 구조는 채널 정보와 집행 현황을 왕복해야 해서 한눈에 파악이 어렵다.

**Q**: 채널 카드에 예산 한도+집행률 바 게이지를 통합하여 원클릭 없이 채널별 집행 현황을 파악할 수 있는가?

**A**: CampaignView.js 1개 파일을 수정하여 3가지 변경을 완료했다. (1) formatWon 함수를 3단계 분기(원/만원/억원)로 개선하여 소수점 1자리 표시 지원, (2) 채널 카드에 "한도: XX만원/월" + 집행 바 게이지 "XX만원(XX%)" 통합, (3) 캠페인 개요 섹션에 "이번 달 집행" 블록 추가. 기존 예산 집행 현황 별도 섹션은 완전 제거.

## 수정 파일

- `/home/jay/workspace/dashboard/components/CampaignView.js` (430줄 → 412줄)

## 변경 상세

### 1. formatWon 함수 (라인 4~15)
- 기존: 10,000 이상은 일괄 `Math.round(n/10000) + '만원'` (정수만)
- 변경: 3단계 분기
  - `n >= 100,000,000`: "1.2억원" (소수점 1자리, .0이면 정수)
  - `n >= 10,000`: "12.3만원" (소수점 1자리, .0이면 정수)
  - 그 외: "8,500원" (콤마 포맷)

### 2. 섹션 1 캠페인 개요 (라인 116~126)
- "이번 달 집행" 블록 추가 (emerald 계열 색상)
- `budget_tracking.total_spent / budget.monthly * 100` 퍼센트 표시
- `budget_tracking` 없을 때 조건부 렌더링으로 안전 처리

### 3. 채널 카드 통합 (라인 131~164)
- 기존 `budget_pct` 기반 비율 바 → `channel_spent / monthly_budget` 기반 집행 바로 교체
- 카드 3줄 구조: 아이콘+이름+뱃지 → "한도: XX만원/월" → 바 게이지+"XX만원(XX%)"
- optional chaining(`?.`)으로 budget_tracking 미존재 시 안전 fallback

### 4. 예산 집행 현황 섹션 삭제 (구 라인 143~182)
- 별도 섹션 전체 제거, 채널 카드에 통합됨

## 발견 이슈 및 해결

### 자체 해결 (3건)
1. **formatWon에서 소수점 처리 미흡** — `val % 1 === 0` 체크로 "90만원"(정수)과 "12.3만원"(소수) 자동 분기
2. **channel_spent 키 미존재 시 NaN 발생 가능** — `(data.budget_tracking?.channel_spent?.[ch.id]) || 0` 으로 안전 fallback 처리
3. **monthly_budget이 0일 때 division by zero** — `ch.monthly_budget ? Math.min(100, Math.round(spent / ch.monthly_budget * 100)) : 0` 삼항 연산자로 방어

### 범위 외 미해결 (0건)
없음

## 완료 조건 검증

- [x] 채널별 현황 + 예산 집행 하나로 통합 — 섹션 2에서 통합 카드 렌더링, 별도 예산 섹션 삭제
- [x] 바 게이지에 금액(%) 표시 — `{formatWon(spent)}({spentPct}%)` 형태
- [x] 캠페인 개요에 이번 달 집행 총액 표시 — emerald 색상 블록, total_spent 기반
- [x] 대시보드에서 정상 렌더링 확인 — JSX 문법 오류 없음, 조건부 렌더링 안전 처리 확인

## QC 결과

- file_check: 수정 파일 존재 확인 (28,365 bytes) ✅
- pyright_check: SKIP (JS 파일, Python 아님)
- test_runner: SKIP (관련 테스트 파일 0개)
- style_check: SKIP (Python 아님)

## 머지 판단
- **머지 필요**: No (worktree 미사용, 직접 수정)
