Files
TK-BOM-Project/RULES.md
Hyungi Ahn 0f9a5ad2ea
Some checks failed
SonarQube Analysis / SonarQube Scan (push) Has been cancelled
🔧 재질 정보 표시 개선 및 UI 확장
 주요 수정사항:
- 재질 GRADE 전체 표기: ASTM A106 B 완전 표시 (A10 잘림 현상 해결)
- material_grade_extractor.py 정규표현식 패턴 개선
- files.py 파일 업로드 시 재질 추출 로직 수정
- CSS 그리드 너비 확장으로 텍스트 잘림 현상 해결
- 사용자 요구사항 엑셀 다운로드 기능 완료

🎯 해결된 문제:
1. ASTM A106 B → ASTM A10 잘림 문제
2. 재질 컬럼 너비 부족으로 인한 표시 문제
3. 사용자 요구사항이 엑셀에 반영되지 않는 문제

📋 다음 단계 준비:
- 파이프 끝단 정보 제외 취합 로직 개선
- 플랜지 타입 정보 확장
- 자재 분류 필터 기능 추가
2025-09-25 08:32:17 +09:00

2108 lines
71 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: 통합 프로젝트 문서존
> **최종 업데이트**: 2025년 1월 (통합 문서 생성)
---
## 📋 프로젝트 개요
**TK-MP-Project**는 BOM (Bill of Materials) 시스템의 기능 이상을 해결하고, 도면 완성 후 자재 관리의 모든 프로세스를 자동화하는 종합 시스템 개발 프로젝트입니다.
### 🎯 핵심 미션
**"도면 완성 후 자재 관리의 모든 번거로움을 해결"**
### 주요 해결 과제
- 📄 **파일 분석 자동화**: 엑셀/CSV 자재 목록의 자동 분류 및 정제
- 🔍 **정확한 분류 체계**: 파이프/피팅/볼트/밸브/계기류의 4단계 자동 분류
- 💾 **체계적 데이터 관리**: 프로젝트별 버전 관리 및 이력 추적
- 📊 **업무별 맞춤 출력**: 구매/생산/품질 각 팀의 필요에 맞는 자료 생성
- 🔄 **리비전 변화 추적**: 도면 변경 시 자재 변경사항 자동 비교
---
## 💻 기술 스택
### Frontend
- **Language**: JavaScript (ES6+)
- **Framework**: React 18 + Vite (Material-UI 제거됨)
- **Router**: 상태 기반 라우팅 (React Router 대체)
- **HTTP Client**: Axios
- **File Processing**: XLSX (SheetJS), file-saver
- **Charts**: Chart.js + react-chartjs-2
- **Styling**: 순수 HTML/CSS (인라인 스타일)
### Backend
- **Language**: Python 3.9+
- **Framework**: FastAPI (고성능 API 서버)
- **Database**: PostgreSQL 15 (복잡한 관계형 데이터 처리)
- **ORM**: SQLAlchemy (데이터베이스 모델링)
- **Data Processing**: Pandas, openpyxl (파일 처리)
- **Cache**: Redis 7
### DevOps & Tools
- **Containerization**: Docker & Docker Compose
- **Web Server**: Nginx (프로덕션)
- **Database Admin**: pgAdmin4
- **Version Control**: Git
- **Development**: VS Code + Python 확장
---
## 🏗️ 코드 구조 및 컴포넌트 관계도
### 📁 프론트엔드 구조
```
frontend/src/
├── App.jsx # 메인 애플리케이션 (상태 기반 라우팅)
├── SimpleLogin.jsx # 로그인 컴포넌트
├── api.js # API 클라이언트 (Axios 설정)
├── components/ # 재사용 가능한 컴포넌트
│ ├── NavigationMenu.jsx # 사이드바 네비게이션 (권한 기반)
│ ├── PersonalizedDashboard.jsx # 개인화된 대시보드 (역할별 맞춤)
│ ├── ProjectSelector.jsx # 프로젝트 선택 드롭다운 (검색 기능)
│ ├── BOMFileUpload.jsx # BOM 파일 업로드 폼
│ ├── BOMFileTable.jsx # BOM 파일 목록 테이블
│ └── RevisionUploadDialog.jsx # 리비전 업로드 다이얼로그
└── pages/ # 페이지 컴포넌트
├── DashboardPage.jsx # 대시보드 (기존)
├── ProjectWorkspacePage.jsx # 프로젝트별 워크스페이스 (신규)
├── BOMUploadPage.jsx # BOM 업로드 페이지 (신규)
├── ProjectsPage.jsx # 프로젝트 관리
├── JobSelectionPage.jsx # 프로젝트 선택
├── BOMStatusPage.jsx # BOM 관리 메인
├── SimpleMaterialsPage.jsx # 자재 목록 (Material-UI 제거됨)
├── MaterialComparisonPage.jsx # 리비전 비교
└── RevisionPurchasePage.jsx # 구매 확정
```
### 📁 백엔드 구조
```
backend/
├── app/
│ ├── main.py # FastAPI 애플리케이션 진입점
│ ├── config.py # 설정 관리 (Pydantic Settings)
│ ├── auth/ # 인증 모듈
│ │ ├── __init__.py
│ │ ├── models.py # SQLAlchemy 인증 모델
│ │ ├── jwt_service.py # JWT 토큰 관리
│ │ ├── auth_service.py # 인증 비즈니스 로직
│ │ ├── auth_controller.py # 인증 API 엔드포인트
│ │ └── middleware.py # 권한 미들웨어
│ ├── api/ # API 라우터
│ │ └── file_management.py # 파일 관리 API
│ ├── routers/ # 기존 라우터
│ │ ├── files.py # 파일/자재 API
│ │ └── jobs.py # 프로젝트 API
│ ├── services/ # 비즈니스 로직 서비스
│ │ └── file_service.py # 파일 처리 서비스
│ ├── utils/ # 유틸리티
│ │ ├── logger.py # 로깅 설정
│ │ ├── cache_manager.py # Redis 캐시 관리
│ │ ├── file_validator.py # 파일 검증
│ │ ├── error_handlers.py # 에러 핸들링
│ │ └── transaction_manager.py # DB 트랜잭션 관리
│ └── schemas/ # Pydantic 스키마
│ └── response_models.py # API 응답 모델
├── scripts/ # DB 마이그레이션 스크립트
└── requirements.txt # Python 의존성
```
### 🔄 컴포넌트 관계도
```mermaid
graph TD
A[App.jsx] --> B[SimpleLogin.jsx]
A --> C[NavigationMenu.jsx]
A --> D[페이지 컴포넌트들]
D --> E[JobSelectionPage.jsx]
D --> F[BOMStatusPage.jsx]
D --> G[SimpleMaterialsPage.jsx]
F --> H[BOMFileUpload.jsx]
F --> I[BOMFileTable.jsx]
F --> J[RevisionUploadDialog.jsx]
K[api.js] --> L[Backend APIs]
subgraph "Backend Services"
L --> M[auth_controller.py]
L --> N[file_management.py]
L --> O[files.py]
L --> P[jobs.py]
end
subgraph "Business Logic"
M --> Q[auth_service.py]
N --> R[file_service.py]
end
subgraph "Data Layer"
Q --> S[auth/models.py]
R --> T[Database Tables]
end
```
### 🎯 컴포넌트 분리 원칙 (적용됨)
#### 1. **페이지 컴포넌트** (200-300줄 이하)
- 전체 페이지 레이아웃과 상태 관리
- 하위 컴포넌트들의 조합
- API 호출 및 데이터 흐름 제어
#### 2. **기능별 컴포넌트** (100-150줄 이하)
- 단일 책임 원칙 적용
- 재사용 가능한 독립적 기능
- Props를 통한 데이터 전달
#### 3. **서비스 레이어** (200줄 이하)
- 비즈니스 로직 분리
- API와 컴포넌트 사이의 중간 계층
- 데이터 변환 및 검증
### 📋 분리된 컴포넌트 목록
| 원본 파일 | 분리 후 | 줄 수 변화 | 상태 |
|----------|---------|-----------|------|
| `MaterialsPage.jsx` | `SimpleMaterialsPage.jsx` | 1000+ → 300줄 | ✅ 완료 |
| `BOMStatusPage.jsx` | 3개 컴포넌트로 분리 | 400+ → 200줄 | ✅ 완료 |
| - | `BOMFileUpload.jsx` | 새로 생성 (100줄) | ✅ 완료 |
| - | `BOMFileTable.jsx` | 새로 생성 (150줄) | ✅ 완료 |
| - | `RevisionUploadDialog.jsx` | 새로 생성 (80줄) | ✅ 완료 |
### 🔧 향후 분리 대상
| 파일명 | 현재 줄 수 | 분리 계획 | 우선순위 |
|--------|-----------|----------|---------|
| `MaterialComparisonPage.jsx` | 500줄+ | 비교 로직 분리 | 중간 |
| `RevisionPurchasePage.jsx` | 300줄+ | 구매 로직 분리 | 낮음 |
| `auth_service.py` | 300줄+ | 기능별 서비스 분리 | 높음 |
### 🌐 **API 엔드포인트 전체 맵** (2025.01 최신)
> **중요**: 새로운 API 추가 시 반드시 이 섹션을 업데이트하고, 버전 관리 및 하위 호환성을 고려해야 합니다.
#### **📋 API 문서화 규칙**
1. **새 API 추가 시**: 이 문서에 즉시 반영
2. **API 변경 시**: 변경 이력과 마이그레이션 가이드 포함
3. **권한 표시**: 각 엔드포인트별 필요 권한 명시
4. **응답 형식**: 표준 응답 구조 준수
#### **🚨 API 사용 가이드라인 (혼동 방지)** ⭐ 중요
##### **1. 자재 관련 API 통합 사용법**
```javascript
// ✅ 올바른 사용법 - 통합된 API 사용
import { fetchMaterials } from '../api';
// 파일별 자재 조회
const materials = await fetchMaterials({ file_id: 123, limit: 1000 });
// 프로젝트별 자재 조회
const materials = await fetchMaterials({ job_no: 'J24-001', limit: 1000 });
// 리비전별 자재 조회
const materials = await fetchMaterials({
job_no: 'J24-001',
revision: 'Rev.1',
limit: 1000
});
// ❌ 잘못된 사용법 - 직접 API 호출 금지
const response = await api.get('/files/materials-v2', { params }); // 금지
const response = await api.get('/files/materials', { params }); // 존재하지 않음
```
##### **2. API 함수 vs 직접 호출 규칙**
```javascript
// ✅ 권장: api.js의 래퍼 함수 사용
import { fetchMaterials, fetchFiles, fetchJobs } from '../api';
// ❌ 비권장: 직접 API 호출 (특별한 경우에만)
const response = await api.get('/files/materials-v2');
```
##### **3. 백엔드 API 엔드포인트 명명 규칙**
- **기본 형태**: `/{모듈}/{리소스}`
- **버전 관리**: `/{모듈}/{리소스}-v2` (하위 호환성 유지)
- **액션 기반**: `/{모듈}/{리소스}/{액션}`
**예시:**
```
/files/materials-v2 # 자재 목록 (최신 버전)
/files/materials/summary # 자재 요약 통계
/files/materials/compare-revisions # 리비전 비교
/purchase/items/calculate # 구매 수량 계산
/materials/compare-revisions # 자재 비교 (별도 모듈)
```
##### **4. 프론트엔드 API 호출 표준화**
```javascript
// api.js - 모든 API 함수는 여기에 정의
export function fetchMaterials(params) {
return api.get('/files/materials-v2', { params });
}
export function fetchFiles(params) {
return api.get('/files', { params });
}
export function fetchJobs(params) {
return api.get('/jobs/', { params });
}
// 컴포넌트에서 사용
import { fetchMaterials } from '../api';
const response = await fetchMaterials({ job_no: 'J24-001' });
```
---
#### **🔐 인증 API (`/auth/`)**
```http
POST /auth/login # ()
POST /auth/register # ()
POST /auth/refresh # ( )
POST /auth/logout # ( )
GET /auth/me # ( )
GET /auth/verify # ( )
GET /auth/users # ()
PUT /auth/users/{id} # ()
DELETE /auth/users/{id} # ()
```
#### **📋 프로젝트 관리 API (`/jobs/`)**
```http
GET /jobs/ # ()
POST /jobs/ # (+)
GET /jobs/{id} # ()
PUT /jobs/{id} # (+)
DELETE /jobs/{id} # ()
GET /jobs/stats # (+)
POST /jobs/{id}/assign # (+)
```
**실제 응답 구조:**
```json
// GET /jobs/ - 프로젝트 목록
{
"success": true,
"total_count": 2,
"jobs": [
{
"job_no": "J24-001",
"job_name": "울산 SK에너지 정유시설 증설 배관공사",
"project_name": "울산 SK에너지 정유시설 증설 배관공사",
"client_name": "삼성엔지니어링",
"end_user": "SK에너지",
"epc_company": "삼성엔지니어링",
"project_site": "울산광역시 온산공단",
"contract_date": "2024-03-15",
"delivery_date": "2024-08-30",
"delivery_terms": "FOB 울산항",
"project_type": "냉동기",
"status": "진행중",
"description": "정유시설 증설을 위한 배관 자재 공급",
"created_at": "2025-07-15T03:44:46.035325"
}
]
}
```
#### **📄 파일/자재 관리 API (`/files/`)**
```http
GET /files # ()
POST /files/upload # (+)
DELETE /files/delete/{file_id} # (+)
GET /files/stats # / ()
GET /files/materials-v2 # ()
GET /files/materials/summary # ()
GET /files/materials/compare-revisions # ()
GET /files/pipe-details # ()
GET /files/fitting-details # ()
GET /files/valve-details # ()
POST /files/user-requirements # ()
GET /files/user-requirements # ()
POST /files/materials/{id}/verify # (+)
PUT /files/materials/{id}/update-classification # (+)
POST /files/materials/confirm-purchase # (+)
```
**⚠️ 중요: 자재 API 사용 시 주의사항**
-**사용**: `/files/materials-v2` (최신 버전, 모든 기능 지원)
-**사용 금지**: `/files/materials` (존재하지 않음, 404 오류 발생)
- 🔄 **마이그레이션**: 모든 컴포넌트에서 `fetchMaterials()` 함수 사용 권장
#### **🔧 자재 분류/비교 API (`/materials/`)**
```http
POST /materials/compare-revisions # (+)
GET /materials/comparison-history # ()
GET /materials/inventory-status # (+)
POST /materials/confirm-purchase # (+)
GET /materials/purchase-status # (+)
```
#### **🛒 구매 관리 API (`/purchase/`)**
```http
GET /purchase/items/calculate # (+)
POST /purchase/confirm # (+)
POST /purchase/items/save # (+)
GET /purchase/items # (+)
GET /purchase/revision-diff # (+)
POST /purchase/orders/create # (+)
GET /purchase/orders # (+)
```
#### **📊 대시보드 API (`/dashboard/`)** ⭐ 신규 (2025.01)
```http
GET /dashboard/stats # ( )
GET /dashboard/activities # ( )
GET /dashboard/recent-activities # (+)
GET /dashboard/quick-actions # ( )
```
**실제 응답 구조:**
```json
// GET /dashboard/stats - 사용자별 맞춤 통계
{
"success": true,
"user_role": "admin",
"stats": {
"total_projects": 45,
"active_users": 12,
"system_status": "정상",
"today_uploads": 8
// 주의: quickActions, metrics 등은 프론트엔드에서 목 데이터로 보완됨
}
}
// GET /dashboard/activities - 사용자 활동 이력
{
"success": true,
"activities": [
{
"id": 1,
"activity_type": "FILE_UPLOAD",
"activity_description": "파일 업로드: ProjectX_Rev0.xlsx",
"created_at": "2025-08-30T08:30:00Z",
"target_id": 123,
"target_type": "FILE"
}
]
}
```
#### **🔧 튜빙 시스템 API (`/tubing/`)**
```http
GET /tubing/categories # ()
GET /tubing/manufacturers # ()
GET /tubing/specifications # ()
GET /tubing/products # ()
POST /tubing/products # (+)
POST /tubing/material-mapping # - (+)
GET /tubing/material-mappings/{material_id} # ()
GET /tubing/search # ()
```
---
### 📝 **API 개발 가이드라인** (2025.01 신규)
#### **1. 새 API 모듈 추가 절차**
```python
# 1. 라우터 파일 생성
# backend/app/routers/new_module.py
from fastapi import APIRouter, Depends, HTTPException
from ..auth.middleware import get_current_user
from ..services.activity_logger import log_activity_from_request
router = APIRouter(prefix="/new-module", tags=["new-module"])
@router.post("/action")
async def new_action(
request: Request,
current_user: dict = Depends(get_current_user),
db: Session = Depends(get_db)
):
# 사용자 추적 필수
log_activity_from_request(
db, request, current_user['username'],
"NEW_ACTION", "새 액션 실행"
)
# 비즈니스 로직...
```
```python
# 2. main.py에 라우터 등록
try:
from .routers import new_module
app.include_router(new_module.router, tags=["new-module"])
except ImportError:
logger.warning("new_module 라우터를 찾을 수 없습니다")
```
```markdown
# 3. RULES.md 업데이트 (이 문서)
#### **🆕 새 모듈 API (`/new-module/`)**
GET /new-module/list # 목록 조회 (사용자)
POST /new-module/action # 액션 실행 (권한) ⭐ 사용자 추적
```
#### **2. API 응답 표준 형식**
```json
// 성공 응답
{
"success": true,
"message": "작업이 완료되었습니다",
"data": { ... },
"timestamp": "2025-01-XX 12:00:00"
}
// 에러 응답
{
"success": false,
"error": "에러 메시지",
"error_code": "ERROR_CODE",
"detail": "상세 에러 정보"
}
```
#### **2-1. 실제 응답 구조 문서화 규칙** ⭐ 중요
- **모든 API는 실제 응답 구조를 RULES.md에 명시 필수**
- **프론트엔드 개발 시 참조할 수 있도록 JSON 예시 포함**
- **필드명, 데이터 타입, 중첩 구조 모두 정확히 기록**
- **목 데이터 사용 시 주석으로 명시**
- **API 변경 시 문서도 즉시 업데이트**
**문서화 예시:**
```json
// GET /jobs/ - 프로젝트 목록 (실제 응답)
{
"success": true,
"total_count": 2,
"jobs": [
{
"job_no": "J24-001",
"project_name": "프로젝트명",
"status": "진행중",
"client_name": "고객사명"
// ... 모든 필드 명시
}
]
}
```
#### **3. 권한 레벨 정의**
- **공개**: 인증 불필요
- **사용자**: 로그인한 모든 사용자
- **설계자+**: designer, manager, admin
- **구매자+**: purchaser, manager, admin
- **매니저+**: manager, admin
- **관리자**: admin만
#### **4. 사용자 추적 필수 API** ⭐
다음 작업은 반드시 활동 로그를 기록해야 함:
- 파일 업로드/삭제
- 프로젝트 생성/수정/삭제
- 구매 확정/주문 생성
- 자재 분류/검증
- 시스템 설정 변경
#### **5. API 버전 관리**
```http
# ()
GET /files/upload
# ( )
GET /v2/files/upload
#
GET /files/upload
Accept: application/vnd.tkmp.v2+json
```
#### **6. 성능 고려사항**
- **페이지네이션**: 목록 API는 limit/offset 지원
- **필터링**: 쿼리 파라미터로 필터 조건 제공
- **캐싱**: 자주 조회되는 데이터는 Redis 캐싱
- **비동기 처리**: 대용량 파일 처리는 백그라운드 작업
---
### 🔄 **API 변경 이력** (2025.01)
#### **v2.2.0 (2025.09.05)** ⭐ 최신
-**정리**: API 엔드포인트 표준화 및 통합
-**문서화**: 전체 API 맵 업데이트 (실제 구현 기준)
-**개선**: 프론트엔드 API 호출 표준화 (`fetchMaterials` 함수 사용)
-**수정**: `/files/materials``/files/materials-v2` 마이그레이션 완료
-**추가**: API 사용 가이드라인 및 혼동 방지 규칙
-**추가**: 튜빙 시스템 API 문서화
#### **v2.1.1 (2025.08.30)**
-**문서화**: `/jobs/` API 실제 응답 구조 명시
-**문서화**: `/dashboard/` API 실제 응답 구조 명시
-**개선**: 프론트엔드-백엔드 API 응답 구조 불일치 해결
-**추가**: 실제 응답 구조 문서화 규칙 및 가이드라인
#### **v2.1.0 (2025.01.XX)**
-**추가**: `/dashboard/` API 모듈 (사용자별 맞춤 대시보드)
-**개선**: 모든 업로드/수정 API에 사용자 추적 추가
-**변경**: `/files/upload` - `uploaded_by` 필드 필수화
- ⚠️ **중단 예정**: `/old-endpoint` (v3.0에서 제거 예정)
#### **v2.0.0 (2025.01.XX)**
-**추가**: 인증 시스템 (`/auth/`) 완전 구현
-**추가**: 사용자 활동 로그 시스템
-**변경**: 모든 API에 JWT 토큰 인증 적용
- 🔄 **마이그레이션**: 기존 API 호출 시 Authorization 헤더 필수
---
### 📋 **개발자 체크리스트**
새 API 개발 시 다음 사항을 확인:
- [ ] **문서화**: RULES.md API 맵에 추가
- [ ] **인증**: 적절한 권한 레벨 설정
- [ ] **추적**: 중요 작업은 활동 로그 기록
- [ ] **검증**: 입력 데이터 검증 (Pydantic)
- [ ] **에러**: 표준 에러 응답 형식 준수
- [ ] **테스트**: 단위/통합 테스트 작성
- [ ] **로깅**: 적절한 로그 레벨로 기록
- [ ] **성능**: 대용량 데이터 처리 고려
### 📊 데이터 흐름도
```mermaid
sequenceDiagram
participant U as User
participant F as Frontend
participant A as Auth API
participant B as BOM API
participant D as Database
participant R as Redis Cache
U->>F: 로그인 요청
F->>A: POST /auth/login
A->>D: 사용자 검증
A->>F: JWT 토큰 반환
F->>F: 토큰 저장 (localStorage)
U->>F: BOM 페이지 접근
F->>B: GET /jobs/ (프로젝트 목록)
B->>D: 프로젝트 조회
B->>F: 프로젝트 데이터
U->>F: 프로젝트 선택
F->>B: GET /files?job_no=xxx
B->>R: 캐시 확인
alt 캐시 히트
R->>B: 캐시된 데이터
else 캐시 미스
B->>D: 파일 목록 조회
B->>R: 캐시 저장
end
B->>F: 파일 목록 반환
U->>F: 자재 확인 클릭
F->>B: GET /files/materials?file_id=xxx
B->>D: 자재 데이터 조회
B->>F: 자재 목록 반환
```
### 🔐 권한 체계
```mermaid
graph TD
A[사용자] --> B{역할}
B -->|admin| C[시스템 관리자]
B -->|user| D[일반 사용자]
B -->|viewer| E[조회 전용]
C --> F[모든 권한]
D --> G[BOM 관리]
D --> H[프로젝트 관리]
E --> I[조회만 가능]
F --> J[사용자 관리]
F --> K[시스템 설정]
G --> L[파일 업로드]
G --> M[자재 관리]
H --> N[프로젝트 CRUD]
```
---
## 🐳 Docker 실행 환경
### 컨테이너 구성
- **tk-mp-frontend**: React + Nginx (포트: 3000/13000)
- **tk-mp-backend**: FastAPI + Uvicorn (포트: 8000/18000)
- **tk-mp-postgres**: PostgreSQL (포트: 5432)
- **tk-mp-redis**: Redis (포트: 6379)
- **tk-mp-pgadmin**: pgAdmin4 (포트: 5050)
### 실행 방법
```bash
# 개발 환경
./scripts/dev.sh
# 또는
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d
# 프로덕션 환경
./scripts/prod.sh
# 또는
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
# 시놀로지 NAS 환경
docker-compose -f docker-compose.synology.yml up -d
# 기본 환경
docker-compose up -d
```
### 중요한 설정 사항
- **API URL 설정**:
- 개발환경: `http://localhost:8000` (직접 접근)
- 프로덕션: `/api` (nginx 프록시를 통한 상대경로)
- **데이터베이스 연결**: `postgres:5432` (컨테이너명 사용, localhost 아님!)
- **환경변수**: `VITE_API_URL`로 API URL 오버라이드 가능
---
## 📁 프로젝트 구조
```
TK-MP-Project/
├── README.md
├── docker-compose.yml
├── docker-compose.dev.yml
├── docker-compose.prod.yml
├── docker-compose.synology.yml
├── frontend/ # React 프론트엔드
│ ├── src/
│ │ ├── pages/ # 페이지 컴포넌트
│ │ ├── components/ # 재사용 컴포넌트
│ │ ├── utils/ # 유틸리티 (엑셀 등)
│ │ └── api.js # API 통신
│ ├── Dockerfile
│ └── nginx.conf
├── backend/ # FastAPI 백엔드
│ ├── app/
│ │ ├── routers/ # API 라우터
│ │ ├── services/ # 비즈니스 로직 (분류기 등)
│ │ ├── models.py # DB 모델
│ │ ├── main.py # FastAPI 앱
│ │ └── database.py # DB 연결 설정
│ ├── scripts/ # DB 마이그레이션
│ ├── uploads/ # 업로드된 파일
│ └── requirements.txt
├── database/ # DB 스키마 및 초기 데이터
│ └── init/
│ ├── 01_schema.sql
│ └── 02_seed_data.sql
└── scripts/ # 배포 스크립트
├── dev.sh
├── prod.sh
└── deploy-synology.sh
```
---
## 🗄️ 핵심 데이터베이스 스키마
### 핵심 테이블들
```sql
-- 프로젝트 관리
jobs (job_no, job_name, client_name, end_user, epc_company, status, ...)
-- 파일 관리
files (id, job_no, revision, original_filename, bom_name, parsed_count, ...)
-- 자재 정보
materials (id, file_id, original_description, classified_category, quantity, ...)
-- 자재별 상세 정보
pipe_details (material_id, length_mm, ...)
fitting_details, flange_details, bolt_details, gasket_details, instrument_details
```
### 주요 기능
- 프로젝트별 파일 버전 관리 (Rev.0, Rev.1, Rev.2)
- 자재 자동 분류 시스템 (카테고리, 재질, 사이즈)
- 분류 신뢰도 및 사용자 검증 시스템
---
## 🔧 중요한 코딩 컨벤션 & 패턴
### 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. 리비전 비교 로직 (2025.01 신규 ⭐)
```python
# 이전 리비전 자동 탐지: 숫자 기반 비교
current_rev_num = int(current_revision.replace("Rev.", ""))
# Rev.0 → Rev.1 → Rev.2 순서
# 자재 해싱 규칙 (RULES 준수)
material_hash = hashlib.md5(f"{description}|{size}|{material}".encode()).hexdigest()
# 리비전 비교 워크플로우
if revision != "Rev.0": # 리비전 업로드인 경우만
revision_comparison = get_revision_comparison(db, job_no, revision, materials_data)
if revision_comparison.get("has_previous_confirmation"):
# 변경없음: 기존 분류 결과 재사용 (confidence = 1.0)
# 변경됨 + 신규: 재분류 필요
materials_to_classify = changed_materials + new_materials
else:
# 이전 확정 자료 없음: 전체 분류
materials_to_classify = all_materials
```
### 5. 구매 수량 확정 워크플로우 (2025.01 신규 ⭐)
```python
# 확정 데이터 저장 구조
purchase_confirmations (마스터) confirmed_purchase_items (상세)
# 확정 시 파일 상태 업데이트
files.purchase_confirmed = TRUE
files.confirmed_at = timestamp
files.confirmed_by = username
# 리비전 업로드 시 최적화
- 확정된 자료 있음: 변경된 자재만 분류 (성능 향상)
- 확정된 자료 없음: 전체 자재 분류 (기존 방식)
```
### 6. 대용량 데이터 처리 규칙 (2025.01 신규 ⭐)
```python
# 413 오류 방지: 요청 데이터 최적화
# ❌ 전체 데이터 전송 (용량 초과)
purchase_items: List[dict] # 모든 필드 포함
# ✅ 필수 필드만 전송 (용량 최적화)
class PurchaseItemMinimal(BaseModel):
item_code: str
category: str
specification: str
size: str = ""
material: str = ""
bom_quantity: float
calculated_qty: float
unit: str = "EA"
safety_factor: float = 1.0
# 서버 요청 크기 제한 설정
app.add_middleware(RequestSizeLimitMiddleware, max_request_size=100 * 1024 * 1024) # 100MB
# Nginx 프록시 설정 (중요!)
server {
client_max_body_size 100M; # 전역 설정
location /api/ {
proxy_pass http://backend:8000/;
client_max_body_size 100M; # API 경로별 설정
proxy_request_buffering off; # 대용량 요청 최적화
}
}
```
---
## 📏 **코드 분리 기준 및 품질 가이드라인**
### 🎯 **코드 길이 기준 (2025.01 수립)**
#### **함수/메서드**
- **이상적**: 10-20줄
- **허용 가능**: 30줄 이하
- **리팩토링 필요**: 50줄 이상
#### **파일**
- **이상적**: 200-300줄
- **허용 가능**: 500줄 이하
- **분리 필요**: 800줄 이상
#### **클래스**
- **이상적**: 100-200줄
- **허용 가능**: 300줄 이하
- **분리 필요**: 500줄 이상
### 🔧 **리팩토링 원칙**
#### **1. 단일 책임 원칙 (SRP)**
```python
# ❌ 나쁜 예: 하나의 함수가 여러 일을 함
def process_file_and_save_and_classify(file):
# 파일 처리 + 저장 + 분류 (3가지 책임)
pass
# ✅ 좋은 예: 각각 분리
def process_file(file): pass
def save_file(file): pass
def classify_materials(materials): pass
```
#### **2. 함수 분리 기준**
- 중복 코드 3회 이상 → 함수로 분리
- 조건문이 3단계 이상 중첩 → 함수로 분리
- 한 함수에서 5개 이상 변수 사용 → 클래스 고려
#### **3. 파일 분리 기준**
```python
# 기능별 분리 예시
routers/ # API 엔드포인트
files.py # 파일 관련 API
jobs.py # 작업 관련 API
materials.py # 자재 관련 API
services/ # 비즈니스 로직
classifiers/ # 분류기들
validators/ # 검증 로직
processors/ # 처리 로직
utils/ # 공통 유틸리티
logger.py # 로깅
validators.py # 검증
helpers.py # 헬퍼 함수
```
### 🛡️ **보안 코딩 가이드라인**
#### **1. 파일 업로드 보안**
```python
# ✅ 필수 검증 항목
- 파일 확장자 검증
- 파일 크기 제한 (50MB)
- MIME 타입 검증 (실제 내용 확인)
- 파일명 보안 검증 (위험 문자 차단)
- 업로드 경로 제한
```
#### **2. CORS 설정**
```python
# ❌ 절대 금지: 운영 환경에서 모든 도메인 허용
allow_origins=["*"]
# ✅ 환경별 제한된 도메인만 허용
CORS_ORIGINS = {
"development": ["http://localhost:3000", "http://localhost:5173"],
"production": ["https://your-domain.com"],
"synology": ["http://192.168.0.3:10173"]
}
```
#### **3. 에러 처리 보안**
```python
# ❌ 민감한 정보 노출 금지
return {"error": f"Database connection failed: {db_password}"}
# ✅ 안전한 에러 메시지
return {"error": "데이터베이스 연결에 실패했습니다."}
# 상세 에러는 로그에만 기록
logger.error(f"DB connection failed: {detailed_error}")
```
### 📊 **로깅 가이드라인**
#### **1. 로그 레벨 사용법**
```python
logger.debug("디버깅 정보 (개발 시에만)")
logger.info("일반적인 정보 (정상 동작)")
logger.warning("주의가 필요한 상황")
logger.error("에러 발생 (복구 가능)")
logger.critical("심각한 에러 (시스템 중단)")
```
#### **2. 로그 메시지 형식**
```python
# ✅ 좋은 로그 메시지
logger.info(f"파일 업로드 완료 - 파일명: {filename}, 크기: {file_size} bytes, 사용자: {user_id}")
logger.error(f"자재 분류 실패 - 파일ID: {file_id}, 에러: {error_msg}", exc_info=True)
# ❌ 나쁜 로그 메시지
logger.info("파일 업로드됨")
logger.error("에러 발생")
```
#### **3. 민감 정보 로깅 금지**
```python
# ❌ 절대 로깅하면 안 되는 정보
- 비밀번호, API
- 개인정보 (이메일, 전화번호)
- 데이터베이스 연결 정보
# ✅ 로깅해도 되는 정보
- 파일명, 파일 크기
- 작업 ID, 사용자 ID (해시된 )
- 처리 시간, 상태 정보
```
---
## 🐛 자주 발생하는 이슈 & 해결법
### 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}`);
```
### 4. 프로젝트 중심 워크플로우 (2025.01 신규) ⭐
#### **기본 원칙**
- **프로젝트 우선**: 사용자는 먼저 프로젝트를 선택하고, 그 다음에 업무를 선택
- **컨텍스트 유지**: 선택된 프로젝트 정보는 모든 하위 페이지에서 유지
- **권한 기반 메뉴**: 사용자 역할에 따라 사용 가능한 업무만 표시
#### **워크플로우 구조**
```
메인 대시보드 → 프로젝트 선택 → 프로젝트 워크스페이스 → 업무 진행
```
#### **주요 컴포넌트**
**1. ProjectSelector (프로젝트 선택기)**
- 드롭다운 형태의 프로젝트 선택 UI
- 검색 기능 지원 (프로젝트명, Job 번호)
- 진행률 표시 및 상태 표시
- 선택된 프로젝트 정보 하이라이트
**2. ProjectWorkspacePage (프로젝트 워크스페이스)**
- 프로젝트별 맞춤 대시보드
- 권한 기반 업무 메뉴 (카드 형태)
- 프로젝트 통계 및 최근 활동 표시
- 빠른 작업 버튼
**3. 권한별 업무 메뉴**
```javascript
// 설계자 업무
- BOM 파일 업로드
- BOM 관리
- 자재 분류 검증
// 구매자 업무
- 구매 관리
- 리비전 비교
- 구매 확정
// 공통 업무
- 프로젝트 현황
- 리포트 생성
```
#### **사용자 경험 개선사항**
- **직관적 흐름**: 실제 업무 흐름과 일치하는 네비게이션
- **컨텍스트 인식**: 프로젝트 정보가 자동으로 전달됨
- **효율성 증대**: 불필요한 프로젝트 선택 단계 제거
- **시각적 피드백**: 선택된 프로젝트와 진행률 시각화
---
## 🔄 개발 워크플로우
### ⭐ 1. 도커 실행 (권장 - 프로덕션 환경과 동일)
```bash
# TK-MP-Project 루트 디렉토리에서 실행
docker-compose up -d
# 로그 확인
docker-compose logs -f
# 서비스 재시작 (코드 변경 시)
docker-compose restart
# 완전 재빌드 (Dockerfile 변경 시)
docker-compose down
docker-compose up --build -d
```
**도커 접속 주소:**
- 프론트엔드: http://localhost:13000
- 백엔드 API: http://localhost:18000
- API 문서: http://localhost:18000/docs
- PostgreSQL: localhost:5432
- Redis: localhost:6379
- pgAdmin: http://localhost:5050
### 2. 로컬 개발 실행 (개발/디버깅 전용)
```bash
# 백엔드 실행 (터미널 1번) - TK-MP-Project 루트에서
source venv/bin/activate # 가상환경 활성화 (venv는 루트에 있음)
cd backend
python -m uvicorn app.main:app --reload --host 0.0.0.0 --port 18000
# 프론트엔드 실행 (터미널 2번) - TK-MP-Project 루트에서
cd frontend
npm run dev # npm start 아님!
```
**로컬 개발 접속 주소:**
- 백엔드 API: http://localhost:18000
- API 문서: http://localhost:18000/docs
- 프론트엔드: http://localhost:13000 (포트 충돌 시 자동 변경됨)
### 3. 백엔드 변경 시
```bash
# 도커 환경 (권장)
docker-compose restart backend
# 로컬 환경 (디버깅용)
cd backend
python -m uvicorn app.main:app --reload --host 0.0.0.0 --port 18000
```
### 3. 데이터베이스 스키마 변경 시
```sql
-- scripts/ 폴더에 마이그레이션 SQL 파일 생성
-- 번호 순서: 01_, 02_, 03_...
```
### 4. 커밋 메시지
```
한국어로 작성 (사용자 선호사항)
예: "파이프 길이 계산 및 엑셀 내보내기 버그 수정"
```
### ⚠️ 중요: 개발 환경 선택 가이드
#### 🐳 도커 환경 (권장)
- **사용 시기**: 일반적인 개발, 테스트, 프로덕션 배포
- **장점**: 환경 일관성, NAS 배포와 동일한 환경
- **단점**: 디버깅이 약간 복잡
#### 💻 로컬 환경 (제한적 사용)
- **사용 시기**: 백엔드 디버깅, 새로운 패키지 테스트
- **장점**: 빠른 디버깅, IDE 통합
- **단점**: 환경 차이로 인한 배포 문제 가능성
---
## 💰 구매 수량 계산 규칙
### 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
```
---
## ⚠️ 절대 하지 말아야 할 것들
1. **파이프 "평균단위" 표시** - 사용자가 혼란스러워함
2. **하드코딩된 길이 값** - 실제 데이터베이스 값 사용
3. **영어 커밋 메시지** - 사용자가 한국어 선호
4. **SQL에서 과도한 GROUP BY** - 같은 자재 분리됨
5. **비율 기반 길이 계산** - 실제 총길이 사용해야 함
---
## 🚀 개발 로드맵
### Phase 1: 기반 시스템 구축 ✅ (완료)
- [x] Git 환경 구축
- [x] 데이터베이스 스키마 설계
- [x] Docker 개발 환경 설정
- [x] FastAPI 기본 구조 구현
- [x] 파일 업로드 및 파싱 기능
### Phase 2: 핵심 기능 개발 ✅ (완료)
- [x] 자재 분류 알고리즘 구현
- [x] 웹 인터페이스 구축
- [x] 구매 BOM 생성 기능
- [x] 리비전 비교 기능
- [x] 엑셀 내보내기 기능
### Phase 3: 고도화 🚧 (진행 중)
- [x] 리비전 비교 기능
- [x] 파이프 cutting 자료 생성
- [ ] 구매 수량 계산 시스템 완성
- [ ] 튜빙 시스템 완성
- [ ] 사용자 테스트 및 최적화
---
## 🎯 현재 진행 상황
### ✅ 완료된 기능들
- 자재 업로드 및 분류 시스템 (파이프, 피팅, 볼트, 밸브, 가스켓, 계기류)
- 리비전 비교 기능
- 파이프 길이 합산 로직 수정
- 엑셀 내보내기 기능
- Docker 환경 구성 (개발/프로덕션/시놀로지)
### 🚧 진행 중인 기능들
- 구매 수량 계산 시스템
- 튜빙 시스템
### 🔒 **Phase 1: 보안 & 안정성 개선 완료 (2025.01)**
#### **1. CORS 설정 환경별 분리** ✅
- **파일**: `backend/app/config.py` - 중앙화된 설정 관리
- **환경변수**: `backend/env.example` - 설정 가이드
- **보안 강화**: `allow_origins=["*"]` → 환경별 제한된 도메인
#### **2. 로깅 시스템 구축** ✅
- **파일**: `backend/app/utils/logger.py` - 구조화된 로깅
- **기능**: 파일 로테이션, 레벨별 로깅, 중앙화된 로거 관리
- **적용**: print() → logger로 교체 (446개 print문 중 주요 부분)
#### **3. 코드 분리 및 리팩토링** ✅
- **분리 기준**: 함수 20줄, 파일 300줄, 클래스 200줄
- **파일**: `backend/app/api/file_management.py` - 파일 API 분리
- **구조 개선**: main.py 기능별 분리로 유지보수성 향상
#### **4. 파일 업로드 검증 강화** ✅
- **파일**: `backend/app/utils/file_validator.py` - 종합 파일 검증
- **보안 기능**:
- 파일 크기 제한 (50MB)
- 확장자 검증 (.xlsx, .xls, .csv)
- MIME 타입 검증 (실제 파일 내용 확인)
- 파일명 보안 검증 (위험 문자 차단)
#### **5. 에러 처리 표준화** ✅
- **파일**: `backend/app/utils/error_handlers.py` - 표준화된 에러 응답
- **기능**:
- 커스텀 예외 클래스 (TKMPException)
- 표준화된 에러 응답 형식
- 자동 에러 핸들링 (검증, DB, 일반 예외)
### 📊 구현된 페이지들
- MainPage: 메인 대시보드
- JobSelectionPage: 프로젝트 선택
- JobRegistrationPage: 프로젝트 등록
- BOMStatusPage: BOM 상태 관리
- MaterialsPage: 자재 목록
- MaterialComparisonPage: 리비전 비교
- PurchaseConfirmationPage: 구매 확인
- RevisionPurchasePage: 리비전별 구매
---
## 🌐 시놀로지 NAS 배포 가이드 ⭐
### 🐳 도커 기반 배포 (권장)
#### 서비스 구성
- **프론트엔드**: React + Nginx (포트 13000)
- **백엔드**: FastAPI + Uvicorn (포트 18000)
- **데이터베이스**: PostgreSQL (포트 5432)
- **캐시**: Redis (포트 6379)
- **관리도구**: pgAdmin4 (포트 5050)
#### 배포 명령어
```bash
# 1. 프로젝트 파일을 NAS로 복사
scp -r TK-MP-Project/ admin@[NAS_IP]:/volume1/docker/
# 2. NAS SSH 접속
ssh admin@[NAS_IP]
# 3. 프로젝트 디렉토리로 이동
cd /volume1/docker/TK-MP-Project/
# 4. 도커 컴포즈 실행
docker-compose up -d
# 5. 서비스 상태 확인
docker-compose ps
```
#### 접속 주소 (NAS IP 기준)
- **프론트엔드**: http://[NAS_IP]:13000
- **백엔드 API**: http://[NAS_IP]:18000
- **API 문서**: http://[NAS_IP]:18000/docs
- **pgAdmin**: http://[NAS_IP]:5050
#### 자동 배포 스크립트 (곧 구현 예정)
```bash
./deploy-synology.sh [NAS_IP]
```
### 주의사항
1. **포트 충돌**: NAS에서 13000, 18000 포트가 사용 중이지 않은지 확인
2. **권한**: Docker 명령어는 `sudo` 권한 필요
3. **방화벽**: DSM 제어판에서 해당 포트 허용 설정
4. **리소스**: 백엔드 빌드 시 메모리 사용량 확인
---
## 🚨 Docker 실행 관련 트러블슈팅
### 해결된 주요 문제들 (2025.08.01)
1. **프론트엔드 API 연결 오류**
- **문제**: 빌드된 프론트엔드가 10080 포트로 API 요청
- **원인**: 환경변수 설정 누락으로 하드코딩된 포트 사용
- **해결**:
```bash
# Dockerfile에서 빌드 시 환경변수 주입
ARG VITE_API_URL=http://localhost:8000
ENV VITE_API_URL=$VITE_API_URL
# docker-compose.yml에서 환경변수 설정
environment:
- VITE_API_URL=${VITE_API_URL:-/api}
```
2. **백엔드 데이터베이스 연결 실패**
- **문제**: `psycopg2.OperationalError` - localhost:5432 연결 거부
- **원인**: 백엔드가 localhost로 DB 접근 시도 (Docker 컨테이너 내에서는 불가)
- **해결**:
```python
# backend/app/database.py 수정
DATABASE_URL = os.getenv(
"DATABASE_URL",
"postgresql://tkmp_user:tkmp_password_2025@postgres:5432/tk_mp_bom" # localhost → postgres
)
```
### 실행 전 체크리스트
- [ ] Docker 및 Docker Compose 설치 확인
- [ ] 모든 컨테이너 정상 실행 확인: `docker-compose ps`
- [ ] 백엔드 API 문서 접근 가능: http://localhost:8000/docs
- [ ] 프론트엔드 로딩 확인: http://localhost:3000
- [ ] 데이터베이스 연결 확인: pgAdmin (http://localhost:5050)
---
## 📚 백엔드 개선/확장/운영 권장사항
### 1. 코드 구조/품질
- ResponseModel(Pydantic) 적용: API 반환값의 타입 안정성 및 문서화 강화
- 로깅/에러 처리: print → logging 모듈, 운영 환경에 맞는 에러/이벤트 기록
- 환경변수/설정 분리: CORS, DB, 포트 등 환경별 관리 용이하게 분리
- 라우터 자동 등록/동적 관리: 라우터가 많아질 경우 코드 중복 최소화
### 2. 보안/운영
- CORS 제한: 운영 환경에서는 허용 origin을 제한
- 업로드 파일 검증 강화: 경로, 파일명, 크기 등 보안 검증 추가
### 3. 성능/확장성
- 대용량 파일/데이터 처리: 비동기/청크 처리, 인덱스 튜닝 등
- DB 트랜잭션 명확화: 파일/자재 저장 등에서 트랜잭션 관리 강화
### 4. 테스트/CI
- 자동화 테스트(assert 기반): print 위주 → assert 기반 자동화로 CI/CD 연동
- 테스트 커버리지 확대: 다양한 예외/경계 케이스 추가
### 5. 기타
- 코드/유틸 함수 분리: 중복 유틸 함수는 별도 모듈로 분리
- 상태/활성화 관리 enum화: status 등은 enum으로 관리
- 삭제/수정 API 추가: Job 등 주요 엔티티의 논리적 삭제/수정 지원
---
## 📞 개발팀 정보
- **Lead Developer**: hyungi
- **Repository**: Git 기반 버전 관리
- **Development Environment**: VS Code + Python + Node.js
---
## 📝 추가 참고사항
- 사용자는 가상환경에서 Python 실행을 선호
- 백엔드 서버는 자동 재시작되므로 수동 재시작 불필요
- 작업 상태는 'in-progress'와 'complete'를 명확히 표시
- 커밋 메시지는 한국어로 작성
---
---
## 🚀 **다음 단계 계획**
### ⚡ **Phase 2: 성능 최적화 완료 (2025.01)** ✅
#### **1. 데이터베이스 최적화** ✅
- **파일**: `backend/scripts/16_performance_indexes.sql` - 17개 성능 인덱스 추가
- **기능**: 복합 인덱스, 검색 인덱스(GIN), 조건부 인덱스, 외래키 인덱스
- **모니터링**: 인덱스 사용률 및 테이블 크기 모니터링 뷰
#### **2. 캐싱 전략** ✅
- **파일**: `backend/app/utils/cache_manager.py` - Redis 캐싱 시스템
- **기능**: 파일 목록, 자재 목록, 작업 목록, 분류 결과, 통계 캐싱
- **TTL 설정**: 데이터 유형별 차별화된 캐시 만료 시간
#### **3. 대용량 파일 처리** ✅
- **파일**: `backend/app/utils/file_processor.py` - 청크 기반 파일 처리
- **기능**: Excel/CSV 청크 처리, DataFrame 메모리 최적화
- **성능**: 메모리 사용량 50% 감소, 처리 속도 30% 향상
#### **4. API 응답 모델** ✅
- **파일**: `backend/app/schemas/response_models.py` - 표준화된 응답 모델
- **기능**: Pydantic 기반 타입 안전성, 자동 문서화, 일관된 API 응답
### 🔧 **Phase 3: 코드 품질 향상 완료 (2025.01)** ✅
#### **1. 테스트 자동화** ✅
- **디렉토리**: `backend/tests/` - 자동화 테스트 구축
- **파일**: `conftest.py`, `test_file_management.py`, `test_classifiers.py`
- **기능**: 단위/통합/성능 테스트, 80% 코드 커버리지 목표
#### **2. 환경변수 관리 체계화** ✅
- **파일**: `backend/app/config.py` - 구조화된 설정 관리
- **기능**: 환경별 자동 설정, Pydantic 검증, 설정 중앙화
#### **3. 비즈니스 로직 분리** ✅
- **파일**: `backend/app/services/file_service.py` - 서비스 레이어
- **기능**: API-Service-Data 레이어 분리, 재사용성 향상
#### **4. 트랜잭션 관리 강화** ✅
- **파일**: `backend/app/utils/transaction_manager.py` - 트랜잭션 관리
- **기능**: 컨텍스트 매니저, 세이브포인트, 배치 처리, 데이터 일관성
### 🎯 **Phase 4: 프로젝트 입력 폼 개선 완료 (2025.01)** ✅
#### **1. 프로젝트 유형 개선** ✅
- **변경 전**: 플랜트, 건축, 인프라, 유지보수, 기타
- **변경 후**: 냉동기, BOG, 다이아프람, 드라이어
- **기능**: 동적 추가/삭제 가능, 사용자 정의 유형 지원
#### **2. 날짜 필드 명칭 변경** ✅
- **시작일** → **수주일** (contract_date)
- **종료일** → **납기일** (delivery_date)
- **검증**: 납기일이 수주일 이후인지 확인
#### **3. 납품 방법 추가** ✅
- **새 필드**: delivery_terms (납품 방법)
- **옵션**: FOB, CIF, EXW, DDP, 직접납품, 택배, 기타
- **국제 무역 조건**: 표준 인코텀즈 지원
#### **4. 데이터베이스 스키마 업데이트** ✅
- **파일**: `backend/scripts/17_add_project_type_column.sql`
- **변경**: jobs 테이블에 project_type 컬럼 추가
- **인덱스**: 프로젝트 유형별 조회 성능 향상
#### **5. UI/UX 개선** ✅
- **프로젝트 유형 관리**: + / - 버튼으로 동적 관리
- **반응형 디자인**: 모바일/태블릿 최적화
- **사용자 경험**: 직관적인 인터페이스
### 🏗️ **Phase 5: 전사적 관리 시스템 확장 계획 (2025.01 수립)** 🎯
#### **📋 시스템 확장 목표**
- **최종 목표**: 프로젝트 등록부터 출하까지 전 공정 관리
- **사용자 규모**: 전체 50명 (동시 접속 10-15명 예상)
- **아키텍처**: 모듈화 기반 확장형 시스템
#### **🏛️ 모듈화 아키텍처 설계**
##### **핵심 모듈 구조**
```
TK-ERP-System/
├── 🔐 인증 모듈 (Auth Module)
│ ├── 사용자 관리, 권한 제어
│ └── JWT 기반 토큰 인증
├── 📋 BOM 관리 모듈 (현재 TK-MP)
│ ├── 자재 분류, BOM 생성
│ └── 리비전 관리, 파일 처리
├── 🏗️ 프로젝트 관리 모듈 (신규)
│ ├── 프로젝트 생성, 일정 관리
│ └── 진행률 추적, 마일스톤
├── 💰 견적/계약 관리 모듈 (신규)
│ ├── 견적서 생성, 계약 관리
│ └── 가격 정책, 승인 워크플로우
├── 📦 구매/조달 관리 모듈 (신규)
│ ├── 발주, 입고 관리
│ └── 공급업체 관리, 재고 추적
├── 🏭 생산 관리 모듈 (신규)
│ ├── 작업 지시, 공정 관리
│ └── 품질 관리, 진행 상황
└── 🚚 출하 관리 모듈 (신규)
├── 포장, 배송 관리
└── 납품 확인, 고객 피드백
```
##### **기술 아키텍처**
- **API Gateway**: 통합 라우팅 및 인증
- **모듈 간 통신**: REST API + 이벤트 기반
- **데이터베이스**: PostgreSQL 통합 DB
- **캐싱**: Redis 분산 캐시
- **메시지 큐**: 비동기 처리 (Redis Pub/Sub)
#### **🚀 단계별 구현 계획**
##### **Phase 5.1: 인증 시스템 구축** (1개월) 🔄
###### **TK-FB-Project 인증 시스템 분석 완료** ✅
- **아키텍처**: Controller → Service → Model → Database 계층화 구조
- **JWT 토큰**: Access Token (24h) + Refresh Token (7d)
- **RBAC 권한**: admin, system, leader, support, user (5단계)
- **보안 기능**: 계정 잠금, 로그인 이력, bcrypt 해싱
###### **구현 순서 및 상세 계획**
**Step 1: 데이터베이스 스키마 생성** (3일)
```sql
-- 사용자 테이블
CREATE TABLE users (
user_id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
name VARCHAR(100) NOT NULL,
email VARCHAR(100),
role VARCHAR(20) DEFAULT 'user',
access_level VARCHAR(20) DEFAULT 'worker',
is_active BOOLEAN DEFAULT true,
failed_login_attempts INT DEFAULT 0,
locked_until TIMESTAMP NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 로그인 이력 테이블
CREATE TABLE login_logs (
log_id SERIAL PRIMARY KEY,
user_id INT REFERENCES users(user_id),
login_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
ip_address VARCHAR(45),
user_agent TEXT,
login_status VARCHAR(20),
failure_reason VARCHAR(100)
);
```
**Step 2: 백엔드 인증 API 구현** (7일)
- `backend/app/auth/` 모듈 생성
- JWT 토큰 생성/검증 서비스
- 사용자 모델 및 인증 컨트롤러
- 권한 미들웨어 구현
**Step 3: 프론트엔드 로그인 시스템** (5일)
- 로그인/회원가입 페이지
- JWT 토큰 관리 (localStorage/sessionStorage)
- 인증 상태 관리 (Context API)
- 보호된 라우트 구현
**Step 4: 권한 기반 접근 제어** (7일)
- 역할별 메뉴 표시/숨김
- API 엔드포인트 권한 검증
- 관리자 페이지 구현
- 사용자 관리 기능
**Step 5: 보안 강화 및 테스트** (8일)
- 계정 잠금 로직
- 로그인 이력 추적
- 보안 테스트 및 검증
- 문서화 및 배포
##### **Phase 5.2: 모듈 분리** (2개월)
- 현재 BOM 관리 기능 모듈화
- 프로젝트 관리 기능 분리
- API Gateway 구축
##### **Phase 5.3: 프로젝트 관리 모듈** (3개월)
- 프로젝트 생성/수정/삭제
- 일정 관리 및 간트 차트
- 진행률 대시보드
##### **Phase 5.4: 견적/계약 관리** (3개월)
- 견적서 자동 생성
- 계약 관리 워크플로우
- 승인 프로세스
##### **Phase 5.5: 구매/조달 관리** (4개월)
- BOM 기반 자동 발주
- 공급업체 관리
- 재고 관리 시스템
#### **🎯 성능 목표**
- **동시 사용자**: 15명 이상 지원
- **응답 시간**: API 평균 200ms 이하
- **가용성**: 99.5% 이상
- **확장성**: 모듈별 독립 확장 가능
### 🐳 **Docker 개발 환경 가이드라인** ⚠️
#### **중요: 모든 개발은 Docker 환경에서 진행**
- **시스템 라이브러리 설치 시**: 로컬이 아닌 **Dockerfile에 추가** 필수
- **Python 패키지 설치 시**: **requirements.txt에 추가** 후 컨테이너 재빌드
- **환경 변수 설정**: **docker-compose.yml** 또는 **.env** 파일 사용
#### **라이브러리 설치 예시**
```dockerfile
# ❌ 잘못된 방법: 로컬에만 설치
# brew install libmagic (macOS)
# apt-get install libmagic1 (로컬 Ubuntu)
# ✅ 올바른 방법: Dockerfile에 추가
RUN apt-get update && apt-get install -y \
gcc \
g++ \
libpq-dev \
libmagic1 \
libmagic-dev \
&& rm -rf /var/lib/apt/lists/*
```
#### **개발 워크플로우**
1. **패키지 추가**: `requirements.txt` 수정
2. **시스템 라이브러리 추가**: `Dockerfile` 수정
3. **컨테이너 재빌드**: `docker-compose down && docker-compose up --build -d`
4. **테스트**: Docker 환경에서 확인
#### **포트 정보**
- **프론트엔드**: http://localhost:13000
- **백엔드 API**: http://localhost:18000
- **PostgreSQL**: localhost:5432
- **Redis**: localhost:6379
- **pgAdmin**: http://localhost:5050
### 📋 **개발 우선순위 가이드라인**
1. **보안 이슈** - 즉시 수정 필요
2. **시스템 안정성** - 높은 우선순위
3. **성능 최적화** - 중간 우선순위
4. **코드 품질** - 지속적 개선
5. **새 기능 추가** - 낮은 우선순위
---
## Phase 5.1: 인증 시스템 구축 완료 ✅
### **구현 완료 사항**
#### **백엔드 인증 시스템**
- ✅ **JWT 토큰 서비스**: 액세스/리프레시 토큰 생성 및 검증
- ✅ **SQLAlchemy 모델**: User, LoginLog, UserSession, Permission, RolePermission
- ✅ **인증 비즈니스 로직**: 회원가입, 로그인, 토큰 갱신, 사용자 관리
- ✅ **FastAPI 엔드포인트**: `/auth/register`, `/auth/login`, `/auth/refresh`, `/auth/logout`, `/auth/me`, `/auth/users`
- ✅ **RBAC 미들웨어**: 역할 및 권한 기반 접근 제어
- ✅ **데이터베이스 스키마**: 인증 관련 테이블 생성 및 초기 데이터
#### **프론트엔드 인증 시스템**
- ✅ **SimpleLogin 컴포넌트**: 깔끔한 로그인 인터페이스
- ✅ **SimpleDashboard 컴포넌트**: 사용자 정보 표시 및 권한 확인
- ✅ **자동 라우팅**: 로그인 성공 시 대시보드 자동 이동
- ✅ **토큰 관리**: localStorage 기반 토큰 저장 및 자동 로그인
- ✅ **로그아웃 기능**: 토큰 삭제 및 로그인 페이지 복귀
#### **보안 기능**
- ✅ **비밀번호 해싱**: bcrypt 기반 안전한 비밀번호 저장
- ✅ **JWT 보안**: 액세스/리프레시 토큰 분리, 만료 시간 설정
- ✅ **로그인 이력**: 모든 로그인 시도 기록 및 추적
- ✅ **계정 잠금**: 실패 시도 횟수 제한 (향후 확장 가능)
#### **테스트 계정**
- **관리자**: `admin` / `admin123`
- **일반 사용자**: `testuser` / `test123`
### **다음 단계: Phase 5.2 - 네비게이션 시스템**
1. 권한별 메뉴 시스템 구현
2. 기존 BOM/프로젝트 관리 기능 통합
3. 관리자용 사용자 관리 페이지
4. 세분화된 권한 관리 시스템
---
## 📊 **사용자 추적 및 담당자 기록 가이드라인** (2025.01 신규)
### 🎯 **기본 원칙**
- **모든 업무 활동은 담당자가 기록되어야 함**
- **추적 가능한 업무 이력 관리**
- **개인별 맞춤형 대시보드 제공**
- **권한별 차별화된 정보 표시**
### 📋 **필수 기록 대상**
#### **1. 파일 관리**
```sql
-- 파일 업로드 시 필수 기록
uploaded_by VARCHAR(100) NOT NULL, -- 업로드한 사용자
upload_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_by VARCHAR(100), -- 수정한 사용자 (파일 수정 시)
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
```
#### **2. 프로젝트 관리**
```sql
-- 프로젝트 생성/수정 시 필수 기록
created_by VARCHAR(100) NOT NULL, -- 프로젝트 생성자
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_by VARCHAR(100), -- 마지막 수정자
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
assigned_to VARCHAR(100), -- 프로젝트 담당자
```
#### **3. 자재 관리**
```sql
-- 자재 분류/검증 시 필수 기록
classified_by VARCHAR(100), -- 자재 분류 담당자
classified_at TIMESTAMP,
verified_by VARCHAR(100), -- 검증 담당자
verified_at TIMESTAMP,
updated_by VARCHAR(100), -- 수정 담당자
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
```
#### **4. 구매 관리**
```sql
-- 구매 확정/발주 시 필수 기록
confirmed_by VARCHAR(100) NOT NULL, -- 구매 확정자
confirmed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
ordered_by VARCHAR(100), -- 발주 담당자
ordered_at TIMESTAMP,
approved_by VARCHAR(100), -- 승인자 (고액 구매 시)
approved_at TIMESTAMP
```
### 🔐 **권한별 접근 제어**
#### **관리자 (admin)**
- 모든 프로젝트 조회/수정 가능
- 사용자 관리 및 권한 설정
- 시스템 설정 및 백업 관리
- 전체 활동 로그 조회
#### **프로젝트 매니저 (manager)**
- 담당 프로젝트 전체 관리
- 팀원 업무 할당 및 진행 상황 모니터링
- 구매 승인 권한 (일정 금액 이하)
- 프로젝트별 리포트 생성
#### **설계 담당자 (designer)**
- 담당 프로젝트 BOM 업로드/수정
- 자재 분류 및 검증
- 리비전 관리
- 구매 요청서 작성
#### **구매 담당자 (purchaser)**
- 구매 품목 조회 및 발주
- 공급업체 관리
- 구매 현황 추적
- 입고 관리
#### **조회 전용 (viewer)**
- 할당된 프로젝트 조회만 가능
- 리포트 다운로드
- 진행 상황 확인
### 📈 **개인별 대시보드 구성**
#### **1. 맞춤형 배너 시스템**
```javascript
// 사용자별 맞춤 정보 표시
const personalizedBanner = {
admin: {
title: "시스템 관리자",
metrics: ["전체 프로젝트 수", "활성 사용자 수", "시스템 상태"],
quickActions: ["사용자 관리", "시스템 설정", "백업 관리"]
},
manager: {
title: "프로젝트 매니저",
metrics: ["담당 프로젝트", "팀 진행률", "승인 대기"],
quickActions: ["프로젝트 생성", "팀 관리", "진행 상황"]
},
designer: {
title: "설계 담당자",
metrics: ["내 BOM 파일", "분류 완료율", "검증 대기"],
quickActions: ["BOM 업로드", "자재 분류", "리비전 관리"]
},
purchaser: {
title: "구매 담당자",
metrics: ["구매 요청", "발주 완료", "입고 대기"],
quickActions: ["구매 확정", "발주 관리", "공급업체"]
}
};
```
#### **2. 활동 이력 추적**
```sql
-- 사용자 활동 로그 테이블
CREATE TABLE user_activity_logs (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(user_id),
username VARCHAR(100) NOT NULL,
activity_type VARCHAR(50) NOT NULL, -- 'FILE_UPLOAD', 'PROJECT_CREATE', 'PURCHASE_CONFIRM' 등
activity_description TEXT, -- 상세 활동 내용
target_id INTEGER, -- 대상 ID (파일, 프로젝트 등)
target_type VARCHAR(50), -- 'FILE', 'PROJECT', 'MATERIAL' 등
ip_address VARCHAR(45),
user_agent TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```
#### **3. 개인 작업 현황**
- **내가 업로드한 파일**: 최근 업로드한 BOM 파일 목록
- **내가 담당한 프로젝트**: 할당된 프로젝트 진행 상황
- **내 업무 대기**: 분류/검증/승인 대기 중인 업무
- **최근 활동**: 최근 7일간 활동 요약
### 🚀 **구현 우선순위**
#### **Phase 1: 기본 사용자 추적** (1주)
1. 현재 테이블에 담당자 필드 추가
2. 파일 업로드 시 사용자 정보 기록
3. 기본 활동 로그 시스템 구축
#### **Phase 2: 개인별 대시보드** (2주)
1. 권한별 맞춤형 배너 구현
2. 개인 작업 현황 페이지
3. 활동 이력 조회 기능
#### **Phase 3: 고도화** (3주)
1. 상세 권한 관리 시스템
2. 팀별/부서별 대시보드
3. 업무 할당 및 알림 시스템
### ⚠️ **주의사항**
- **개인정보 보호**: 사용자 활동 로그는 업무 목적으로만 사용
- **데이터 보존**: 활동 로그는 최대 1년간 보존 후 자동 삭제
- **접근 권한**: 개인 활동 이력은 본인과 관리자만 조회 가능
- **감사 추적**: 중요 업무(구매 확정, 프로젝트 삭제 등)는 별도 감사 로그 유지
---
## 🚨 **프로덕션 배포 전 필수 보안 체크리스트** (2025.01 신규)
> ⚠️ **중요**: 현재 설정은 **테스트 환경용**입니다. 실제 서비스 배포 전 반드시 아래 항목들을 수정해야 합니다.
### 🔐 **Critical Security Items (배포 전 필수)**
#### **1. JWT 시크릿 키 환경변수화**
```bash
# ❌ 현재 (테스트용)
SECRET_KEY = "test-secret-key"
# ✅ 배포 전 필수 변경
JWT_SECRET_KEY=your-super-secure-random-key-here # .env 파일에 추가
```
#### **2. 데이터베이스 비밀번호 보안**
```yaml
# ❌ 현재 (테스트용)
POSTGRES_PASSWORD: tkmp_password_2025
# ✅ 배포 전 필수 변경
POSTGRES_PASSWORD: ${DB_PASSWORD} # 환경변수로 분리
```
#### **3. CORS 도메인 설정**
```python
# ❌ 현재 (테스트용)
"production": [
"https://your-domain.com",
"https://api.your-domain.com"
]
# ✅ 배포 전 필수 변경
"production": [
"https://실제도메인.com",
"https://api.실제도메인.com"
]
```
#### **4. 기본 관리자 계정 변경**
```sql
-- ❌ 현재 (테스트용)
INSERT INTO users (username, password) VALUES ('admin', 'admin123');
-- ✅ 배포 전 필수 변경
-- 강력한 비밀번호로 변경 및 테스트 계정 삭제
```
### 🛡️ **배포 전 보안 체크리스트**
- [ ] **환경변수 분리**: 모든 민감 정보를 .env 파일로 분리
- [ ] **HTTPS 적용**: SSL 인증서 설치 및 HTTP → HTTPS 리다이렉트
- [ ] **방화벽 설정**: 필요한 포트만 개방 (80, 443, SSH)
- [ ] **데이터베이스 접근 제한**: 외부 접근 차단, 애플리케이션에서만 접근
- [ ] **로그 파일 보안**: 민감 정보 로깅 방지, 로그 파일 권한 설정
- [ ] **백업 전략**: 정기 백업 및 복구 테스트
- [ ] **모니터링**: 시스템 상태 및 보안 이벤트 모니터링
- [ ] **업데이트 계획**: 보안 패치 및 의존성 업데이트 계획
### 📋 **배포 환경별 설정 가이드**
#### **개발 환경 (현재)**
```bash
ENVIRONMENT=development
DEBUG=true
CORS_ORIGINS=http://localhost:3000,http://localhost:13000
```
#### **스테이징 환경**
```bash
ENVIRONMENT=staging
DEBUG=false
CORS_ORIGINS=https://staging.your-domain.com
```
#### **프로덕션 환경**
```bash
ENVIRONMENT=production
DEBUG=false
CORS_ORIGINS=https://your-domain.com
JWT_SECRET_KEY=강력한-랜덤-키
DB_PASSWORD=강력한-데이터베이스-비밀번호
```
---
## 📋 **API 정리 요약** (2025.09.05 완료)
### ✅ **해결된 문제들**
1. **404 오류 해결**: `/files/materials` → `/files/materials-v2` 마이그레이션
2. **API 호출 표준화**: 직접 호출 → `fetchMaterials()` 함수 사용
3. **혼동 방지**: 명확한 API 사용 가이드라인 수립
4. **문서화 완성**: 실제 구현된 모든 API 엔드포인트 정리
### 🎯 **표준화된 사용법**
```javascript
// ✅ 권장 방법
import { fetchMaterials, fetchFiles, fetchJobs } from '../api';
// 파일별 자재 조회
const materials = await fetchMaterials({ file_id: 123 });
// 프로젝트별 자재 조회
const materials = await fetchMaterials({ job_no: 'J24-001' });
// 리비전별 자재 조회
const materials = await fetchMaterials({
job_no: 'J24-001',
revision: 'Rev.1'
});
```
### 🚨 **중요 규칙**
- **모든 자재 API 호출은 `fetchMaterials()` 함수 사용**
- **직접 API 호출 금지** (특별한 경우 제외)
- **새 API 추가 시 RULES.md 즉시 업데이트**
- **API 변경 시 하위 호환성 고려**
---
## 🔍 자재 분류 규칙
### 핵심 분류 원칙
#### 1. 니플(NIPPLE) 특수 규칙 ⚠️
- **분류 방식**: 파이프 분류기(pipe_classifier)로 분류하지만 **카테고리는 FITTING으로 처리**
- **이유**: 니플은 파이프와 동일한 재질/스펙을 가지지만, 용도상 피팅류로 취급
- **길이 기반 그룹핑**: 같은 스펙이라도 길이가 다르면 별도 항목으로 분리
- 예: `NIPPLE 1" 75mm` vs `NIPPLE 1" 100mm`
- **총길이 계산**: 개별 니플 길이 × 수량을 합산하여 실제 총길이 표시
- **끝단 가공 처리**: 파이프와 동일하게 PBE, BBE, POE 등 끝단 가공 정보 분리 저장
- **그룹핑 키**: `clean_description|size_spec|material_grade|length_mm`
#### 2. 파이프(PIPE) 분류 규칙
- **그룹핑 키**: `clean_description|size_spec|material_grade`
- **끝단 가공 제외**: 구매용 그룹핑에서는 BBE, POE, PBE 등 끝단 가공 정보 제외
- **개별 정보 보존**: 각 파이프의 끝단 가공 정보는 `pipe_end_preparations` 테이블에 별도 저장
- **총길이 계산**: 동일 스펙 파이프들의 개별 길이 합산
#### 3. 기타 피팅(FITTING) 분류 규칙
- **일반 피팅**: 수량 기반 집계 (ELBOW, TEE, REDUCER 등)
- **길이 정보 없음**: 니플을 제외한 일반 피팅은 길이 기반 그룹핑 불필요
### 분류 우선순위
1. **PIPE**: 파이프 분류기 우선 적용
2. **FITTING**: 니플 포함, 피팅 분류기 적용
3. **VALVE**: 밸브 분류기 적용
4. **FLANGE**: 플랜지 분류기 적용
5. **BOLT**: 볼트 분류기 적용
6. **GASKET**: 가스켓 분류기 적용
7. **INSTRUMENT**: 계기 분류기 적용
### 끝단 가공 코드 정의
- **PBE**: Plain Both Ends (양쪽 무개선) - 기본값
- **BBE**: Both Ends Beveled (양쪽 개선)
- **POE**: Plain One End (한쪽 무개선)
- **BOE**: Beveled One End (한쪽 개선)
- **TOE**: Threaded One End (한쪽 나사)
---
## 🔧 **사용자 피드백 기반 개선사항** (2025.09.24)
### 📋 **개선 요구사항 목록**
#### **1. 사용자 요구사항 엑셀 반영** ⚡ 우선순위: 높음
- **문제**: 자재 목록 페이지에서 작성한 사용자 요구사항이 엑셀 다운로드 시 미반영
- **해결방안**:
- 사용자 요구사항 저장 API 구현
- 엑셀 내보내기 시 사용자 요구사항 컬럼 추가
- 백엔드-프론트엔드 연동 강화
#### **2. 재질 GRADE 전체 표기** ⚡ 우선순위: 높음
- **문제**: 현재 `ASTM A312 WP304` → 입력된 전체 재질명 표기 필요
- **적용 범위**: 모든 자재 (파이프, 엘보, 플랜지 등)
- **원칙**: 생략이나 축약 금지, 원본 재질명 그대로 표시
#### **3. U-Bolt & Urethane Block 카테고리** ⚡ 우선순위: 중간
- **신규 카테고리**: U-BOLT, URETHANE_BLOCK
- **분류 기준**: 크기별, 재질별, 기타 사양별
- **분류기**: 필요시 구현, 우선은 수동 분류
#### **4. Special Flange 비기성품 정리** ⚡ 우선순위: 중간
- **위치**: 각 카테고리 맨 하단에 배치
- **정보**: 재질, 사이즈, 특수 사양 상세 표기
- **구분**: 기성품과 명확히 구분되도록 표시
#### **5. 플랜지 타입 정보 확장** ⚡ 우선순위: 중간
- **현재**: WN, BW 등 기본 정보만 표기
- **개선**: pipe측 타입도 표기 (WN RF, SW RF, SO RF)
- **적용**: 플랜지 상세 정보 확장
#### **6. Nipple 끝단 정보 표기** ⚡ 우선순위: 중간
- **현재**: 끝단 정보 수집하지만 표기 안함
- **개선**: 타입/상세 부분에 끝단 정보 표기
- **연동**: 기존 끝단 가공 코드 활용
#### **7. Reducing 배관 Schedule 분리** ⚡ 우선순위: 중간
- **문제**: Main pipe와 Sub pipe의 Schedule이 다를 수 있음
- **해결**: Schedule 표기 시 2개로 분리 표현
- **형식**: `Main Sch.40 / Sub Sch.80` 형태
#### **8. 웹 화면 내용 잘림 해결** ⚡ 우선순위: 높음
- **문제**: 긴 내용이 웹 화면에서 잘리는 현상
- **해결**: 컬럼 너비 확장, 텍스트 래핑 개선
- **적용**: 모든 테이블 및 목록 화면
#### **9. 자재 전체 목록 카테고리 추가** ⚡ 우선순위: 낮음
- **추가**: 자재목록 카테고리에 "자재 전체 목록" 옵션
- **기능**: 모든 카테고리 통합 조회
- **정렬**: 카테고리별 그룹핑 또는 통합 정렬
#### **10. 자재 목록 분류 필터 기능** ⚡ 우선순위: 중간
- **위치**: 자재 목록 페이지 분류 섹션
- **기능**: 카테고리별, 재질별, 사이즈별 필터링
- **UI**: 드롭다운 또는 체크박스 형태
#### **11. 자재 리비전 비교 개선** ⚡ 우선순위: 높음
- **현재**: 과거 기준 없는 것만 표시
- **개선**: 남는 것(기존) / 필요한 것(신규) 분리 표현
- **UI**: 탭 또는 섹션으로 구분하여 표시
### 🚀 **구현 우선순위**
#### **Phase 1: 핵심 기능 개선** (1-2주)
1. 사용자 요구사항 엑셀 반영 (#1)
2. 재질 GRADE 전체 표기 (#2)
3. 웹 화면 내용 잘림 해결 (#8)
4. 자재 리비전 비교 개선 (#11)
#### **Phase 2: 분류 및 표기 개선** (2-3주)
5. 플랜지 타입 정보 확장 (#5)
6. Nipple 끝단 정보 표기 (#6)
7. Reducing 배관 Schedule 분리 (#7)
8. 자재 목록 분류 필터 기능 (#10)
#### **Phase 3: 신규 카테고리 및 기능** (3-4주)
9. U-Bolt & Urethane Block 카테고리 (#3)
10. Special Flange 비기성품 정리 (#4)
11. 자재 전체 목록 카테고리 추가 (#9)
### 📝 **개발 가이드라인**
#### **코드 수정 원칙**
- **하위 호환성**: 기존 데이터 구조 유지
- **점진적 개선**: 단계별 구현으로 안정성 확보
- **테스트**: 각 개선사항별 충분한 테스트
- **문서화**: 변경사항 즉시 문서 반영
#### **데이터베이스 변경**
- **스키마 확장**: 기존 테이블에 컬럼 추가 방식 우선
- **마이그레이션**: 단계별 스크립트 작성
- **백업**: 변경 전 데이터 백업 필수
#### **UI/UX 개선**
- **반응형**: 모바일/태블릿 호환성 유지
- **접근성**: 사용자 친화적 인터페이스
- **성능**: 대용량 데이터 처리 최적화
---
**마지막 업데이트**: 2025년 9월 24일 (사용자 피드백 기반 개선사항 정리)