Commit Graph

486 Commits

Author SHA1 Message Date
d07bad16df feat:DB 트리거 기반 데이터 변경 추적 시스템 구현
Phase 1: DB 기반 구축
- trigger_audit_logs 테이블 (RANGE 파티셔닝 15개, 3개 인덱스)
- 789개 MySQL AFTER 트리거 (263 테이블 × INSERT/UPDATE/DELETE)
- SetAuditSessionVariables 미들웨어 (@sam_actor_id, @sam_session_info)

Phase 2: 복구 메커니즘
- TriggerAuditLog 모델, TriggerAuditLogService, AuditRollbackService
- 6개 API 엔드포인트 (index, show, stats, history, rollback-preview, rollback)
- FormRequest 검증 (TriggerAuditLogIndexRequest, TriggerAuditRollbackRequest)

Phase 3: 관리 도구
- v_unified_audit VIEW (APP + TRIGGER 통합, COLLATE 처리)
- audit:partitions 커맨드 (파티션 추가/삭제, dry-run)
- audit:triggers 커맨드 (트리거 재생성, 테이블별/전체)
- 월 1회 파티션 자동 관리 스케줄러 등록

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 09:17:15 +09:00
ee6794be1a feat: [생산관리] 중간검사 데이터 저장/조회 API 구현
- POST /work-orders/{id}/items/{itemId}/inspection: 품목별 검사 데이터 저장
- GET /work-orders/{id}/inspection-data: 전체 품목 검사 데이터 조회
- GET /work-orders/{id}/inspection-report: 검사 성적서용 데이터 조회
- WorkOrderItem 모델에 getInspectionData/setInspectionData 헬퍼 추가
- StoreItemInspectionRequest FormRequest 생성
- work_order_items.options['inspection_data']에 검사 결과 저장

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 09:00:57 +09:00
78851ec04a feat: 테넌트별 채번 규칙 시스템 구현
- numbering_rules 테이블: JSON 패턴 기반 채번 규칙 저장 (tenant별)
- numbering_sequences 테이블: MySQL UPSERT 기반 atomic 시퀀스 관리
- NumberingService: generate/preview/nextSequence 핵심 서비스
- QuoteNumberService: NumberingService 우선, 폴백 QT{YYYYMMDD}{NNNN}
- OrderService: NumberingService 우선 (pair_code 지원), 폴백 ORD{YYYYMMDD}{NNNN}
- StoreOrderRequest: pair_code 필드 추가
- NumberingRuleSeeder: tenant_id=287 견적(KD-PR)/수주(KD-{pairCode}) 규칙

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 09:50:52 +09:00
6318474b6f fix: [자재투입] 입고 로트번호 기반으로 자재 목록 변경
- getMaterials(): 품목당 1행 → StockLot(입고 로트)당 1행으로 변경
- ITEM-{id} 가짜 로트번호 → Receiving에서 생성된 실제 lot_no 반환
- registerMaterialInput(): material_ids → stock_lot_id+qty 로트별 수량 차감
- StockService::decreaseFromLot() 신규 추가 (특정 로트 지정 차감)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 05:06:28 +09:00
d4125dc4ad fix: [견적관리] 견적-수주 역방향 참조 보정 및 자동 동기화
- QuoteService::show() - order_id가 null인 경우 Order.quote_id 역방향 탐색으로 연결된 수주 자동 보정
- QuoteService::update() - 역방향 참조 포함하여 syncFromQuote() 동기화 트리거 확장
- 수주에서 견적 수정 시 기존 수주에 자동 반영 + "수주 보기" 버튼 정상 표시

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 04:55:22 +09:00
487e651845 feat: 견적확정 밸리데이션, 작업지시 통계 공정별 카운트, 입고/재고 개선
- 견적확정 시 업체명/현장명/담당자/연락처 필수 검증 추가 (QuoteService)
- 작업지시 stats API에 by_process 공정별 카운트 반환 추가
- 작업지시 목록/상세 쿼리에 수주 개소(rootNodes) 연관 로딩
- 작업지시 품목에 sourceOrderItem.node 관계 추가
- 입고관리 완료건 수정 허용 및 재고 차이 조정
- work_order_step_progress 테이블 마이그레이션
- receivings 테이블 options 컬럼 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 03:27:07 +09:00
6b3e5c3e87 Merge remote-tracking branch 'origin/develop' into develop 2026-02-06 22:16:36 +09:00
김보곤
3a62a2a6e6 feat:인터뷰 시나리오 마이그레이션/모델 추가
- interview_categories, interview_templates, interview_questions 테이블 생성
- interview_sessions, interview_answers 테이블 생성
- InterviewCategory, InterviewTemplate, InterviewQuestion 모델 추가
- InterviewSession, InterviewAnswer 모델 추가
- 멀티테넌트(tenant_id) 지원, 감사 로깅(Auditable) 적용

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 21:01:24 +09:00
d2b0f028d4 feat: [수주관리] 전환/동기화 로직에 OrderNode 생성 및 아이템 연결
- convertToOrder: calculation_inputs.items[]로 OrderNode(location) 생성, order_items에 order_node_id 연결
- resolveLocationIndex() 헬퍼 추가 (formula_source/note 기반 개소 인덱스 매칭)
- syncFromQuote: 기존 nodes 삭제 후 재생성, 아이템 node 연결 동기화
- show(): rootNodes + withRecursiveChildren eager loading 추가
- createFromQuoteItem: order_node_id 매핑 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 20:15:00 +09:00
874bf97b8f feat: [수주관리] order_nodes 테이블 및 모델 생성 (N-depth 트리 구조)
- order_nodes 마이그레이션: 자기참조 parent_id, 고정코어(통계용) + options JSON(하이브리드)
- order_items에 order_node_id nullable FK 추가
- OrderNode 모델: BelongsToTenant, Auditable, SoftDeletes, 트리 관계(parent/children)
- Order 모델: nodes(), rootNodes() HasMany 관계 추가
- OrderItem 모델: order_node_id fillable + node() BelongsTo 관계 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 20:06:14 +09:00
4ae7b438f1 feat: 품목 치수 정규화 Artisan 커맨드 추가
- items:normalize-dimensions 커맨드 신규 생성
- 101_specification_1/2/3에서 thickness/width/length 자동 추출
- --dry-run(미리보기) / --execute(실행) 모드 지원
- 기존 값이 있는 경우 안전하게 스킵

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 20:05:23 +09:00
6dbcb5337d feat: [수주관리] convertToOrder 개소 파싱 로직 추가
- convertToOrder에서 calculation_inputs.items[] 파싱하여 floor_code/symbol_code 매핑
- resolveLocationMapping() 공통 메소드 추출 (note 파싱 1순위, formula_source 2순위)
- syncFromQuote와 동일한 2단계 파싱 로직으로 일관성 확보
- Exception → Throwable 변경 (동기화 실패 catch 범위 확대)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 19:40:14 +09:00
6bc766411b feat: 생산지시 생성 시 공정 자동 분류 및 아이템 연결
- OrderService: 생산지시 생성 로직 개선
  - order_items.item_id → process_items 테이블에서 공정 자동 조회
  - 공정별로 아이템 그룹화 (미지정 아이템은 별도 그룹)
  - 각 공정별 작업지시 생성
  - work_order_items에 해당 공정의 아이템들 자동 추가

