Files
sam-docs/plans/dashboard-api-integration-plan.md
권혁성 00023b2d69 chore: 계획 문서 정리 및 아카이브 이동
- 완료된 계획 문서 12개 → plans/archive/ 이동
- 완료된 하위 계획 2개 → plans/sub/archive/ 이동
- 새 계획 문서 추가:
  - 5130-bom-migration-plan.md (완료)
  - 5130-sam-data-migration-plan.md (완료)
  - bidding-api-implementation-plan.md (완료)
  - dashboard-api-integration-plan.md
  - order-workorder-shipment-integration-plan.md
  - dev-toolbar-plan.md
- AI 리포트 키워드 색상체계 가이드 v1.4 추가
- index_plans.md 업데이트
2026-01-20 19:05:43 +09:00

578 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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/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 개발 계획 상세화: 섹션별 개발 방향, 데이터 소스, 권장 사항 추가 |