# Dashboard API 연동 개발 계획

> **작성일**: 2026-01-20
> **목적**: CEO Dashboard 페이지의 목업 데이터 → 실제 API 연동
> **Serena ID**: dashboard-api-state

---

## 📍 현재 상태 요약

```
┌─────────────────────────────────────────────────────────────────┐
│  전체 진행률: 45% (5/11 섹션 완료)                               │
├─────────────────────────────────────────────────────────────────┤
│  ✅ Phase 1 완료 - 기존 API 연동 (프론트엔드)                    │
│  ⏳ Phase 2 대기 - 신규 API 개발 필요 (백엔드)                   │
└─────────────────────────────────────────────────────────────────┘
```

| 구분 | 섹션 | 데이터 소스 | 상태 |
|:---:|------|:----------:|:----:|
| Phase 1 | 일일 일보 (DailyReport) | API | ✅ |
| Phase 1 | 미수금 현황 (Receivable) | API | ✅ |
| Phase 1 | 채권추심 현황 (DebtCollection) | API | ✅ |
| Phase 1 | 당월 예상 지출 (MonthlyExpense) | API | ✅ |
| Phase 1 | 카드/가지급금 관리 (CardManagement) | API | ✅ |
| **Phase 2** | **오늘의 이슈 (TodayIssue)** | mockData | ⏳ |
| **Phase 2** | **현황판 (StatusBoard)** | mockData | ⏳ |
| **Phase 2** | **접대비 현황 (Entertainment)** | mockData | ⏳ |
| **Phase 2** | **복리후생비 현황 (Welfare)** | mockData | ⏳ |
| **Phase 2** | **부가세 현황 (Vat)** | mockData | ⏳ |
| **Phase 2** | **캘린더 (Calendar)** | mockData | ⏳ |

---

## Phase 1 완료 내역

### 생성된 파일

| 파일 | 설명 |
|------|------|
| `react/src/lib/api/dashboard/types.ts` | API 응답 타입 정의 (5개 엔드포인트) |
| `react/src/lib/api/dashboard/transformers.ts` | API → Frontend 변환 함수 + CheckPoint 생성 |
| `react/src/hooks/useCEODashboard.ts` | 통합 Dashboard Hook (병렬 API 호출) |
| `react/src/lib/api/dashboard/index.ts` | 모듈 export |

### 수정된 파일

| 파일 | 변경 내용 |
|------|----------|
| `CEODashboard.tsx` | `useCEODashboard` Hook 연동, mockData fallback 패턴 |

### 연동된 API 엔드포인트

| 섹션 | 프론트 호출 경로 | 백엔드 실제 경로 |
|------|-----------------|-----------------|
| DailyReport | `/api/proxy/daily-report/summary` | `DailyReportService::summary()` |
| Receivable | `/api/proxy/receivables/summary` | `ReceivablesService::summary()` |
| DebtCollection | `/api/proxy/bad-debts/summary` | `BadDebtService::summary()` |
| MonthlyExpense | `/api/proxy/expected-expenses/summary` | `ExpectedExpenseService::summary()` |
| CardManagement | `/api/proxy/card-transactions/summary` | `CardTransactionService::summary()` |

### API 불일치 사항 (fallback 처리)

| 섹션 | 이슈 | 처리 방식 |
|------|------|----------|
| MonthlyExpense | `by_transaction_type` 필드로 제공 | purchase/card/bill 키로 분류 |
| CardManagement | 가지급금, 법인세 예상 가중 등 미제공 | mockData fallback 사용 |

---

## Phase 2 개발 계획 (신규 API 필요)

### 2.1 오늘의 이슈 (TodayIssue)

#### 기능 설명

대시보드 상단에 표시되는 실시간 이벤트 목록. 각 이벤트는 뱃지, 내용, 시간, 관련 페이지 링크로 구성.

#### 현재 mockData 구조

```
todayIssueList: [
  {
    id: string,
    badge: string,           // "수주 성공", "주식 이슈", "직정 제고", "세금 신고", "결재 요청", "기타"
    content: string,         // "A전자 신규 수주 450,000,000원 확정"
    time: string,            // "10분 전", "1시간 전", "어제"
    date: string,            // "2026-01-16"
    needsApproval: boolean,  // 결재 필요 여부
    path: string             // 관련 페이지 경로
  }
]
```

