docs: sam_stat 프로젝트 완료 - DB 스키마 문서 + 계획 100% 완료

- database-schema.md: sam_stat 섹션 추가 (20테이블, 5커맨드, 4 API)
- 계획 문서: Phase 6 추가, 진행률 100%, 상태 '구현 완료'

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-30 09:23:57 +09:00
parent f5c5d908a0
commit 38411ad8b9
2 changed files with 88 additions and 9 deletions

View File

@@ -3,7 +3,7 @@
> **작성일**: 2026-01-29
> **목적**: SAM ERP의 확장 가능한 통계 전용 데이터베이스(sam_stat) 설계
> **기준 문서**: `docs/specs/database-schema.md`, `docs/architecture/system-overview.md`
> **상태**: 📋 설계 제안 (검토 대기)
> **상태**: ✅ 구현 완료
---
@@ -11,10 +11,10 @@
| 항목 | 내용 |
|------|------|
| **마지막 완료 작업** | Phase 5: 최적화 및 안정화 완료 (백필/검증 커맨드, 파티셔닝 준비, Redis 캐싱, 모니터링 알림) |
| **다음 작업** | Phase 6: 문서화 및 마무리 |
| **진행률** | 5/6 Phase (83%) |
| **마지막 업데이트** | 2026-01-29 |
| **마지막 완료 작업** | Phase 6: 문서화 및 마무리 완료 (Swagger, DB 스키마 문서, 계획 문서 완료 처리) |
| **다음 작업** | ✅ 전체 완료 |
| **진행률** | 6/6 Phase (100%) |
| **마지막 업데이트** | 2026-01-30 |
---
@@ -1118,6 +1118,13 @@ docker compose exec mysql mysql -u root -proot sam_stat \
| 5.4 | Redis 캐싱 | ✅ | `StatQueryService` - Cache::remember TTL 5분. 키 패턴: `stat:{daily\|monthly\|dashboard}:{tenantId}:...`. `invalidateCache()` 정적 메서드: Redis keys 패턴 매칭 삭제. 집계 완료 시 StatAggregatorService에서 자동 호출 |
| 5.5 | 모니터링 알림 | ✅ | `StatMonitorService` - recordAggregationFailure(critical), recordMissingData(warning), recordMismatch(critical), resolveAlerts(). StatAggregatorService catch 블록에서 자동 호출. stat_alerts 테이블 연동 검증 완료 |
### Phase 6: 문서화 및 마무리
| # | 작업 항목 | 상태 | 구체적 작업 내용 |
|---|----------|:----:|-----------------|
| 6.1 | Swagger API 문서 | ✅ | `app/Swagger/v1/StatApi.php` - Stats 태그, 4개 엔드포인트 (summary/daily/monthly/alerts), StatSalesDaily/StatFinanceDaily/StatDashboardSummary/StatAlert 스키마 정의. `l5-swagger:generate` 성공 |
| 6.2 | DB 스키마 문서 | ✅ | `docs/specs/database-schema.md`에 sam_stat 섹션 추가 - 20개 테이블 (메타 2, 차원 3, 일간 7, 월간 4, KPI/알림/이벤트 4) + Artisan 커맨드 5개 + API 엔드포인트 4개 |
| 6.3 | 계획 문서 완료 | ✅ | Phase 6 섹션 추가, 진행률 100%, 상태 완료 |
---
## 7. 기술 설계 요약
@@ -1280,6 +1287,7 @@ StatSalesDaily::updateOrCreate(
| 2026-01-29 | Phase 3 완료 | P1 도메인: dim_client/dim_product 차원 + 재고/견적/인사 일간 3개 + KPI/알림 2개 = 테이블 7개, 모델 7개, 서비스 4개(Dimension/Inventory/Quote/Hr/KpiAlert), 커맨드 1개, 스케줄러 1개. 실데이터 검증 완료. products→items, client_groups.name→group_name 수정 |
| 2026-01-29 | Phase 4 완료 | P2 도메인 + API + 대시보드: stat_project_monthly/stat_system_daily/stat_events/stat_snapshots 테이블 4개, 모델 4개, 서비스 4개(Project/System/StatEvent/StatQuery), StatController + FormRequest 3개 + routes/stats.php, StatEventObserver(6모델), DashboardService sam_stat 전환(폴백 패턴). 버그: whereHas→DB Builder 제거, User모델경로 수정. sam_stat 총 20테이블 |
| 2026-01-29 | Phase 5 완료 | 최적화 및 안정화: StatBackfillCommand(백필), StatVerifyCommand(정합성 검증+자동 재집계), 파티셔닝 준비 마이그레이션(7테이블 RANGE), StatQueryService Redis 캐싱(TTL 5분+invalidateCache), StatMonitorService(집계 실패/누락/불일치 알림→stat_alerts), StatAggregatorService에 모니터링+캐시 무효화 연동. severity enum 수정(high→critical). 전체 테스트 통과 |
| 2026-01-30 | Phase 6 완료 | 문서화 및 마무리: StatApi.php Swagger 문서(4 엔드포인트, 4 스키마), database-schema.md sam_stat 섹션 추가(20테이블+5커맨드+4API). 전체 6 Phase 100% 완료 |
---

View File

@@ -1,8 +1,8 @@
# SAM 데이터베이스 스키마
**업데이트**: 2025-12-26
**업데이트**: 2026-01-29
**데이터베이스**: samdb (MySQL 8.0.44)
**전체 테이블**: 171
**전체 테이블**: 219
---
@@ -470,5 +470,76 @@ $role->syncPermissions(['users.view', 'users.create']);
---
**최종 업데이트**: 2025-11-24
**Phase 4**: 완료 (8개 테이블 상세화)
**최종 업데이트**: 2026-01-30
**Phase 4**: 완료 (8개 테이블 상세화)
**테이블 수 갱신**: samdb 219개 + sam_stat 20개 = 239개
---
## sam_stat 데이터베이스 (통계 전용)
> 별도 MySQL 데이터베이스. Laravel `sam_stat` 커넥션 사용. 마이그레이션 경로: `database/migrations/stats/`
### 메타/관리 테이블
| 테이블 | 설명 | 주요 컬럼 |
|--------|------|----------|
| `stat_definitions` | 통계 정의 마스터 | domain, stat_type, table_name, is_active |
| `stat_job_logs` | 집계 작업 로그 | tenant_id, job_type, target_date, status, records_processed, duration_ms |
### 차원 테이블
| 테이블 | 설명 | 주요 컬럼 |
|--------|------|----------|
| `dim_date` | 날짜 차원 (2020~2030) | date, year, quarter, month, day, day_of_week, is_weekend, is_holiday |
| `dim_client` | 고객 차원 (samdb 동기화) | tenant_id, source_client_id, client_name, group_name |
| `dim_product` | 제품 차원 (samdb 동기화) | tenant_id, source_product_id, product_name, product_type |
### 일간 팩트 테이블 (7개)
| 테이블 | 도메인 | UK | 주요 지표 |
|--------|--------|------|----------|
| `stat_sales_daily` | 매출/수주 | (tenant_id, stat_date) | order_count/amount, sales_count/amount, new/active_client_count, shipment_count/amount |
| `stat_finance_daily` | 재무/회계 | (tenant_id, stat_date) | deposit/withdrawal count/amount, net_cashflow, purchase_count/amount, bank_balance_total |
| `stat_production_daily` | 생산/작업 | (tenant_id, stat_date) | work_order_count, completed/in_progress_count, defect_count/rate, total_quantity |
| `stat_inventory_daily` | 재고 | (tenant_id, stat_date) | receipt_count/quantity, shipment_count/quantity, total_stock_value, low_stock_count |
| `stat_quote_pipeline_daily` | 견적/영업 | (tenant_id, stat_date) | new/sent/won/lost_quote_count, pipeline_value, conversion_rate, avg_quote_amount |
| `stat_hr_attendance_daily` | 인사/근태 | (tenant_id, stat_date) | total/present/absent/late/leave_count, overtime_hours, attendance_rate |
| `stat_system_daily` | 시스템/감사 | (tenant_id, stat_date) | api_request/error_count, active_user_count, audit_create/update/delete_count, fcm_sent/failed_count |
### 월간 요약 테이블 (4개)
| 테이블 | 도메인 | UK | 주요 지표 |
|--------|--------|------|----------|
| `stat_sales_monthly` | 매출/수주 | (tenant_id, stat_year, stat_month) | order/sales/shipment count/amount, unique_client_count, avg_order_amount, mom/yoy_growth_rate |
| `stat_finance_monthly` | 재무/회계 | (tenant_id, stat_year, stat_month) | deposit/withdrawal/purchase_total, net_cashflow, bank_balance_end, mom_cashflow_change |
| `stat_production_monthly` | 생산/작업 | (tenant_id, stat_year, stat_month) | total_work_orders, completed/in_progress_count, avg_defect_rate, total_production_quantity |
| `stat_project_monthly` | 건설/프로젝트 | (tenant_id, stat_year, stat_month) | active/completed_site_count, new_contract_count/amount, gross_profit/rate |
### KPI/알림/이벤트 테이블
| 테이블 | 설명 | 주요 컬럼 |
|--------|------|----------|
| `stat_kpi_targets` | KPI 목표값 | tenant_id, domain, metric_code, target_year/month, target_value, actual_value |
| `stat_alerts` | 통계 알림 | tenant_id, domain, alert_type, severity(enum: info/warning/critical), title, message, is_read, is_resolved |
| `stat_events` | 실시간 이벤트 로그 | tenant_id, domain, event_type, entity_type, entity_id, payload(JSON), occurred_at |
| `stat_snapshots` | 상태 스냅샷 | tenant_id, snapshot_date, domain, snapshot_type, data(JSON) |
### Artisan 커맨드
| 커맨드 | 설명 |
|--------|------|
| `stat:aggregate-daily` | 일간 통계 집계 (스케줄러: 매일 01:00) |
| `stat:aggregate-monthly` | 월간 통계 집계 (스케줄러: 매월 1일 02:00) |
| `stat:sync-dimensions` | 차원 테이블 동기화 (스케줄러: 매일 00:30) |
| `stat:backfill --from= --to=` | 과거 데이터 일괄 백필 |
| `stat:verify --date=` | 원본 DB vs sam_stat 정합성 검증 |
### API 엔드포인트
| Method | Path | 설명 |
|--------|------|------|
| GET | `/api/v1/stats/summary` | 대시보드 통계 요약 |
| GET | `/api/v1/stats/daily` | 도메인별 일간 통계 (domain, start_date, end_date) |
| GET | `/api/v1/stats/monthly` | 도메인별 월간 통계 (domain, year, month?) |
| GET | `/api/v1/stats/alerts` | 통계 알림 목록 (limit?, unread_only?) |