- _index.md: 문서 목록 및 버전 관리 - 01~09: 아키텍처, API패턴, 컴포넌트, 폼, 스타일, 인증, 대시보드, 컨벤션 - 10: 문서 API 연동 스펙 (api-specs에서 이관) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
184 lines
5.9 KiB
Markdown
184 lines
5.9 KiB
Markdown
# 08. CEO 대시보드 시스템
|
|
|
|
> **대상**: 프론트엔드/백엔드 개발자
|
|
> **버전**: 1.0.0
|
|
> **최종 수정**: 2026-03-09
|
|
|
|
---
|
|
|
|
## 1. 아키텍처 개요
|
|
|
|
CEO 대시보드는 20개 섹션으로 구성된 실시간 경영 현황 화면.
|
|
|
|
```
|
|
CEODashboard.tsx
|
|
├── useCEODashboard() # 12개 섹션 API 통합 Hook
|
|
├── useEntertainment() # 접대비 독립 Hook
|
|
├── useWelfare() # 복리후생비 독립 Hook
|
|
├── useTodayIssue() # 금일 이슈 Hook
|
|
├── useCalendar() # 캘린더 Hook
|
|
├── useVat() # 부가세 Hook
|
|
├── SummaryNavBar # 섹션 바로가기 네비게이션
|
|
├── DashboardSettingsDialog # 섹션 표시/순서 설정
|
|
├── DetailModal # 상세 모달 (공통)
|
|
└── sections/ # 20개 섹션 컴포넌트
|
|
├── DailyReportSection
|
|
├── MonthlyExpenseSection
|
|
├── EntertainmentSection
|
|
├── WelfareSection
|
|
└── ... (17개 더)
|
|
```
|
|
|
|
---
|
|
|
|
## 2. 섹션 목록
|
|
|
|
| 섹션 | API Hook | 데이터 소스 |
|
|
|------|----------|------------|
|
|
| 일일일보 | useCEODashboard.dailyReport | sam_stat 캐시 |
|
|
| 현황보드 | useCEODashboard.statusBoard | 실시간 집계 |
|
|
| 당월예상지출 | useCEODashboard.monthlyExpense | 예상경비 테이블 |
|
|
| 카드/가지급금 | useCEODashboard.cardManagement | 가지급금 테이블 |
|
|
| 매출채권 | useCEODashboard.receivable | 매출/입금 |
|
|
| 채권회수 | useCEODashboard.debtCollection | 부실채권 |
|
|
| 매출현황 | useCEODashboard.salesStatus | 매출 통계 |
|
|
| 매입현황 | useCEODashboard.purchaseStatus | 매입 통계 |
|
|
| 일일생산 | useCEODashboard.dailyProduction | 생산실적 |
|
|
| 미출하 | useCEODashboard.unshipped | 출하 대기 |
|
|
| 공사현황 | useCEODashboard.construction | 공사 진행 |
|
|
| 근태현황 | useCEODashboard.dailyAttendance | 근태 데이터 |
|
|
| **접대비** | **useEntertainment()** | **expense_accounts** |
|
|
| **복리후생비** | **useWelfare()** | **expense_accounts** |
|
|
| 금일이슈 | useTodayIssue() | 이슈 목록 |
|
|
| 부가세 | useVat() | 부가세 신고 |
|
|
| 캘린더 | useCalendar() | 일정 |
|
|
| 출하현황 | useCEODashboard.dailyProduction | 출하 실적 |
|
|
|
|
---
|
|
|
|
## 3. Invalidation 시스템
|
|
|
|
다른 화면에서 CUD 발생 시 대시보드 데이터 자동 갱신.
|
|
|
|
### 흐름
|
|
|
|
```
|
|
[입금관리에서 입금 등록]
|
|
↓
|
|
invalidateDashboard('deposit')
|
|
↓
|
|
DOMAIN_SECTION_MAP에서 영향 섹션 조회
|
|
deposit → ['dailyReport', 'receivable']
|
|
↓
|
|
1. sessionStorage에 stale 섹션 저장
|
|
2. CustomEvent 발행
|
|
↓
|
|
[대시보드가 마운트 중이면]
|
|
→ 즉시 해당 섹션만 refetch
|
|
[대시보드 비마운트 상태면]
|
|
→ 다음 방문 시 stale 섹션 refetch
|
|
```
|
|
|
|
### 도메인 → 섹션 매핑
|
|
|
|
| 도메인 | 영향 섹션 |
|
|
|--------|----------|
|
|
| `deposit` | dailyReport, receivable |
|
|
| `withdrawal` | dailyReport, monthlyExpense |
|
|
| `sales` | dailyReport, salesStatus, receivable |
|
|
| `purchase` | dailyReport, purchaseStatus, monthlyExpense |
|
|
| `badDebt` | debtCollection, receivable |
|
|
| `expectedExpense` | monthlyExpense |
|
|
| `bill` | dailyReport, receivable |
|
|
| `giftCertificate` | entertainment, cardManagement |
|
|
| `journalEntry` | entertainment, welfare, monthlyExpense |
|
|
|
|
### 사용법 (CUD 완료 후)
|
|
|
|
```typescript
|
|
import { invalidateDashboard } from '@/lib/dashboard-invalidation';
|
|
|
|
// 입금 등록 성공 후
|
|
const handleSuccess = () => {
|
|
loadData();
|
|
invalidateDashboard('deposit');
|
|
};
|
|
|
|
// 전표 등록 성공 후
|
|
const handleJournalSuccess = () => {
|
|
loadData();
|
|
invalidateDashboard('journalEntry');
|
|
};
|
|
```
|
|
|
|
### 새 도메인 추가 시
|
|
|
|
`src/lib/dashboard-invalidation.ts`에서:
|
|
1. `DomainKey`에 새 도메인 추가
|
|
2. `DOMAIN_SECTION_MAP`에 영향 섹션 매핑 추가
|
|
3. 해당 도메인의 CUD 콜백에서 `invalidateDashboard('newDomain')` 호출
|
|
|
|
---
|
|
|
|
## 4. 사용자 설정
|
|
|
|
### 섹션 표시/숨김 + 순서
|
|
|
|
```typescript
|
|
// localStorage에 저장
|
|
const settings: DashboardSettings = {
|
|
dailyReport: true,
|
|
monthlyExpense: true,
|
|
entertainment: { enabled: true, companyType: 'medium' },
|
|
welfare: { enabled: true, calculationType: 'monthly' },
|
|
sectionOrder: ['dailyReport', 'statusBoard', 'monthlyExpense', ...],
|
|
};
|
|
localStorage.setItem('ceo-dashboard-settings', JSON.stringify(settings));
|
|
```
|
|
|
|
### 순서 변경
|
|
- DashboardSettingsDialog에서 드래그 앤 드롭 또는 순서 변경
|
|
- `sectionOrder` 배열로 관리
|
|
|
|
---
|
|
|
|
## 5. expense_accounts 동기화
|
|
|
|
접대비/복리후생비 대시보드 카드의 데이터 소스는 `expense_accounts` 테이블.
|
|
|
|
### 현재 동기화 경로
|
|
|
|
| 입력 경로 | expense_accounts 반영 |
|
|
|----------|----------------------|
|
|
| 일반전표 (수기전표) | **반영됨** — syncExpenseAccounts() |
|
|
| 가지급금 상품권 | **반영됨** — LoanService |
|
|
| 출금관리/카드사용내역 | **확인 중** |
|
|
| 세금계산서 | **확인 중** |
|
|
| 예상경비 | **확인 중** |
|
|
|
|
### 동기화 원리
|
|
- 전표/거래에서 계정과목명에 "복리후생비" 또는 "접대비"가 포함되면
|
|
- `expense_accounts` 테이블에 자동 INSERT
|
|
- CUD 시 delete-then-insert 전략 (정확한 추적)
|
|
- `journal_entry_id`, `journal_entry_line_id`로 원본 추적 가능
|
|
|
|
---
|
|
|
|
## 6. 백엔드 참고
|
|
|
|
### 대시보드 관련 API
|
|
|
|
| 엔드포인트 | 용도 |
|
|
|-----------|------|
|
|
| GET /api/v1/daily-report/summary | 일일일보 요약 |
|
|
| GET /api/v1/monthly-expense/summary | 당월 예상 지출 |
|
|
| GET /api/v1/entertainments/summary | 접대비 리스크 카드 |
|
|
| GET /api/v1/welfares/summary | 복리후생비 리스크 카드 |
|
|
| GET /api/v1/card-management/summary | 카드/가지급금 |
|
|
| GET /api/v1/receivable/summary | 매출채권 |
|
|
|
|
### sam_stat 캐시
|
|
- 일부 대시보드 API는 5분 캐시 (sam_stat 테이블)
|
|
- 실시간이 아닌 근사치 데이터
|
|
- invalidation은 프론트 refetch → 백엔드가 캐시 갱신 여부 판단
|