#### 개발 방향 제안

**방향 A: 통합 이벤트 테이블 신규 생성**

| 장점 | 단점 |
|------|------|
| 단일 API로 모든 이슈 조회 가능 | 신규 테이블 설계 필요 |
| 이벤트 타입별 필터링 용이 | 각 도메인에서 이벤트 생성 로직 추가 필요 |
| 확장성 좋음 | 실시간성 유지를 위한 트리거/큐 필요 |

```
테이블: dashboard_events
- id, tenant_id
- event_type: enum (order, receivable, stock, tax, approval, etc.)
- badge: string
- content: string
- metadata: json (금액, 거래처명 등)
- related_path: string
- needs_approval: boolean
- created_at
```

**방향 B: 각 도메인 API 조합 (Aggregation)**

| 장점 | 단점 |
|------|------|
| 기존 API 재활용 | 여러 API 호출 필요 (성능) |
| 신규 테이블 불필요 | 프론트에서 데이터 병합 로직 필요 |
| 도메인별 독립성 유지 | 일관된 포맷 변환 필요 |

```
호출할 API 목록:
- /orders/recent-events (수주)
- /receivables/overdue-alerts (미수금 연체)
- /stock/low-alerts (재고 부족)
- /tax/deadlines (세금 신고 기한)
- /approvals/pending (결재 대기)
```

**방향 C: 이벤트 큐 기반 실시간 시스템**

| 장점 | 단점 |
|------|------|
| 실시간 푸시 가능 | 인프라 복잡도 증가 |
| 확장성 최고 | Redis/Queue 추가 필요 |
| 알림 시스템과 통합 가능 | 개발 공수 큼 |

#### 데이터 소스 후보

| 뱃지 | 데이터 소스 | 조건 |
|------|------------|------|
| 수주 성공 | `orders` 테이블 | status = 'confirmed', 최근 N일 |
| 주식 이슈 (미수금) | `receivables` 테이블 | overdue_days > 0 |
| 직정 제고 (재고) | `stock_items` 테이블 | quantity < safety_stock |
| 세금 신고 | `tax_schedules` 테이블 | deadline 임박 |
| 결재 요청 | `approvals` 테이블 | status = 'pending' |
| 지출예상내역서 | `expense_requests` 테이블 | status = 'pending' |

#### 권장 사항

- **MVP**: 방향 B (기존 API 조합)로 시작
- **확장**: 추후 방향 A로 마이그레이션 고려

---

### 2.2 현황판 (StatusBoard)

#### 기능 설명

각 업무 영역별 미처리 건수를 카드 형태로 표시. 클릭 시 해당 페이지로 이동.

#### 현재 mockData 구조

```
todayIssue: [
  {
    id: string,
    label: string,        // "수주", "채권 추심", "안전 재고" 등
    count: number|string, // 3 또는 "부가세 신고 D-15"
    path: string,         // 이동할 페이지 경로
    isHighlighted: boolean // 강조 표시 여부
  }
]
```

#### 개발 방향 제안

**방향 A: 단일 집계 API**

```
GET /api/dashboard/status-board

응답:
{
  items: [
    { key: "orders", label: "수주", count: 3, path: "/sales/order-management-sales" },
    { key: "debt_collection", label: "채권 추심", count: 3, path: "/accounting/bad-debt-collection" },
    { key: "safety_stock", label: "안전 재고", count: 3, path: "/material/stock-status", isHighlighted: true },
    { key: "tax_report", label: "세금 신고", count: "부가세 신고 D-15", path: "/accounting/tax" },
    ...
  ]
}
```

| 장점 | 단점 |
|------|------|
| 단일 API 호출 | 백엔드에서 여러 테이블 집계 필요 |
| 프론트 로직 단순 | 새 항목 추가 시 백엔드 수정 필요 |

**방향 B: 설정 기반 동적 집계**

```
1. dashboard_status_items 테이블에 항목 정의
2. 각 항목별 count_query (SQL 또는 서비스 메서드) 지정
3. API에서 동적으로 집계하여 반환
```