- WorkOrderService: 목록 조회 시 관계 추가
  - items 관계 추가 (틀수 계산용)
  - process.department 필드 추가 (부서 표시용)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-06 10:28:30 +09:00
f640a837e9 feat:경동기업 견적/수주 전환 로직 개선
- KyungdongFormulaHandler: 수식 계산 로직 리팩토링 및 확장
- OrderService: 수주 전환 시 BOM 품목 매핑 로직 추가
- QuoteService: 견적 상태 처리 개선
- FormulaEvaluatorService: 디버그 로깅 추가
- Quote 모델: 캐스팅 타입 수정

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 21:58:49 +09:00
9f2b1cf44a feat:품목 검색 API에 수입검사 양식 연결 필드 추가
- has_inspection_template 필드 추가 (수입검사 양식 연결 여부)
- getItemsWithInspectionTemplate() 헬퍼 메서드 추가
- name 필드에 코드 합치기 제거 (중복 표시 해결)
- exclude_process_id 파라미터 추가 (공정별 품목 선택 시 중복 방지)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 21:58:00 +09:00
229ebc7483 feat:문서 resolve/upsert API 추가- React 연동용 resolve API (GET /documents/resolve)
- Upsert API (POST /documents/upsert)
- ResolveRequest, UpsertRequest FormRequest 생성
- DocumentService에 resolve/upsert 로직 추가
- document_category common_codes 마이그레이션
- 에러/성공 메시지 i18n 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 14:45:53 +09:00
e364239572 feat: 견적 참조 데이터 API, 수주 전환 로직 개선, 검사기준서 필드 통합
- 견적 참조 데이터(현장명, 부호) 조회 API 추가 (GET /quotes/reference-data)
- 수주 전환 시 floor_code/symbol_code를 quoteItem.note에서 파싱하도록 변경
- 수주 전환 시 note에 formula_category 저장
- 검사기준서 프리셋: standard + standard_criteria → text_with_criteria로 통합
- tolerance 컬럼 width 조정 (120px → 85px)
- LOGICAL_RELATIONSHIPS.md 문서 갱신

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 23:07:08 +09:00
fa07e5b58a feat: 경동기업 품목 기준 데이터 배포용 시더 구현
- ExportItemMasterDataCommand: tenant_id=287 데이터를 JSON으로 추출
- KyungdongItemMasterSeeder: JSON 기반 DELETE+재삽입 시더
  - Phase 1: item_pages/sections/fields + entity_relationships
  - Phase 2: categories(depth순) + items(배치500건)
  - Phase 3: item_details + prices
  - ID 매핑으로 환경별 충돌 없음, 트랜잭션 안전
