Files
TK-BOM-Project/RULES.md
Hyungi Ahn 9e5250a8f9 자재 분류 시스템 개선 및 통합 분류기 구현
- 통합 분류기 구현으로 키워드 우선순위 체계 적용
- HEX.PLUG → FITTING 분류 수정 (기존 VALVE 오분류 해결)
- 플랜지/밸브가 볼트로 오분류되는 문제 해결 (A193, A194 재질 키워드 우선순위 적용)
- 피팅 재질(A234, A403, A420) 기반 분류 추가
- 니플 길이 정보 보존 로직 개선
- 파이프 끝단 가공 정보를 구매 단계에서 제외
- PostgreSQL 사용으로 RULES.md 업데이트
- 상호 배타적 키워드 시스템 구현 (Level 1 키워드 우선)
2025-07-23 14:38:49 +09:00

189 lines
6.0 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.
# 🏗️ TK-MP-Project Rules & Context
## 📋 **프로젝트 개요**
- **목적**: 배관 자재 BOM 관리 및 리비전 비교 시스템
- **주요 기능**: 파일 업로드, 자재 분류, 리비전 비교, 구매 관리, 엑셀 내보내기
## 🛠️ **기술 스택**
```
Frontend: React.js + Material-UI + Vite + React Router DOM
Backend: FastAPI + SQLAlchemy + Python
Database: PostgreSQL (운영 및 개발)
기타: Axios, XLSX (SheetJS), file-saver
```
## 📁 **프로젝트 구조**
```
TK-MP-Project/
├── frontend/src/
│ ├── pages/ # 페이지 컴포넌트
│ ├── components/ # 재사용 컴포넌트
│ ├── utils/ # 유틸리티 (엑셀 등)
│ └── api.js # API 통신
├── backend/app/
│ ├── routers/ # API 라우터
│ ├── services/ # 비즈니스 로직 (분류기 등)
│ ├── models.py # DB 모델
│ └── main.py # FastAPI 앱
└── database/ # DB 스키마/시드
```
## 🗄️ **핵심 데이터베이스 스키마**
```sql
-- 핵심 테이블들
jobs (job_no, job_name, client_name, ...)
files (id, job_no, revision, original_filename, ...)
materials (id, file_id, original_description, classified_category, quantity, ...)
pipe_details (material_id, length_mm, ...)
-- 기타: fitting_details, flange_details, bolt_details, gasket_details
```
## 🔧 **중요한 코딩 컨벤션 & 패턴**
### **1. 자재 분류 시스템**
```python
# 항상 이 순서로 분류기 호출
classification_result = classify_pipe("", description, main_nom, length_value)
# 결과: {"category": "PIPE", "confidence": 0.95, ...}
```
### **2. 파이프 길이 처리 규칙**
```javascript
// ❌ 절대 하지 말 것: 평균 길이 계산/표시
// ✅ 항상 할 것: 총 길이 기준 계산
const totalLength = quantity * unitLength; // 총 길이 = 수량 × 단위길이
```
### **3. 자재 해싱 규칙**
```python
# 자재 고유성 판단: description + size + material_grade
material_hash = hashlib.md5(f"{description}|{size_spec}|{material_grade}".encode()).hexdigest()
```
### **4. 리비전 비교 로직**
```python
# 이전 리비전 자동 탐지: 숫자 기반 비교
current_rev_num = int(current_revision.replace("Rev.", ""))
# Rev.0 → Rev.1 → Rev.2 순서
```
## 🐛 **자주 발생하는 이슈 & 해결법**
### **1. 파이프 길이 합산 문제**
```python
# ❌ 잘못된 SQL: GROUP BY에 pd.length_mm 포함
# ✅ 올바른 방법: Python에서 같은 파이프들 합치기
if material_hash in materials_dict:
existing["quantity"] += float(new_quantity)
existing["total_length"] += new_quantity * unit_length
```
### **2. 프론트엔드 변수 초기화**
```javascript
// ❌ 사용 전에 선언하지 않음
const summaryData = [..., consolidatedMaterials.length, ...];
const consolidatedMaterials = consolidateMaterials(materials); // 뒤에 선언
// ✅ 사용 전에 먼저 선언
const consolidatedMaterials = consolidateMaterials(materials);
const summaryData = [..., consolidatedMaterials.length, ...];
```
### **3. API 응답 처리**
```javascript
// ✅ 항상 Axios 응답 구조 확인
setComparisonResult(result.data || result); // response.data 우선
```
## 🎯 **UI/UX 가이드라인**
### **1. 자재 표시 규칙**
- **파이프**: "총 길이: 4,561mm" (평균단위 표시 금지)
- **기타 자재**: "수량: 24 EA"
- **변경사항**: "이전: 2,781mm → 현재: 4,561mm / 변화: +1,780mm"
### **2. 버튼 네이밍**
- "BOM 목록으로" (뒤로가기)
- "엑셀 내보내기"
- "상세 비교 보기"
### **3. 페이지 네비게이션**
```javascript
// BOM 관련 페이지들은 job_no 기준으로 이동
navigate(`/bom-status?job_no=${jobNo}`);
navigate(`/material-comparison?job_no=${jobNo}&revision=${revision}`);
```
## 🔄 **개발 워크플로우**
### **1. 백엔드 변경 시**
```bash
# 항상 가상환경에서 실행 (사용자 선호사항)
cd backend
python -m uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
```
### **2. 데이터베이스 스키마 변경 시**
```sql
-- scripts/ 폴더에 마이그레이션 SQL 파일 생성
-- 번호 순서: 01_, 02_, 03_...
```
### **3. 커밋 메시지**
```
한국어로 작성 (사용자 선호사항)
예: "파이프 길이 계산 및 엑셀 내보내기 버그 수정"
```
## ⚠️ **절대 하지 말아야 할 것들**
1. **파이프 "평균단위" 표시** - 사용자가 혼란스러워함
2. **하드코딩된 길이 값** - 실제 데이터베이스 값 사용
3. **영어 커밋 메시지** - 사용자가 한국어 선호
4. **SQL에서 과도한 GROUP BY** - 같은 자재 분리됨
5. **비율 기반 길이 계산** - 실제 총길이 사용해야 함
## 💰 **구매 수량 계산 규칙**
### **1. 파이프 (PIPE)**
```javascript
// 6,000mm 단위 판매 + 절단여유분 2mm/조각
const cutLength = originalLength + 2; // 절단 여유분
const pipeCount = Math.ceil(cutLength / 6000); // 올림 처리
```
### **2. 피팅/계기/밸브 (FITTING/INSTRUMENT/VALVE)**
```javascript
// BOM 수량 그대로
const purchaseQuantity = bomQuantity;
```
### **3. 볼트/너트 (BOLT)**
```javascript
// +5% 후 4의 배수로 올림
const withMargin = bomQuantity * 1.05;
const purchaseQuantity = Math.ceil(withMargin / 4) * 4;
// 예: 150 → 157.5 → 160 SETS
```
### **4. 가스켓 (GASKET)**
```javascript
// 5의 배수로 올림
const purchaseQuantity = Math.ceil(bomQuantity / 5) * 5;
// 예: 7 → 10 EA
```
## 🎯 **현재 진행 상황**
- ✅ 자재 업로드 및 분류 시스템
- ✅ 리비전 비교 기능
- ✅ 파이프 길이 합산 로직 수정
- ✅ 엑셀 내보내기 기능
- 🚧 구매 수량 계산 시스템 (진행 중)
## 📚 **추가 참고사항**
- 사용자는 가상환경에서 Python 실행을 선호
- 백엔드 서버는 자동 재시작되므로 수동 재시작 불필요
- 작업 상태는 'in-progress'와 'complete'를 명확히 표시
---
**마지막 업데이트**: 2024-12-20