| 장점 | 단점 |
|------|------|
| 관리자가 항목 추가/수정 가능 | 구현 복잡도 증가 |
| 유연성 높음 | 쿼리 성능 관리 필요 |

#### 집계 대상 테이블

| 항목 | 테이블 | 집계 조건 |
|------|--------|----------|
| 수주 | `orders` | status = 'pending' AND tenant_id |
| 채권 추심 | `bad_debts` | status IN ('collecting', 'legal_action') |
| 안전 재고 | `stock_items` | quantity < safety_stock |
| 세금 신고 | `tax_schedules` | D-day 계산 |
| 신규 업체 등록 | `vendors` | status = 'pending_approval' |
| 연차 | `vacation_requests` | status = 'pending' |
| 발주 | `purchase_orders` | status = 'pending' |
| 결재 요청 | `approvals` | status = 'pending' |

#### 권장 사항

- 방향 A로 시작 (단일 집계 API)
- 항목은 하드코딩으로 시작, 추후 설정 테이블로 분리 가능

---

### 2.3 접대비 현황 (Entertainment)

#### 기능 설명

세무 규정에 따른 접대비 한도 및 사용 현황. 분기별 한도 관리 필요.

#### 현재 mockData 구조

```
entertainment: {
  cards: [
    { label: "매출", amount: 30530000000 },
    { label: "{1사분기} 접대비 총 한도", amount: 40123000 },
    { label: "{1사분기} 접대비 잔여한도", amount: 30123000 },
    { label: "{1사분기} 접대비 사용금액", amount: 10000000 }
  ],
  checkPoints: [...] // AI 분석 메시지
}
```

#### 세무 규정 (접대비 한도 계산)

```
기본 한도: 3,600만원 (중소기업 기준)
매출 추가 한도:
- 100억 이하: 매출 × 0.3%
- 100~500억: 100억 초과분 × 0.2%
- 500억 초과: 500억 초과분 × 0.03%

분기별 한도 = 연간 한도 ÷ 4
```

#### 개발 방향 제안

**방향 A: 전용 서비스 클래스**

```
EntertainmentExpenseService
├── getQuarterlyLimit(year, quarter)  // 분기별 한도 계산
├── getUsedAmount(year, quarter)       // 분기별 사용액 집계
├── getRemainingLimit(year, quarter)   // 잔여 한도
├── getSummary()                       // 대시보드용 요약
└── generateCheckPoints()              // AI 분석 메시지 생성
```

**방향 B: 기존 회계 시스템 확장**

- `expenses` 테이블에서 접대비 계정 필터링
- 한도 계산 로직만 별도 서비스로 분리

#### 필요 데이터

| 데이터 | 소스 | 비고 |
|--------|------|------|
| 연간 매출 | `orders` 또는 `sales_summary` | 한도 계산용 |
| 접대비 사용액 | `expenses` | account_code = '접대비' |
| 거래처 정보 | `expense_details` | 접대비 증빙용 |

#### CheckPoint 생성 규칙

| 상황 | 타입 | 메시지 예시 |
|------|------|------------|
| 한도 85% 미만 | info | "여유 있게 운영 중입니다" |
| 한도 85~100% | warning | "잔여 한도 600만원입니다. 점검 필요" |
| 한도 초과 | error | "초과분은 손금불산입됩니다" |
| 거래처 정보 누락 | error | "3건의 거래처 정보가 누락되었습니다" |

---

### 2.4 복리후생비 현황 (Welfare)

#### 기능 설명

복리후생비 한도 및 사용 현황. 직원 수 기반 한도 계산.

#### 현재 mockData 구조

```
welfare: {
  cards: [
    { label: "당해년도 복리후생비 한도", amount: 30123000 },
    { label: "{1사분기} 복리후생비 총 한도", amount: 10123000 },
    { label: "{1사분기} 복리후생비 잔여한도", amount: 5123000 },
    { label: "{1사분기} 복리후생비 사용금액", amount: 5123000 }
  ],
  checkPoints: [...]
}
```

#### 한도 계산 방식 옵션

**방식 1: 고정 금액 기준**
- 설정된 연간 한도를 분기별로 분배
- 예: 연간 3,000만원 → 분기당 750만원