- 8개 JSON 데이터 파일 포함 (총 약 1.5MB)
- .gitignore에 시더 데이터 예외 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 22:47:03 +09:00
a7975f7270 fix: ItemService update 시 attributes 머지 로직 추가
- 기존: attributes 전체 덮어쓰기 → 수정: 기존 값 보존 후 새 값만 머지
- 품목 수정 시 레거시 속성(sales_price, legacy 정보 등) 유실 방지

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 20:30:07 +09:00
af42c115ae feat:검사 기준서 동적화 + 외부 키 매핑 동적화
- 템플릿별 동적 필드 정의 (document_template_section_fields)
- 외부 키 매핑 동적화 (document_template_links + link_values)
- 문서 레벨 연결 (document_links)
- 시스템 프리셋 (document_template_field_presets)
- section_items에 field_values JSON 컬럼 추가
- 기존 고정 필드 → 동적 field_values 데이터 마이그레이션
- search_api → source_table 전환 마이그레이션

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 08:37:55 +09:00
3d20c6979d feat: 공정 단계(ProcessStep) CRUD API 구현
- process_steps 테이블 마이그레이션 생성 (step_code, sort_order, boolean 플래그 등)
- ProcessStep 모델 생성 (child entity 패턴, HasFactory만 사용)
- ProcessStepService: CRUD + reorder + STP-001 자동채번
- ProcessStepController: DI + ApiResponse::handle 패턴
- FormRequest 3개: Store, Update, Reorder
- Process 모델에 steps() HasMany 관계 추가
- ProcessService eager-load에 steps 추가 (5곳)
- Nested routes: /processes/{processId}/steps

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 18:59:12 +09:00
f701e0636e feat:검사기준서 탭 개선 - tolerance, measurement_type 컬럼 및 inspection_method 공통코드 추가
- document_template_section_items에 tolerance(공차), measurement_type(측정유형) 컬럼 추가
- common_codes에 inspection_method 그룹 6개 코드 삽입
- DocumentTemplateSectionItem 모델 $fillable 업데이트

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:29:39 +09:00
fb06975d97 feat:문서관리 Phase 4.1 - DocumentTemplate API + 결재 워크플로우 활성화
- DocumentTemplate 모델 6개 생성 (Template, ApprovalLine, BasicField, Section, SectionItem, Column)
- DocumentTemplateService (list/show) + DocumentTemplateController (index/show)
- GET /v1/document-templates, GET /v1/document-templates/{id} 라우트
- DocumentTemplateApi.php Swagger (7개 스키마, 2개 엔드포인트)
- Document 결재 워크플로우 4개 엔드포인트 활성화 (submit/approve/reject/cancel)
- ApproveRequest, RejectRequest FormRequest 생성
- DocumentApi.php Swagger에 결재 엔드포인트 4개 추가
- Document.template() 참조 경로 수정 (DocumentTemplate → Documents 네임스페이스)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 09:39:55 +09:00
fb0155624f feat: DB 백업 시스템 구축 (Phase 1,2,4)
- Phase 1: backup.conf.example + sam-db-backup.sh 백업 스크립트
- Phase 2: BackupCheckCommand + StatMonitorService.recordBackupFailure()
- Phase 2: routes/console.php에 db:backup-check 05:00 스케줄 등록
- Phase 4: SlackNotificationService 생성 (웹훅 알림)
- Phase 4: BackupCheckCommand/StatMonitorService에 Slack 알림 연동

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 08:33:19 +09:00
57d9ac2d7f fix: 가이드레일 세트가격 계산을 5130과 동일하게 수정
- 벽면형/측면형: 단가×2 세트가격 후 round(세트가격×길이)×QTY
- 혼합형: (벽면단가+측면단가) 합산 후 단일 항목으로 계산
- 기존: round(단가×길이)×2×QTY → 수정: round(단가×2×길이)×QTY
- 검증: EGI 84/84 + SUS 44/44 + 가이드타입 36/36 = 164/164 ALL PASS

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 00:29:55 +09:00
e5a293ab12 fix(API): 공통코드 조회 DB::table → CommonCode 모델 전환
- DB::table() 직접 쿼리 → CommonCode 모델 사용으로 변경
- SoftDeletes 자동 적용되어 삭제된 레코드 제외
- getComeCode()도 모델 전환 (TenantScope 자동 적용)
- index()는 TenantScope 해제 후 테넌트/글로벌 폴백 직접 처리

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 00:10:36 +09:00
9bd585bdf3 fix: 견적 반올림 순서를 5130과 동일하게 수정 (단건→수량 곱셈)
- 케이스, 케이스용 연기차단재, 가이드레일, 레일용 연기차단재:
  round(단가 × 길이 × QTY) → round(단가 × 길이) × QTY
