- Plan/Subscription/Payment 모델에 상태 상수, 스코프, 헬퍼 메서드 추가
- PlanService, SubscriptionService, PaymentService 생성
- PlanController, SubscriptionController, PaymentController 생성
- FormRequest 9개 생성 (Plan 3개, Subscription 3개, Payment 3개)
- Swagger 문서 3개 생성 (PlanApi, SubscriptionApi, PaymentApi)
- API 라우트 22개 등록 (Plan 7개, Subscription 8개, Payment 7개)
- Pint 코드 스타일 정리
- loans 테이블 마이그레이션 추가
- Loan 모델 (인정이자 계산, 세금 계산 로직)
- LoanService (CRUD, 정산, 인정이자 계산/리포트)
- LoanController, FormRequest 5개
- 9개 API 라우트 등록
- i18n 키 추가 (validation)
- ai_reports 테이블 마이그레이션 추가
- AiReport 모델 생성 (daily/weekly/monthly 유형)
- AiReportService 구현 (비즈니스 데이터 수집 + Gemini API)
- 4개 API 엔드포인트 추가 (목록/생성/상세/삭제)
- Swagger 문서 및 i18n 메시지 추가
- 마이그레이션 4개 (approval_forms, approval_lines, approvals, approval_steps)
- 모델 4개 (ApprovalForm, ApprovalLine, Approval, ApprovalStep)
- ApprovalService 비즈니스 로직 (양식/결재선 CRUD, 기안함/결재함/참조함, 결재 액션)
- 컨트롤러 3개 (ApprovalFormController, ApprovalLineController, ApprovalController)
- FormRequest 13개 (양식/결재선/문서 검증)
- Swagger 문서 3개 (26개 엔드포인트)
- i18n 메시지/에러 키 추가
- 라우트 26개 등록
- 매출(Sale) 및 매입(Purchase) CRUD API 구현
- 문서번호 자동 생성 (SL/PU + YYYYMMDD + 시퀀스)
- 상태 관리 (draft → confirmed → invoiced)
- 확정(confirm) 및 요약(summary) 기능 추가
- BelongsToTenant, SoftDeletes 적용
- Swagger API 문서 작성 완료
추가된 파일:
- 마이그레이션: sales, purchases 테이블
- 모델: Sale, Purchase
- 서비스: SaleService, PurchaseService
- 컨트롤러: SaleController, PurchaseController
- FormRequest: Store/Update 4개
- Swagger: SaleApi.php, PurchaseApi.php
API 엔드포인트 (14개):
- GET/POST /v1/sales, /v1/purchases
- GET/PUT/DELETE /v1/{sales,purchases}/{id}
- POST /v1/{sales,purchases}/{id}/confirm
- GET /v1/{sales,purchases}/summary
- 근무 설정 API (GET/PUT /settings/work)
- 근무유형, 소정근로시간, 연장근로시간, 근무요일, 출퇴근시간, 휴게시간
- 출퇴근 설정 API (GET/PUT /settings/attendance)
- GPS 출퇴근, 허용 반경, 본사 위치 설정
- 현장 관리 API (CRUD /sites)
- 현장 등록/수정/삭제, 활성화된 현장 목록(셀렉트박스용)
- GPS 좌표 기반 위치 관리
마이그레이션: work_settings, attendance_settings, sites 테이블
모델: WorkSetting, AttendanceSetting, Site (BelongsToTenant, SoftDeletes)
서비스: WorkSettingService, SiteService
Swagger 문서 및 i18n 메시지 키 추가
- leaves, leave_balances 테이블 마이그레이션 추가
- Leave, LeaveBalance 모델 구현 (BelongsToTenant, SoftDeletes)
- LeaveService 서비스 구현 (CRUD, 승인/반려/취소, 잔여일수 관리)
- LeaveController 및 FormRequest 5개 생성
- API 엔드포인트 11개 등록 (/v1/leaves/*)
- Swagger 문서 (LeaveApi.php) 작성
- i18n 메시지 키 추가 (message.leave.*, error.leave.*)
- Item 모델 files() 관계를 document_id/document_type 기반으로 변경
- show() 메서드에 files 로딩 및 field_key별 그룹화 추가
- item_type 파라미터 선택적 처리 (ID만으로 조회 가능)
- showWithPrice() 메서드 반환 타입 변경에 맞게 수정
- api_request_logs 테이블 생성 (하루치만 보관)
- LogApiRequest 미들웨어로 DB + 로그 파일 이중 저장
- 날짜별 로그 파일: storage/logs/api/api-YYYY-MM-DD.log
- 민감 데이터 자동 마스킹 (password, token 등)
- api-log:prune 스케줄러로 매일 03:00 자동 정리
- Order 모델: product_id 제거, item_id 추가, item() 관계 추가
- OrderItem 모델: product_id 제거, item_id 추가, item() 관계 추가
- Quote 모델: product_id 제거, item_id 추가, item() 관계 추가
- MaterialReceipt 모델: material_id 제거, item_id 추가, material() → item() 변경
- Lot 모델: Material import 제거, material() → item() 변경
DB 스키마는 이미 마이그레이션됨 (2025_12_13_153544)
기존 product_id/material_id 컬럼은 DB에 남아있지만 fillable에서 제거
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- ItemsBomController: ProductBomService 제거, Item.bom JSON 기반으로 재구현
- ItemsFileController: Product/Material → Item 모델로 통합
- ItemPage: products/materials 클래스 매핑 제거
- ItemsService 삭제 (1,210줄) - ItemService로 대체 완료
BOM 기능 변경:
- 기존: ProductBomService (삭제됨)
- 변경: Item 모델의 bom JSON 필드 직접 조작
- 모든 BOM API 엔드포인트 정상 동작
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- BOM child_item_id를 새 items 테이블 ID로 마이그레이션
- Item.loadBomChildren() 수정: setRelation()으로 모델에 설정
- ItemService.validateBom() 추가: 순환 참조 방지
- error.php에 self_reference_bom 메시지 추가
- ID 7 자기참조 BOM 데이터 수정 완료
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
## 주요 변경사항
- Phase 0: 비표준 item_type 데이터 정규화 마이그레이션
- Phase 1.1: items 테이블 생성 (products + materials 통합)
- Phase 1.2: item_details 테이블 생성 (1:1 확장 필드)
- Phase 1.3: 데이터 이관 + item_id_mappings 테이블 생성
- Phase 3: item_pages.source_table 업데이트
- Phase 5: 참조 테이블 마이그레이션 (product_components, orders 등)
## 신규 파일
- app/Models/Items/Item.php - 통합 아이템 모델
- app/Models/Items/ItemDetail.php - 1:1 확장 필드 모델
- app/Services/ItemService.php - 통합 서비스 클래스
## 수정 파일
- ItemPage.php - items 테이블 지원 추가
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- file_type: ENUM → VARCHAR(50) 변경 (확장성 개선)
- field_key: VARCHAR(100) 신규 컬럼 (비즈니스 용도 구분)
- ItemsFileController: field_key 사용, file_type 자동 분류 (detectFileType)
- File 모델: fillable에 field_key 추가
- ItemsService: getItemFiles()에서 field_key로 그룹핑
- rollback_items_migration: FK 제약조건 처리 수정
- GET /items/{id} 응답에 BOM 확장 데이터 포함
- child_item_code, child_item_name, unit, specification 필드 추가
- expandBomData() 메서드 구현 (ItemsService)
- Product 모델 bom 캐스팅 추가
- products 테이블에 options JSON 컬럼 추가 (마이그레이션)
- Material/Product 모델에 options 필드 추가 (fillable, casts)
- SystemFields::PRODUCTS에 options 상수 추가
- MaterialService/ProductService에 동적 필드 자동 추출 로직:
- getKnownFields(): SystemFields + ItemField 기반 고정 필드 조회
- extractDynamicOptions(): 동적 필드 추출
- normalizeOptions(): [{label, value, unit}] 형태로 정규화
- material_code 중복 체크 시 soft delete 포함 (withTrashed)
- 사용 중인 자재 삭제 방지 (checkMaterialUsage)
- Material 모델에 category 관계 추가
- AttendanceController, AttendanceService 추가
- EmployeeController, EmployeeService 추가
- Attendance 모델 및 마이그레이션 추가
- TenantUserProfile에 employee_status 컬럼 추가
- DepartmentService 트리 조회 기능 개선
- Swagger 문서 추가 (AttendanceApi, EmployeeApi)
- API 라우트 등록
- ItemField 모델: 소스 매핑 컬럼 추가 (source_table, source_column 등)
- ItemPage 모델: source_table 컬럼 추가
- ItemDataService: 동적 데이터 조회 서비스
- ItemMasterApi Swagger 업데이트
- ItemTypeSeeder: 품목 유형 시더
- 스펙 문서: ITEM_MASTER_FIELD_INTEGRATION_PLAN.md
- Price, PriceRevision 모델 추가 (PriceHistory 대체)
- PricingService: CRUD, 원가 조회, 확정 기능
- PricingController: statusCode 파라미터로 201 반환 지원
- NotFoundHttpException(404) 적용 (존재하지 않는 리소스)
- FormRequest 분리 (Store, Update, Index, Cost, ByItems)
- Swagger 문서 업데이트
- ApiResponse::handle()에 statusCode 옵션 추가
- prices/price_revisions 마이그레이션 및 데이터 이관
- 마이그레이션: is_active 컬럼 추가 (기본값 true)
- ItemField 모델: fillable, casts에 is_active 추가
- ItemFieldService: store, storeIndependent, clone, update 메서드에 is_active 처리
- FormRequest: is_active 유효성 검사 규칙 추가
- API Flow 테스트 시나리오 추가 (docs/api-flows/)
- docs/INDEX.md에 api-flows 섹션 추가
ModelTrait::scopeActive() 메서드 사용을 위한 필수 컬럼
- 거래처 유형(client_type), 연락처(mobile, fax), 담당자 정보 필드 추가
- 발주처 설정(account_id/password, payment_day) 필드 추가
- 약정 세금(tax_agreement, tax_amount, tax_start/end_date) 필드 추가
- 악성채권(bad_debt 관련 5개 필드) 정보 필드 추가
- Model, Service, FormRequest, Swagger 문서 업데이트
- 견적 API 계획에 문서 발송 API(email/fax/kakao) 요구사항 추가
- 마이그레이션 생성: quotes, quote_items, quote_revisions 테이블
- Model 생성: Quote, QuoteItem, QuoteRevision
- BelongsToTenant, SoftDeletes 트레이트 적용
- 상태 관리 메서드 및 스코프 구현
- 개발 계획서 작성 및 진행 상황 문서화
- BoardController, PostController 추가
- Board, BoardSetting 모델 수정
- BoardService 추가
- FormRequest 클래스 추가
- Swagger 문서 추가 (BoardApi, PostApi)
- 게시판 시스템 필드 마이그레이션 추가
- field_key: {ID}_{key} 형식으로 고유키 생성
- is_locked, locked_by, locked_at 잠금 컬럼 추가
- ItemFieldService: store/update/clone 로직 수정
- FormRequest: field_key 검증 규칙 추가
- Swagger 스키마 업데이트
- EntityRelationship::link() 호출 파라미터 순서 수정 (3개 파일)
- ItemSectionService: tenantId를 첫 번째 파라미터로 변경
- ItemBomItemService: tenantId를 첫 번째 파라미터로 변경
- ItemFieldService: tenantId를 첫 번째 파라미터로 변경
- ItemSection 모델의 fields()/bomItems() 관계 메서드 문제 해결
- 쿼리빌더 반환으로 인한 addEagerConstraints() 에러 수정
- loadRelatedEntities() 메서드 신규 추가
- with()/load() 대신 setRelation()으로 데이터 설정
- 영향받은 서비스 파일 전체 수정
- ItemSectionService, SectionTemplateService, ItemMasterService
## 잠금 기능 (Lock Feature)
- entity_relationships 테이블에 is_locked, locked_by, locked_at 컬럼 추가
- EntityRelationship 모델에 잠금 관련 헬퍼 메서드 추가
- LockCheckTrait 생성 (destroy 시 잠금 체크 공통 로직)
- 각 Service의 destroy() 메서드에 잠금 체크 적용
- API 응답에 is_locked 필드 포함
- 한국어 에러 메시지 추가
## FK 레거시 코드 정리
- ItemMasterSeeder: entity_relationships 기반으로 전환
- ItemPage 모델: FK 기반 sections() 관계 제거
- ItemSectionService: clone() 메서드 FK 제거
- SectionTemplateService: page_id 컬럼 참조 제거
- EntityRelationship::link() 파라미터 순서 통일
## 기타
- Swagger 스키마에 is_locked 속성 추가
- 프론트엔드 가이드 문서 추가
- FK 컬럼 제거: item_sections.page_id, item_fields.section_id, item_bom_items.section_id
- entity_relationships 테이블로 전환하여 독립 엔티티 구조 확립
- ItemMasterField 관련 파일 삭제 (Controller, Service, Model, Requests)
- destroy 메서드 독립 엔티티 아키텍처 적용 (관계 링크만 삭제)
- Swagger 스키마에서 FK 참조 제거
- FormRequest 및 Swagger에 group_id(계층번호) 필드 추가
- CASCADE FK → 독립 엔티티 + entity_relationships 링크 테이블
- 독립 API 10개 추가 (섹션/필드/BOM CRUD, clone, usage)
- SectionTemplate 모델 제거 → ItemSection.is_template 통합
- 페이지-섹션, 섹션-필드, 섹션-BOM 링크/언링크 API 14개 추가
- Swagger 문서 업데이트
- 마이그레이션 9개 생성 (unit_options, section_templates, item_master_fields, item_pages, item_sections, item_fields, item_bom_items, custom_tabs, tab_columns)
- Eloquent 모델 9개 구현 (ItemMaster 네임스페이스)
- ItemMasterSeeder 작성 및 테스트 데이터 생성
주요 특징:
- Multi-tenant 지원 (BelongsToTenant trait)
- Soft Delete 적용 (deleted_at, deleted_by)
- 감사 로그 지원 (created_by, updated_by)
- JSON 필드로 동적 속성 지원 (display_condition, validation_rules, options, properties)
- FK 제약조건 및 Composite Index 설정
- 계층 구조 (ItemPage → ItemSection → ItemField/ItemBomItem)
SAM API Development Rules 준수
- is_active 컬럼 추가 마이그레이션 (default 1)
- Product 모델 fillable 및 casts 업데이트
- Material 모델 fillable 및 casts 업데이트
- Material 모델에 material_type fillable 추가
- ModelTrait의 scopeActive() 메서드 지원
- Products 테이블에 9개 파일 관련 필드 추가
- bending_diagram, bending_details (JSON)
- specification_file, specification_file_name
- certification_file, certification_file_name
- certification_number, certification_start_date, certification_end_date
- ItemsFileController 구현 (Code-based API)
- POST /items/{code}/files - 파일 업로드
- DELETE /items/{code}/files/{type} - 파일 삭제
- 파일 타입: bending_diagram, specification, certification
- ItemsFileUploadRequest 검증
- 파일 타입별 MIME 검증 (이미지/문서)
- 파일 크기 제한 (10MB/20MB)
- 인증 정보 및 절곡 상세 정보 검증
- Swagger 문서 작성 (ItemsFileApi.php)
- 업로드/삭제 API 스펙
- 스키마: ItemFileUploadResponse, ItemFileDeleteResponse
- FormRequest 패턴 적용 (CategoryFieldStoreRequest, CategoryFieldUpdateRequest)
- Service에서 Validator::make() 제거
- Controller 메시지 i18n 키로 변경 (__('message.category_field.*'))
- is_required 타입을 'Y'/'N' → boolean으로 통일
- Swagger 스키마 is_required boolean 타입으로 업데이트
- Model scopeRequired() boolean 조건으로 변경
[추가된 파일]
- app/Models/Tenants/TenantStatField.php
- 테넌트별 통계 필드 설정 모델
- Scopes: forTable, critical, withAggregation, ordered
- 통계 시스템의 메타 정보 제공
- claudedocs/mes/HYBRID_STRUCTURE_GUIDE.md
- 하이브리드 구조 사용 가이드 문서
- 데이터베이스 구조 설명
- 코드 예제 (Product, ProductComponent 생성)
- 통계 쿼리 예제
- 성능 고려사항 및 주의사항
[모델 기능]
- BelongsToTenant, ModelTrait 적용
- aggregation_types JSON 자동 캐스팅
- tenant, target_table, field_key 조합으로 통계 필드 관리
[문서 내용]
- 고정 필드 vs 동적 필드 선택 기준
- attributes JSON 사용법
- 통계 쿼리 예제 (JSON_EXTRACT)
- CategoryField와 연동 방법
- 향후 Virtual Column 최적화 가이드
[모델 업데이트]
- Product 모델: 하이브리드 구조 필드로 fillable/casts 간소화
- 고정 필드: safety_stock, lead_time, is_variable_size, product_category, part_type, attributes_archive
- 동적 필드: attributes JSON (category_fields로 관리)
- 제거: BP-MES 전용 33개 필드 (이제 attributes에 저장)
- ProductComponent 모델: BOM 계산 필드 + 동적 필드
- 고정 필드: quantity_formula, condition
- 동적 필드: attributes JSON
- 제거: is_bending, bending_diagram, bending_details (이제 attributes에 저장)
[Seeder 실행]
- BpMesCategoryFieldsSeeder: FG/PT/절곡품 카테고리 및 필드 생성
- BpMesTenantStatFieldsSeeder: 통계 필드 설정 (마진율, 가공비, 인건비, 설치비 등)
[검증 완료]
- Tinker 모델 테스트 통과
- Pint 코드 포맷팅 검사 통과
- enhance_files_table: 이중 파일명 시스템 (display_name/stored_name), 폴더 관리, 문서 연결 지원
- create_folders_table: 동적 폴더 관리 시스템 (tenant별 커스터마이징 가능)
- 5개 stub 마이그레이션 생성 (file_share_links, file_deletion_logs, storage_usage_history, add_storage_columns_to_tenants)
- FolderSeeder stub 생성
- CURRENT_WORKS.md에 Phase 1 진행상황 문서화
fix: 파일 공유 및 삭제 기능 버그 수정
- ShareLinkRequest: PATH 파라미터 {id}를 file_id로 자동 병합
- routes/api.php: 공유 링크 다운로드를 auth.apikey 그룹 밖으로 이동 (인증 불필요)
- FileShareLink: File, Tenant 클래스 import 추가
- File 모델: softDeleteFile()에서 SoftDeletes의 delete() 메서드 사용
- FileStorageService: getTrash(), restoreFile(), permanentDelete()에서 onlyTrashed() 사용
- File 모델: Tenant 네임스페이스 수정 (App\Models\Tenants\Tenant)
refactor: Swagger 문서 정리 - File 태그를 Files로 통합
- FileApi.php의 모든 태그를 Files로 변경
- 구 파일 시스템 라우트 삭제 (prefix 'file')
- 구 FileController.php 삭제
- 신규 파일 저장소 시스템으로 완전 통합
fix: 모든 legacy 파일 컬럼 nullable 일괄 처리
- 5개 legacy 컬럼을 한 번에 nullable로 변경
* original_name, file_name, file_name_old (string)
* fileable_id, fileable_type (polymorphic)
- foreach 루프로 반복 작업 자동화
- 신규/기존 시스템 간 완전한 하위 호환성 확보
fix: legacy 파일 컬럼 nullable 처리 완료
- file_name, file_name_old 컬럼도 nullable로 변경
- 기존 시스템과 신규 시스템 간 완전한 하위 호환성 확보
- Legacy: original_name, file_name, file_name_old (nullable)
- New: display_name, stored_name (required)
fix: original_name 컬럼 nullable 처리
- original_name을 nullable로 변경하여 하위 호환성 유지
- 새 시스템에서는 display_name 사용, 기존 시스템은 original_name 사용 가능
fix: 파일 업로드 DB 컬럼 누락 및 메시지 구조 개선
- files 테이블에 감사 컬럼 추가 (created_by, updated_by, uploaded_by)
- ApiResponse::handle() 메시지 로직 개선 (접미사 제거)
- 다국어 지원을 위한 완성된 문장 구조 유지
- FileUploadRequest 파일 검증 규칙 수정
fix: 파일 저장소 버그 수정 및 신규 테넌트 폴더 자동 생성
- FolderSeeder 네임스페이스 수정 (App\Models\Tenant → App\Models\Tenants\Tenant)
- FileStorageController use 문 구문 오류 수정 (/ → \)
- TenantObserver에 신규 테넌트 기본 폴더 자동 생성 로직 추가
- 5개 기본 폴더 (생산관리, 품질관리, 회계, 인사, 일반)
- 에러 처리 및 로깅
- 회원가입 시 자동 실행