refactor: stat_snapshots 테이블 제거 (통계 시스템과 분리)

[변경 이유]
- 추후 별도 통계 시스템 구축 예정
- stat_snapshots는 캐싱용 스냅샷과 통계 시스템 역할이 겹침
- 역할 분리를 위해 제거

[변경 사항]
- stat_snapshots 테이블 rollback 및 마이그레이션 파일 삭제
- tenant_stat_fields 테이블은 유지 (통계 시스템의 메타 정보로 활용)

[유지되는 구조]
- tenant_stat_fields: 각 테넌트가 통계를 원하는 필드 선언
- 통계 시스템 구축 시 이 메타 정보를 기반으로 통계 생성

[향후 계획]
- 각 테넌트별 통계 데이터를 별도 통계 시스템에서 처리
- 리포트 기능에서 테넌트별 커스텀 통계 제공
This commit is contained in:
2025-11-14 11:29:22 +09:00
parent 4fde8c0221
commit 62d671edcf
2 changed files with 1 additions and 98 deletions

View File

@@ -1,6 +1,6 @@
# 논리적 데이터베이스 관계 문서
> **자동 생성**: 2025-11-14 10:55:53
> **자동 생성**: 2025-11-14 11:26:35
> **소스**: Eloquent 모델 관계 분석
## 📊 모델별 관계 현황

View File

@@ -1,97 +0,0 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
/**
* 통계 스냅샷 캐싱 테이블
*
* 목적: 자주 조회하는 통계를 사전 계산하여 저장
*
* 동작 방식:
* 1. tenant_stat_fields에서 is_critical=true 필드 식별
* 2. 일일/월별 스케줄러가 해당 필드의 통계 계산
* 3. 이 테이블에 결과 저장
* 4. 통계 조회 시 실시간 계산 대신 이 테이블 참조
*
* 예시:
* - snapshot_type: 'daily'
* - target_table: 'products'
* - field_key: 'margin_rate'
* - metric_type: 'avg'
* - metric_value: 25.50
* - group_by_field: 'product_category'
* - group_by_value: 'SCREEN'
* → "SCREEN 카테고리 제품의 평균 마진율: 25.50%"
*
* @see /claudedocs/mes/ITEM_MANAGEMENT_MIGRATION_GUIDE.md
*/
return new class extends Migration
{
public function up(): void
{
Schema::create('stat_snapshots', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('tenant_id')->comment('테넌트 ID');
// ================================================
// 스냅샷 메타 정보
// ================================================
$table->string('snapshot_type', 50)->comment('스냅샷 타입 (daily, weekly, monthly)');
$table->string('target_table', 50)->comment('통계 대상 테이블 (products, materials 등)');
$table->date('snapshot_date')->comment('스냅샷 기준일');
// ================================================
// 통계 대상 필드
// ================================================
$table->string('field_key', 100)->comment('통계 필드 키 (attributes JSON 내 키값)');
$table->string('metric_type', 20)->comment('집계 함수 (avg, sum, min, max, count)');
$table->decimal('metric_value', 18, 4)->nullable()->comment('계산된 통계 값');
// ================================================
// 그룹화 기준 (선택적)
// ================================================
$table->string('group_by_field', 100)->nullable()->comment('그룹화 기준 필드 (product_category, part_type 등)');
$table->string('group_by_value', 100)->nullable()->comment('그룹화 기준 값 (SCREEN, STEEL 등)');
// ================================================
// 신뢰성 정보
// ================================================
$table->integer('record_count')->nullable()->comment('계산에 사용된 레코드 수');
$table->timestamp('calculated_at')->nullable()->comment('계산 실행 시각');
// ================================================
// 감사 정보
// ================================================
$table->text('calculation_note')->nullable()->comment('계산 상세 정보 (에러 로그 등)');
$table->timestamps();
// ================================================
// 인덱스 - 조회 성능 최적화
// ================================================
$table->index(['tenant_id', 'snapshot_type', 'snapshot_date'], 'idx_stat_snapshots_tenant_type_date');
$table->index(['tenant_id', 'target_table', 'field_key', 'snapshot_date'], 'idx_stat_snapshots_field_lookup');
$table->index(['tenant_id', 'target_table', 'group_by_field', 'group_by_value'], 'idx_stat_snapshots_group_lookup');
$table->index(['snapshot_date', 'calculated_at'], 'idx_stat_snapshots_freshness');
// ================================================
// 유니크 제약 (중복 스냅샷 방지)
// ================================================
$table->unique(
['tenant_id', 'snapshot_type', 'snapshot_date', 'target_table', 'field_key', 'metric_type', 'group_by_field', 'group_by_value'],
'idx_stat_snapshots_unique'
);
// ================================================
// 외래 키 (개발 환경에서만 권장)
// ================================================
// $table->foreign('tenant_id')->references('id')->on('tenants')->onDelete('cascade');
});
}
public function down(): void
{
Schema::dropIfExists('stat_snapshots');
}
};