Files
sam-api/CURRENT_WORKS.md
hskwon a6b06be61d feat: 견적 단가 자동 적용 기능 추가
- 고객 그룹별 단가 조정 지원
- 견적 생성 시 자동 단가 조회
- 매출단가만 사용 (매입단가는 경고)
2025-10-13 21:52:34 +09:00

364 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# SAM API 저장소 작업 현황
## 2025-10-13 (일) - 고객그룹별 차등 가격 시스템 구축
### 주요 작업
- **고객 그룹 관리 시스템 구축**: 고객별 차등 가격 관리를 위한 client_groups 테이블 및 모델 구현
- **가격 이력 시스템 확장**: price_histories 테이블에 고객그룹별 가격 지원 추가
- **PricingService 신규 구축**: 우선순위 기반 가격 조회 로직 구현
- **EstimateService 통합**: 견적 생성 시 자동 가격 계산 기능 추가
### 추가된 파일:
- `database/migrations/2025_10_13_213549_create_client_groups_table.php` - 고객 그룹 테이블 생성
- `database/migrations/2025_10_13_213556_add_client_group_id_to_clients_table.php` - clients 테이블에 그룹 ID 추가
- `database/migrations/2025_10_13_213602_add_client_group_id_to_price_histories_table.php` - price_histories 테이블에 그룹 ID 추가
- `app/Models/Orders/ClientGroup.php` - 고객 그룹 모델
- `app/Services/Pricing/PricingService.php` - 가격 조회/관리 서비스
### 수정된 파일:
- `app/Models/Orders/Client.php` - ClientGroup 관계 추가
- `app/Models/Products/PriceHistory.php` - ClientGroup 관계 추가, 다양한 스코프 메서드 추가
- `app/Services/Estimate/EstimateService.php` - PricingService 의존성 주입 및 가격 계산 로직 통합
- `lang/ko/error.php` - price_not_found 에러 메시지 추가
### 작업 내용:
#### 1. 데이터베이스 스키마 설계
**client_groups 테이블:**
```sql
- id, tenant_id
- group_code (그룹 코드)
- group_name (그룹명)
- price_rate (가격 배율: 1.0 = 기준가, 0.9 = 90%, 1.1 = 110%)
- is_active (활성 여부)
- created_by, updated_by, deleted_by (감사 컬럼)
- created_at, updated_at, deleted_at
- UNIQUE(tenant_id, group_code)
```
**clients 테이블 확장:**
- `client_group_id` 컬럼 추가 (NULL 허용 = 기본 그룹)
**price_histories 테이블 확장:**
- `client_group_id` 컬럼 추가 (NULL = 기본 가격, 값 있으면 그룹별 차등 가격)
- 인덱스 재구성: (tenant_id, item_type_code, item_id, client_group_id, started_at)
#### 2. 모델 관계 설정
**ClientGroup 모델:**
- `clients()` → hasMany 관계
- `scopeActive()` → 활성 그룹만 조회
- `scopeCode()` → 코드로 검색
**Client 모델:**
- `clientGroup()` → belongsTo 관계
**PriceHistory 모델:**
- `clientGroup()` → belongsTo 관계
- `item()` → Polymorphic 관계 (Product/Material)
- 다양한 스코프 메서드:
- `scopeForItem()` → 특정 항목 필터링
- `scopeForClientGroup()` → 고객 그룹 필터링
- `scopeValidAt()` → 기준일 기준 유효한 가격
- `scopeSalePrice()` → 매출단가만
- `scopePurchasePrice()` → 매입단가만
#### 3. PricingService 핵심 로직
**가격 조회 우선순위:**
```php
1순위: 고객 그룹별 매출단가 (client_group_id 있음)
2순위: 기본 매출단가 (client_group_id = NULL)
3순위: NULL (경고 발생)
// ❌ 제거: 매입단가는 견적에서 사용하지 않음 (순수 참고용)
```
**주요 메서드:**
- `getItemPrice()` → 단일 항목 가격 조회
- `getBulkItemPrices()` → 여러 항목 일괄 조회
- `upsertPrice()` → 가격 등록/수정
- `listPrices()` → 가격 이력 조회 (페이지네이션)
- `deletePrice()` → 가격 삭제 (Soft Delete)
#### 4. EstimateService 통합
**견적 생성 프로세스:**
```php
1. BOM 계산 (수량만)
2. BOM 항목의 가격 조회 (PricingService)
3. unit_price × quantity = total_price 계산
4. 전체 항목의 total_price 합산 = total_amount
5. 가격 없는 항목 경고 로그 기록
```
**수정된 메서드:**
- `createEstimate()` → client_id 전달, total_amount 재계산
- `updateEstimate()` → 파라미터 변경 시 가격 재계산
- `createEstimateItems()` → 가격 조회 로직 추가, float 반환
#### 5. 에러 처리 및 로깅
**가격 없는 항목 처리:**
- 경고 메시지 반환: `__('error.price_not_found', [...])`
- Laravel Log에 경고 기록
- 견적 생성은 계속 진행 (unit_price = 0)
- 프론트엔드에서 경고 표시 가능
### 비즈니스 규칙 정리:
#### 매입단가 vs 매출단가
- **매입단가 (PURCHASE)**: 순수 참고용, 견적 계산에 미사용
- **매출단가 (SALE)**: 실제 견적 계산에 사용
- **STANDARD 가격**: 경동 비즈니스에서는 불필요 (사용하지 않음)
#### 고객 그룹별 차등 가격
```
예시 데이터:
- 기본 가격: 100,000원 (client_group_id = NULL)
- A그룹 가격: 90,000원 (client_group_id = 1, price_rate = 0.9)
- B그룹 가격: 110,000원 (client_group_id = 2, price_rate = 1.1)
조회 로직:
- A그룹 고객 → 90,000원 (1순위)
- B그룹 고객 → 110,000원 (1순위)
- 일반 고객 → 100,000원 (2순위)
- 가격 없음 → NULL + 경고 (3순위)
```
### 마이그레이션 실행 결과:
```bash
✅ 2025_10_13_213549_create_client_groups_table (46.85ms)
✅ 2025_10_13_213556_add_client_group_id_to_clients_table (38.75ms)
✅ 2025_10_13_213602_add_client_group_id_to_price_histories_table (38.46ms)
```
### 코드 품질:
- Laravel Pint 포맷팅 완료 (5 files, 4 style issues fixed)
- SAM API Development Rules 준수
- Service-First 아키텍처 유지
- BelongsToTenant 멀티테넌트 스코프 적용
- SoftDeletes 적용
- 감사 컬럼 (created_by, updated_by, deleted_by) 포함
### 예상 효과:
1. **유연한 가격 관리**: 고객 그룹별 차등 가격 설정 가능
2. **자동 가격 계산**: 견적 생성 시 수동 입력 불필요
3. **이력 관리**: 기간별 가격 변동 이력 추적
4. **확장성**: 향후 복잡한 가격 정책 적용 가능
5. **투명성**: 가격 출처 추적 가능 (price_history_id, client_group_id)
### 향후 작업:
- [x] PricingService 구현
- [x] EstimateService 통합
- [ ] 가격 관리 API 엔드포인트 추가 (CRUD)
- [ ] Swagger 문서 작성 (가격 관련 API)
- [ ] 고객 그룹 관리 API 엔드포인트 추가
- [ ] Frontend 가격 관리 화면 구현
- [ ] 가격 일괄 업로드 기능 추가
### Git 커밋 준비:
- 다음 커밋 예정: `feat: 고객그룹별 차등 가격 시스템 구축`
---
## 2025-10-01 (화) - Client API 및 Swagger 문서 구조 개선
### 주요 작업
- **Client API Swagger 문서 생성**: Controller에서 분리된 Swagger 파일 생성
- **Swagger 구조 표준화**: Controller는 비즈니스 로직만, Swagger는 별도 파일로 관리
- **CLAUDE.md 업데이트**: Swagger 문서 작성 규칙 명확화
### 추가된 파일:
- `app/Swagger/v1/ClientApi.php` - Client API Swagger 문서 (Tag, Schemas, Endpoints)
### 수정된 파일:
- `app/Http/Controllers/Api/V1/ClientController.php` - Swagger 어노테이션 제거 (비즈니스 로직만 유지)
- `CLAUDE.md` - Swagger 문서 작성 규칙 섹션 업데이트
### 작업 내용:
#### 1. Swagger 문서 구조 표준화
**기존 방식 (잘못된 방식):**
- Controller에 Swagger 어노테이션 직접 작성
- 비즈니스 로직과 API 문서가 혼재
- Controller 가독성 저하
**새로운 방식 (표준 방식):**
- `app/Swagger/v1/{Resource}Api.php` 별도 파일로 관리
- Controller는 순수 비즈니스 로직만 포함
- Swagger 문서는 독립적으로 관리
#### 2. ClientApi.php 구조
```php
namespace App\Swagger\v1;
/**
* @OA\Tag - 리소스 태그 정의
* @OA\Schema(schema="Client") - 모델 스키마
* @OA\Schema(schema="ClientPagination") - 페이지네이션
* @OA\Schema(schema="ClientCreateRequest") - 생성 요청
* @OA\Schema(schema="ClientUpdateRequest") - 수정 요청
*/
class ClientApi {
public function index() {} // GET /api/v1/clients
public function show() {} // GET /api/v1/clients/{id}
public function store() {} // POST /api/v1/clients
public function update() {} // PUT /api/v1/clients/{id}
public function destroy() {} // DELETE /api/v1/clients/{id}
public function toggle() {} // PATCH /api/v1/clients/{id}/toggle
}
```
#### 3. CLAUDE.md 규칙 업데이트
**추가된 내용:**
- Swagger 파일 위치: `app/Swagger/v1/`
- 파일 네이밍: `{Resource}Api.php`
- Controller 정책: Swagger 어노테이션 금지
- Schemas 구성: Model, Pagination, CreateRequest, UpdateRequest
- 재생성 명령어: `php artisan l5-swagger:generate`
#### 4. Client API 엔드포인트 구성
- **GET** `/api/v1/clients` - 거래처 목록 (페이지네이션)
- **GET** `/api/v1/clients/{id}` - 거래처 상세
- **POST** `/api/v1/clients` - 거래처 생성
- **PUT** `/api/v1/clients/{id}` - 거래처 수정
- **DELETE** `/api/v1/clients/{id}` - 거래처 삭제 (soft)
- **PATCH** `/api/v1/clients/{id}/toggle` - 활성/비활성 토글
### 시스템 개선 효과:
1. **코드 가독성 향상**: Controller가 순수 비즈니스 로직만 포함
2. **문서 관리 효율성**: Swagger 문서를 독립적으로 관리 가능
3. **표준화**: 모든 API가 동일한 구조로 문서화
4. **유지보수성**: Swagger 변경 시 Controller 영향 없음
### Swagger 재생성:
```bash
php artisan l5-swagger:generate
```
- Client API가 Swagger UI에 "Client" 태그로 표시됨
- `/api-docs/index.html`에서 확인 가능
### 향후 작업:
- 다른 Controller에도 동일한 패턴 적용
- Swagger 문서 품질 검증
- API 엔드포인트 테스트
---
## 2025-09-24 (화) - FK 제약조건 최적화 및 데이터베이스 성능 개선
### 주요 작업
- 데이터베이스 FK 제약조건 분석 및 최적화
- 성능과 관리 편의성을 위한 비중요 FK 제거
- 3단계 점진적 FK 제거 마이그레이션 구현
### 추가된 파일:
- `database/migrations/2025_09_24_214146_remove_non_critical_foreign_keys_phase1.php` - 1차 FK 제거 (Classifications, Departments)
- `database/migrations/2025_09_24_214200_remove_estimate_foreign_keys_phase2.php` - 2차 FK 제거 (견적 시스템)
- `database/migrations/2025_09_24_214300_remove_material_foreign_key_phase3.php` - 3차 FK 제거 (제품-자재 관계)
- `CURRENT_WORKS.md` - 저장소별 작업 현황 추적
### 수정된 파일:
- `CLAUDE.md` - CURRENT_WORKS.md 파일 위치 규칙 명확화
- `database/migrations/2025_09_24_000002_create_dynamic_estimate_fields.php` - level 컬럼 제거로 마이그레이션 오류 해결
### 작업 내용:
#### 1. FK 제약조건 현황 분석
- 현재 8개 마이그레이션에서 FK 제약조건 사용 확인
- 권한 관리, 제품/자재 관리, 견적 시스템, 기타 시스템별 분류
- 총 15+개의 FK 제약조건 식별
#### 2. 중요도별 테이블 분류
**🔴 핵심 테이블 (FK 유지 필수):**
- 인증/권한 시스템: users, roles, permissions 관계
- 제품/BOM 관리 핵심: products.category_id, product_components 내부 관계
- 멀티테넌트 핵심: 모든 tenant_id 참조
**🟡 중요 테이블 (FK 선택적 유지):**
- 견적 시스템: estimates, estimate_items 관계
- 자재 관리: product_components.material_id
**🟢 일반 테이블 (FK 제거 권장):**
- 분류/코드 관리: classifications.tenant_id
- 부서 관리: departments.parent_id (자기참조)
- 감사 로그: 모든 audit 관련 FK
#### 3. 코드 영향도 분석 결과
**✅ 중요 결론: 모델/컨트롤러/서비스 코드 수정 불필요!**
- Laravel Eloquent 관계가 FK 제약조건과 독립적으로 작동
- 현재 코드가 CASCADE 동작에 의존하지 않음
- BelongsToTenant 트레잇과 소프트 딜리트로 무결성 관리
- 비즈니스 로직이 애플리케이션 레벨에서 처리됨
#### 4. 3단계 점진적 FK 제거 전략
**Phase 1 (즉시 적용 가능):**
- `classifications.tenant_id``tenants`
- `departments.parent_id``departments` (자기참조)
- 영향도: 낮음, 관리 편의성 증가
**Phase 2 (견적 시스템):**
- `estimates.model_set_id``categories`
- `estimate_items.estimate_id``estimates`
- 영향도: 중간, 성능 향상 효과
- 멀티테넌트 보안 FK는 유지
**Phase 3 (신중한 검토 필요):**
- `product_components.material_id``materials`
- 영향도: 중간, 자재 관리 유연성 증가
- 핵심 제품 관계 FK는 유지
#### 5. 마이그레이션 특징
- 동적 FK 이름 탐지로 안전한 제거
- 성능을 위한 인덱스 유지/추가
- 상세한 진행 상황 로깅
- 완전한 롤백 기능
- 각 단계별 영향도와 주의사항 문서화
### 데이터베이스 마이그레이션 상태:
- 기존 마이그레이션 오류 해결 완료 (level 컬럼 이슈)
- 새로운 FK 제거 마이그레이션 3개 생성
- 롤백 가능한 안전한 구조로 설계
### 예상 효과:
1. **성능 향상**: 견적 시스템과 분류 관리에서 FK 검증 오버헤드 제거
2. **관리 편의성**: 부서 구조 변경, 자재 관리 시 유연성 증가
3. **개발 생산성**: 데이터 변경 시 FK 제약 에러 감소
4. **확장성**: 향후 시스템 확장 시 유연한 스키마 변경 가능
### 향후 작업:
1. Phase 1 마이그레이션 개발 서버 테스트
2. 각 단계별 성능 영향 모니터링
3. Service 레벨에서 데이터 무결성 검증 로직 보강 검토
4. 프로덕션 적용 전 백업 및 롤백 계획 수립
### 논리적 관계 자동화 시스템 구축:
- **자동화 도구 4개 생성**: 관계 문서 생성/업데이트/모델생성 명령어
- **Provider 시스템**: 마이그레이션 후 자동 문서 업데이트
- **간소화 문서**: 즉시 사용 가능한 관계 문서 생성 (LOGICAL_RELATIONSHIPS_SIMPLE.md)
### 새로운 명령어:
- `php artisan db:update-relationships` - 모델에서 관계 자동 추출
- `php artisan db:generate-simple-relationships` - 기본 관계 문서 생성
- `php artisan make:model-with-docs` - 모델 생성 후 관계 문서 자동 업데이트
### ERD 생성 시스템:
- **ERD 생성 도구**: beyondcode/laravel-er-diagram-generator 활용
- **GraphViz 설치**: `brew install graphviz`로 dot 명령어 지원
- **모델 오류 해결**: BelongsToTenantTrait → BelongsToTenant 수정
- **생성 결과**: 60개 모델의 완전한 관계도 생성 (`graph.png`, 4.1MB)
- **명령어**: `php artisan generate:erd --format=png`
### 예상 효과 (업데이트):
1. **시각화 개선**: 복잡한 다중 테넌트 구조의 시각적 이해 향상
2. **개발 생산성**: ERD를 통한 빠른 스키마 파악 및 설계 검증
3. **문서화 자동화**: 스키마 변경 시 ERD 자동 업데이트 가능
4. **기존 효과 유지**: 성능 향상, 관리 편의성, 확장성은 FK 제거로 달성
### Git 커밋:
- `cfd4c25` - fix: categories 테이블 level 컬럼 제거로 마이그레이션 오류 해결
- `7dafab3` - docs: CURRENT_WORKS.md 파일 위치 규칙 명확화
- `c63e676` - feat: 데이터베이스 FK 제약조건 최적화 및 3단계 마이그레이션 구현