- _index.md: 문서 목록 및 버전 관리 - 01~09: 아키텍처, API패턴, 컴포넌트, 폼, 스타일, 인증, 대시보드, 컨벤션 - 10: 문서 API 연동 스펙 (api-specs에서 이관) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
5.9 KiB
5.9 KiB
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 완료 후)
import { invalidateDashboard } from '@/lib/dashboard-invalidation';
// 입금 등록 성공 후
const handleSuccess = () => {
loadData();
invalidateDashboard('deposit');
};
// 전표 등록 성공 후
const handleJournalSuccess = () => {
loadData();
invalidateDashboard('journalEntry');
};
새 도메인 추가 시
src/lib/dashboard-invalidation.ts에서:
DomainKey에 새 도메인 추가DOMAIN_SECTION_MAP에 영향 섹션 매핑 추가- 해당 도메인의 CUD 콜백에서
invalidateDashboard('newDomain')호출
4. 사용자 설정
섹션 표시/숨김 + 순서
// 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 → 백엔드가 캐시 갱신 여부 판단