**방식 2: 직원 수 기준 (비율)**
- 직원 1인당 월 N만원 기준
- 예: 50명 × 20만원 × 3개월 = 3,000만원/분기

#### 개발 방향 제안

```
WelfareExpenseService
├── getAnnualLimit()           // 연간 한도 (설정값 또는 계산)
├── getQuarterlyLimit(quarter) // 분기별 한도
├── getUsedAmount(quarter)     // 분기별 사용액
├── getPerEmployeeAverage()    // 1인당 평균 사용액
├── getSummary()               // 대시보드용 요약
└── generateCheckPoints()      // AI 분석 메시지
```

#### 필요 데이터

| 데이터 | 소스 | 비고 |
|--------|------|------|
| 직원 수 | `employees` | active 상태 |
| 복리후생비 사용액 | `expenses` | account_code = '복리후생비' |
| 한도 설정 | `company_settings` | 연간 한도 또는 1인당 기준 |

#### CheckPoint 생성 규칙

| 상황 | 타입 | 메시지 예시 |
|------|------|------------|
| 1인당 업계 평균 이내 | success | "업계 평균(15~25만원) 내 정상 운영 중" |
| 식대 비과세 한도 초과 | error | "식대가 월 25만원으로 비과세 한도(20만원) 초과" |
| 분기 한도 85% 이상 | warning | "한도 소진 임박" |

---

### 2.5 부가세 현황 (Vat)

#### 기능 설명

부가세 신고 예상 금액 및 관련 이슈 표시.

#### 현재 mockData 구조

```
vat: {
  cards: [
    { label: "매출세액", amount: 3050000000 },
    { label: "매입세액", amount: 2050000000 },
    { label: "예상 납부세액", amount: 110000000 },
    { label: "세금계산서 미발행", amount: 3, unit: "건" }
  ],
  checkPoints: [...]
}
```

#### 개발 방향 제안

**방향 A: 전용 부가세 서비스**

```
VatService
├── getSalesTax(period)        // 매출세액 집계
├── getPurchaseTax(period)     // 매입세액 집계
├── getEstimatedPayment(period)// 예상 납부/환급세액
├── getUnissuedInvoices()      // 미발행 세금계산서
├── getSummary()               // 대시보드용 요약
└── generateCheckPoints()      // AI 분석 메시지
```

**방향 B: 기존 세금계산서 시스템 확장**

- 발행/수취 세금계산서에서 세액 집계
- 미발행 건수 조회 추가

#### 필요 데이터

| 데이터 | 소스 | 비고 |
|--------|------|------|
| 매출세액 | `tax_invoices` (발행) | type = 'sales', 합계 × 10% |
| 매입세액 | `tax_invoices` (수취) | type = 'purchase', 합계 × 10% |
| 미발행 건 | `orders` 또는 `sales` | 세금계산서 미연결 건 |

#### CheckPoint 생성 규칙

| 상황 | 타입 | 메시지 예시 |
|------|------|------------|
| 환급 예상 | success | "예상 환급세액 520만원" |
| 납부 예상 (전기 대비 증가) | info | "전기 대비 12.9% 증가" |
| 미발행 세금계산서 존재 | warning | "3건 미발행, 발행 필요" |
| 신고 기한 임박 | error | "신고 기한 D-3" |

#### 부가세 신고 기간

| 신고 유형 | 과세 기간 | 신고 기한 |
|----------|----------|----------|
| 1기 예정 | 1/1 ~ 3/31 | 4/25 |
| 1기 확정 | 1/1 ~ 6/30 | 7/25 |
| 2기 예정 | 7/1 ~ 9/30 | 10/25 |
| 2기 확정 | 7/1 ~ 12/31 | 다음해 1/25 |

---

### 2.6 캘린더 (Calendar)

#### 기능 설명

회사 일정 표시 및 관리. 부서별, 개인별 일정 지원.

#### 현재 mockData 구조

```
calendarSchedules: [
  {
    id: string,
    title: string,
    startDate: string,      // "2026-01-01"
    endDate: string,        // "2026-01-04"
    startTime?: string,     // "09:00"
    endTime?: string,       // "12:00"
    type: string,           // "schedule", "order", "construction"
    department?: string,    // 부서명
    personName?: string     // 담당자명
  }
]
```