- 5130 레거시와 동일한 반올림 순서 적용
- 검증: 스크린 44건 + 슬랫 32건 + 가이드타입 21건 = 97건 ALL PASS
- 사이즈 범위: 3000×1500 ~ 12000×4000, QTY 1~5

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 23:52:02 +09:00
f4a902fceb fix: FormulaEvaluatorService 슬랫 통합 및 면적/중량 공식 수정
- FormulaEvaluatorService: 슬랫 면적 공식 분리 (W0×(H0+50) vs W1×(H1+550))
- FormulaEvaluatorService: MOTOR_CAPACITY/BRACKET_SIZE 입력값 우선 처리
- KyungdongFormulaHandler: calculateDynamicItems 면적/중량 제품타입별 분기
- KyungdongFormulaHandler: normalizeGuideType() 추가 (벽면↔벽면형 호환)
- KyungdongFormulaHandler: guide_rail_spec 파라미터 별칭 지원
- 검증: 스크린/슬랫 5치수×3수량 전체 5130 정합성 확인 (±1원 이내)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:39:53 +09:00
e9639d1011 feat: 슬랫(철재) 견적 계산 지원 추가 및 5130 정합성 검증
- calculateSlatPrice() 메서드 추가 (면적 = W0×(H0+50), 원자재 단가 '방화')
- calculateDynamicItems() 주자재 분기 (screen→실리카, slat→방화)
- 레일용 연기차단재: 슬랫 ×1 / 스크린 ×2 분기 처리
- 절곡품: 슬랫일 때 L바/보강평철/환봉 제외 (5130 동일)
- 부자재 앵글: 슬랫은 앵글4T, 스크린은 앵글3T
- 모터 받침용 앵글: 슬랫 기본 비활성 (bracket_angle_enabled 파라미터)
- 조인트바: 슬랫 전용 항목 추가 (joint_bar_qty 파라미터)

검증: 치수 5종 × 수량 3종 모두 5130과 완벽 일치

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:04:04 +09:00
86ec5c4185 fix: 5130 견적 금액 정합성 수정 (5항목)
- guide_type 매핑: installation_type → guide_type 파라미터 전달 추가 (측면형/혼합형 가이드레일 가격 반영)
- 제어기/뒷박스 수량: QTY 곱셈 제거 (5130 동일: col15/col16/col17은 고정 수량)
- 샤프트 규격 매핑: W0 기반 임의 길이 → 5130 고정 제품(5인치: 6/7/8.2m)으로 매핑
- 환봉/앵글 이중 곱셈 수정: 자동계산에 이미 QTY 포함, 추가 곱셈 제거
- 모터/브라켓 입력값 우선: MOTOR_CAPACITY/BRACKET_SIZE 입력 시 자동계산 대신 사용

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 21:31:22 +09:00
06552ad64e fix: 스크린 면적 계산을 5130 공식과 동일하게 수정
- 기존: (W0+160) × (H0+350+550) / 1,000,000 (W1×H1 기반)
- 수정: W0 × (H0+550) / 1,000,000 (5130 공식과 동일)
- 전 모델 10개 조합 검증 완료 (SAM = 5130 정확 일치)
  KSS01/02, KSE01, KTE01, KWE01, KQTS01, KDSS01
  SUS마감/EGI마감 모두 확인

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 21:06:55 +09:00
868b765658 docs: 앱 버전 API Swagger 문서 추가
- App Version 태그 (latestVersion, download)
- AppVersionCheckResponse, AppVersionLatest 스키마 정의

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 21:06:14 +09:00
24c97cf75a fix(API): 공통코드 조회 테넌트 분리 - 글로벌 폴백 적용
- 테넌트 데이터 존재 시 테넌트만 조회, 없으면 글로벌 폴백
- 기존: tenant OR NULL → 글로벌+테넌트 중복 반환 문제 해결

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 20:13:39 +09:00
49d163ae0c feat: 인앱 업데이트 체크 API 구현
- app_versions 테이블 마이그레이션 (시스템 레벨, tenant_id 없음)
- AppVersion 모델 (SoftDeletes)
- AppVersionService: getLatestVersion, downloadApk
- AppVersionController: GET /api/v1/app/version, GET /api/v1/app/download/{id}
- ApiKeyMiddleware 화이트리스트에 api/v1/app/* 추가
- app_releases 스토리지 디스크 추가

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 19:53:09 +09:00
a41bf48dd8 fix: 가이드레일 모델별 규격 매핑 및 finishing_type 정규화
- getGuideRailSpecs() 메서드 추가: 모델별 가이드레일 규격 매핑
  - KTE01/KQTS01 → 130*75/130*125
  - KDSS01 → 150*150/150*212
  - 기본(KSS01/02, KSE01, KWE01) → 120*70/120*120
- 벽면형/측면형/혼합형 하드코딩 규격을 동적 변수로 교체
- finishing_type 정규화: 'SUS마감' → 'SUS' 변환 (DB 값 매칭)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 19:52:06 +09:00
1c3cb48c7c feat(API): FCM 채널명 동기화 및 config 일원화 (7채널)
- push_urgent → push_vendor_register (거래처등록)
- push_payment → push_approval_request (결재요청)
- push_income 신규 추가 (입금)
- config/fcm.php에 전체 7개 채널 등록 (기존 2개→7개)
- 서비스 파일 하드코딩을 config() 참조로 전환

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 18:07:44 +09:00
c111b2b55d fix(API): CommonCode 라벨 조회 시 테넌트 스코프 적용
- getLabel(), getCodeMap()에서 withoutGlobalScopes() → query()로 변경
- BelongsToTenant 스코프가 적용되어 테넌트별 공통코드 정상 조회

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 15:35:36 +09:00
c9e37f4338 fix(API): Schedule 모델 Builder import 누락으로 캘린더/현황판 500 에러 수정
- scopeForTenant 등 스코프 메서드에서 Builder 타입힌트 사용하나 import 누락
- CalendarService, StatusBoardService에서 forTenant() 호출 시 500 발생

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 12:00:13 +09:00
63afa4fc9b feat(API): 경동 견적 계산 개선 및 stock_transactions 관계 문서 갱신
- FormulaEvaluatorService: 완제품 미등록 상태에서도 경동 전용 계산 진행, product_model/finishing_type/installation_type 변수 추가
- LOGICAL_RELATIONSHIPS.md: stock_transactions 모델 관계 반영

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:23:35 +09:00
66887c9c69 fix(API): 입고 수정 시 completed 상태 변경 지원
- UpdateReceivingRequest: status 허용값에 completed 추가, receiving_qty/receiving_date/lot_no 필드 추가
- ReceivingService::update(): status가 completed로 변경 시 LOT번호 자동생성, 입고수량/입고일 설정, 재고 연동(StockService) 처리

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 11:22:28 +09:00
0fbd080875 docs: sam_stat Swagger API 문서 추가 (Phase 6)
- StatApi.php: Stats 태그, 4개 엔드포인트 Swagger 정의
  - GET /stats/summary - 대시보드 통계 요약
  - GET /stats/daily - 도메인별 일간 통계
  - GET /stats/monthly - 도메인별 월간 통계
  - GET /stats/alerts - 통계 알림 목록
- 스키마: StatSalesDaily, StatFinanceDaily, StatDashboardSummary, StatAlert

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 09:23:51 +09:00
ca2dd44567 fix: 환봉·각파이프 5130 자동계산 공식 적용
- 환봉: W0 기준 자동계산 (≤3000→1, ≤6000→2, ≤9000→3, ≤12000→4 × 수량)
- 각파이프: col67(케이스길이+3000×연결수) 기준 3000mm/6000mm 수량 자동계산
- 기존 하드코딩(각파이프 1개, 환봉 0개) 제거

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 22:55:40 +09:00
e300062f32 fix: 견적 계산 마구리 수량·각파이프 구조 5130 일치 보정
- 케이스 마구리: 수량 2 고정 → quantity 기반 (5130: maguriPrices × $su)
- 각파이프: 하드코딩 1개 → pipe_3000_qty/pipe_6000_qty 2종 분리 (5130: col68+col69)
- 기본값 fallback: 파이프 수량 미입력 시 W0 기준 자동 결정 유지

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 22:28:27 +09:00
ca51867cc2 feat: sam_stat 최적화 및 안정화 (Phase 5)
- StatBackfillCommand: 과거 데이터 일괄 백필 (일간+월간, 프로그레스바, 에러 리포트)
- StatVerifyCommand: 원본 DB vs sam_stat 정합성 교차 검증 (--fix 자동 재집계)
- 파티셔닝 준비: 7개 일간 테이블 RANGE COLUMNS(stat_date) 마이그레이션
- Redis 캐싱: StatQueryService Cache::remember TTL 5분 + invalidateCache()
- StatMonitorService: 집계 실패/누락/불일치 시 stat_alerts 알림 기록
- StatAggregatorService: 모니터링 알림 + 캐시 무효화 연동

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 22:17:11 +09:00
3793e95662 fix: 견적 단가 chandj 원본 소스 전환 및 5130 계산 일치 보정
- MigrateBDModelsPrices: chandj 원본 테이블(price_motor, price_angle 등)에서 직접 마이그레이션
- EstimatePriceService: 모터 LIKE 매칭, 제어기 카테고리 분리, 앵글 bracket/main 분리, 샤프트 포맷 정규화
- KyungdongFormulaHandler:
  - 검사비 항목 추가 (기본 50,000원)
  - 뒷박스 항목 추가 (제어기 섹션)
  - 부자재 앵글3T 항목 추가 (calculatePartItems)
  - 면적 소수점 2자리 반올림 후 곱셈 (5130 동일)
  - model_name에 product_model fallback 추가 (KSS02 단가 정확 조회)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 22:00:15 +09:00
4d8dac1091 feat: sam_stat P2 도메인 + 통계 API + 대시보드 전환 (Phase 4)
- 4.1: stat_project_monthly + ProjectStatService (건설/프로젝트 월간)
- 4.2: stat_system_daily + SystemStatService (API/감사/FCM/파일/결재)
- 4.3: stat_events, stat_snapshots + StatEventService + StatEventObserver
- 4.4: StatController (summary/daily/monthly/alerts) + StatQueryService + FormRequest 3개 + routes/stats.php
- 4.5: DashboardService sam_stat 우선 조회 + 원본 DB 폴백 패턴

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 21:56:53 +09:00
595e3d59b4 feat: sam_stat P1 도메인 확장 (Phase 3)
- 차원 테이블: dim_client, dim_product 마이그레이션 + SCD Type 2 동기화 (DimensionSyncService)
- 재고 통계: stat_inventory_daily + InventoryStatService (stocks, stock_transactions, inspections)
- 견적/영업 통계: stat_quote_pipeline_daily + QuoteStatService (quotes, biddings, sales_prospects)
- 인사/근태 통계: stat_hr_attendance_daily + HrStatService (attendances, leaves, user_tenants)
- KPI/알림: stat_kpi_targets, stat_alerts + KpiAlertService + StatCheckKpiAlertsCommand
- StatAggregatorService에 inventory, quote, hr 도메인 추가 (총 6개 도메인)
- 스케줄러: stat:check-kpi-alerts 매일 09:00 등록

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 20:19:50 +09:00
6c9735581d feat: 견적 단가를 items+item_details+prices 통합 구조로 전환
- EstimatePriceService 생성: items+item_details+prices JOIN 기반 단가 조회
  - item_details.product_category/part_type/specification 컬럼 매핑
  - items.attributes JSON으로 model_name/finishing_type 추가 차원 처리
  - 세션 내 캐시로 중복 조회 방지
- MigrateBDModelsPrices 커맨드: 레거시 BDmodels + kd_price_tables → 85건 마이그레이션
- KyungdongFormulaHandler: KdPriceTable 의존 제거 → EstimatePriceService 사용
- FormulaEvaluatorService: W1 마진 140→160, 면적 공식 W1×(H1+550) 수정
  - 가이드레일 H0+250, 케이스/L바/평철 W0+220 (레거시 일치)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 19:30:46 +09:00
e882d33de1 feat: sam_stat P0 도메인 집계 구현 (Phase 2)
- 영업(Sales), 재무(Finance), 생산(Production) 3개 도메인 구현
- 일간/월간 통계 테이블 6개 마이그레이션 생성
- 도메인별 StatService (SalesStatService, FinanceStatService, ProductionStatService)
- Daily/Monthly 6개 Eloquent 모델 생성
- StatAggregatorService에 도메인 서비스 매핑 활성화
- StatJobLog duration_ms abs() 처리
- 스케줄러 등록 (일간 02:00, 월간 1일 03:00)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 19:30:30 +09:00
c88048db67 feat: sam_stat 통계 DB 인프라 구축 (Phase 1)
- sam_stat DB 연결 설정 (config/database.php, .env)
- 메타 테이블 마이그레이션 (stat_definitions, stat_job_logs)
- dim_date 차원 테이블 + DimDateSeeder (2020~2030, 4018건)
- 기반 모델: BaseStatModel, StatDefinition, StatJobLog, DimDate
- 집계 커맨드: stat:aggregate-daily, stat:aggregate-monthly
- StatAggregatorService + StatDomainServiceInterface 골격

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 17:13:36 +09:00