#### 개발 방향 제안

**방향 A: 전용 일정 테이블**

```
테이블: calendar_schedules
- id, tenant_id
- title
- start_date, end_date
- start_time, end_time (nullable, 종일 여부)
- type: enum (schedule, order, construction, vacation, tax, etc.)
- department_id (nullable)
- user_id (nullable, 담당자)
- color (nullable)
- content (nullable, 상세 내용)
- created_by, created_at, updated_at
```

**방향 B: 기존 데이터 연동 (읽기 전용)**

각 도메인의 기존 데이터를 캘린더 형식으로 변환

| 타입 | 소스 테이블 | 변환 규칙 |
|------|------------|----------|
| 수주 납기 | `orders` | due_date → startDate |
| 공사 일정 | `constructions` | start_date, end_date |
| 세금 신고 | `tax_schedules` | deadline → startDate |
| 휴가 | `vacation_requests` | start_date, end_date |

**방향 C: 하이브리드 (A + B)**

- 직접 등록 일정: 전용 테이블
- 시스템 일정: 각 도메인에서 자동 생성
- 통합 API에서 병합하여 제공

#### API 설계

```
GET /api/calendar/schedules?year=2026&month=1
POST /api/calendar/schedules (일정 생성)
PUT /api/calendar/schedules/{id} (일정 수정)
DELETE /api/calendar/schedules/{id} (일정 삭제)
```

#### 권장 사항

- **MVP**: 방향 A (전용 테이블)로 CRUD 구현
- **확장**: 추후 방향 C로 시스템 일정 연동

---

## 개발 우선순위 제안

| 순위 | 섹션 | 이유 |
|:---:|------|------|
| 1 | **현황판 (StatusBoard)** | 기존 데이터 집계만으로 구현 가능, 공수 적음 |
| 2 | **캘린더 (Calendar)** | 독립적인 CRUD, 다른 섹션과 의존성 없음 |
| 3 | **오늘의 이슈 (TodayIssue)** | StatusBoard 로직 재활용 가능 |
| 4 | **부가세 현황 (Vat)** | 세금계산서 데이터 기반, 로직 명확 |
| 5 | **접대비 현황 (Entertainment)** | 세무 로직 포함, 한도 계산 복잡 |
| 6 | **복리후생비 현황 (Welfare)** | 접대비와 유사한 패턴, 함께 개발 권장 |

---

## 공통 개발 패턴

### API 응답 형식

```json
{
  "success": true,
  "data": {
    "cards": [...],
    "checkPoints": [...]
  },
  "message": null
}
```

### CheckPoint 구조

```json
{
  "id": "unique-id",
  "type": "error|warning|success|info",
  "message": "메시지 내용",
  "highlights": [
    { "text": "강조할 텍스트", "color": "red|green|blue" }
  ]
}
```

### 색상 체계 (AI 리포트)

| 색상 | 의미 | 적용 기준 |
|:---:|:---:|----------|
| 🔴 error | 경고 | 한도 초과, 즉각 조치 필요 |
| 🟠 warning | 주의 | 한도 85~100%, 기한 임박 |
| 🟢 success | 긍정 | 목표 달성, 입금/회수 발생 |
| 🔵 info | 양호 | 정상 범위, 안정적 |

---

## 참고 문서

| 문서 | 경로 |
|------|------|
| AI 리포트 색상 체계 | `docs/dev_plans/AI_리포트_키워드_색상체계_가이드_v1.4.md` |
| Hook 패턴 예제 | `react/src/hooks/useClientList.ts` |
| Transform 예제 | `react/src/lib/api/dashboard/transformers.ts` |
| Proxy 라우트 | `react/src/app/api/proxy/[...path]/route.ts` |

---

## 변경 이력

| 날짜 | 내용 |
|------|------|
| 2026-01-20 | 초기 분석 문서 작성 |
| 2026-01-20 | Phase 1 완료 (5개 섹션 API 연동) |
| 2026-01-20 | Phase 2 개발 계획 상세화: 각 섹션별 개발 방향, 데이터 소스, 권장 사항 추가 |