- README: bending_items 266건 + bending_models 62건 DB 검증 완료 - README: 하장바 검색 문제 해결 (10건 정상) - README: bending_data JSON 통합, bending_item_mappings DROP - README: LOT 코드 체계, 테이블 관계도, 레거시 대응표 갱신 - step1: 데이터분석 업데이트 - step5: canvas 그리기 추가 - .gitattributes CRLF→LF 정규화
22 KiB
절곡품(Bending Parts) 관리 현황 분석
작성일: 2026-03-16 분류: 갭 분석 / 기능 비교 대상: 경동기업(5130) 가이드레일 시스템 vs SAM 시스템
배경 및 질문
경동기업(5130)에는 절곡품(가이드레일) 관리 리스트가 있다.
(5130.codebridge-x.com/guiderail/list.php)
견적/수주를 하면 해당 제품의 가이드레일을 불러와 이미지들을 보여주는 역할을 하며, 개별 절곡품들을 조합하여 가이드레일을 구성하는 구조이다.
SAM 시스템에서도 견적(dev.sam.kr/sales/quote-management/new)에서 가이드레일이 나오는데,
경동기업과 같이 절곡품 이미지를 보여주고 조합할 수 있어야 한다.
구체적 질문
- SAM의
items테이블에BD-XX-XXX코드 품목들이 있는데, 경동기업 절곡품처럼 이미지 표현과 조합 구성이 가능한 상태인가? - 초기 개발 시 절곡품을 고려하지 않고 개발 후 추후 items에 밀어넣었는데, 경동기업 수준의 관리가 되고 있는가?
- 경동기업 절곡품 시스템과 SAM 시스템 간 갭은 무엇인가?
1. 경동기업(5130) 절곡품 관리 체계
1.1 시스템 구조
bending 테이블 (개별 절곡품)
├─ 품명, 대분류(스크린/철재), 중분류(가이드레일/케이스/하단마감재)
├─ 규격(120*70), 재질(SUS 1.2T), 모델명(KSS01)
├─ 인정/비인정 구분
├─ 치수 JSON (inputList), 연신율 JSON (bendingrateList)
├─ 합계 JSON (sumList), 색상 마킹 (colorList)
└─ 검색 키워드 (130x75한빛, 주일-130x70 등)
guiderail 테이블 (조합 전개도)
├─ 모델별 부품 조합 정의 (proditem1~8)
├─ 전개도 이미지 저장
└─ 견적에서 호출되어 이미지 표시
1.2 주요 기능
| 기능 | 구현 파일 | 설명 |
|---|---|---|
| 절곡품 마스터 리스트 | guiderail/list.php |
22개 모델 정의, CRUD 관리 |
| 절곡품 이미지 관리 | put_guiderail_image.php |
이미지 업로드 + Canvas 드로잉 (drawingTool.js) |
| 모델별 부품 조합 | fun_guiderail.php |
KSS01 등 모델마다 1~8개 부품 조합 (getProductData()) |
| 절곡품 검색 | search_bending.php |
대분류/규격/재질/인정여부 복합 필터 |
| 견적에서 호출 | fetch_guiderail_detail.php |
견적 시 해당 모델의 이미지 + 부품 표시 |
| 메타데이터 | guiderail.json |
22개 모델 정의 (이미지 경로, 분류, 마감 유형) |
1.3 모델별 부품 조합 예시 (KSS01 벽면형)
proditem1: ①②마감재 (SUS 1.2T, 수량2)
proditem2: ③본체 (EGI 1.55T, 수량1)
proditem3: ④벽면형-C (EGI 1.55T, 수량1)
proditem4: ⑤벽면형-D (EGI 1.55T, 수량1)
1.4 이미지 관리
- 저장 경로:
/5130/guiderail/images/,/5130/bending/img/ - 파일명 규칙:
YYYY_MM_DD_HH_MM_SS_[모델명].png - 드로잉 도구: Canvas 기반
drawingTool.js로 실시간 전개도 생성
1.5 bending 테이블 주요 컬럼
| 컬럼 | 설명 | 예시 |
|---|---|---|
itemName |
품명 | 가이드레일 |
item_sep |
대분류 | 스크린, 철재 |
item_bending |
중분류 | 가이드레일, 케이스, 하단마감재 |
item_spec |
규격 | 12070, 120120 |
material |
재질 | SUS 1.2T, EGI 1.55T |
model_UA |
인정여부 | 인정, 비인정 |
model_name |
모델명 | KSS01, KWE01, KQTS01 |
search_keyword |
검색어 | 130x75한빛 |
inputList |
치수 JSON | [...] |
bendingrateList |
연신율 JSON | [...] |
sumList |
합계 JSON | [...] |
colorList |
색상 마킹 JSON | [...] |
rail_width |
레일 폭 | 70, 120 |
2. SAM 시스템 현재 상태
2.1 BD-XX-XXX 코드 체계
BendingItemSeeder로 ~40개 품목이 items 테이블에 등록되어 있다.
코드 구조: BD-{PREFIX}-{LENGTH_CODE}
| PREFIX | 용도 | 예시 |
|---|---|---|
| RS/RE | 가이드레일 마감재 (벽면) | BD-RS-30 |
| SS/SE | 가이드레일 마감재 (측면) | BD-SS-35 |
| RM | 가이드레일 본체 (벽면) | BD-RM-42 |
| SM | 가이드레일 본체 (측면) | BD-SM-24 |
| RC/RD | 가이드레일 C형/D형 (벽면) | BD-RC-30 |
| BS/TS | 하단마감재 (SUS/철재) | BD-BS-40 |
| LA | L-Bar | BD-LA-40 |
| HH | 보강평철 | BD-HH-30 |
| CF/CL/CP/CB | 셔터박스 부품 | BD-CF-35 |
| GI | 연기차단재 | BD-GI-54 |
| XX | 하부BASE/상부덮개/마구리 (공용) | BD-XX-35 |
| YY | 별도마감 | BD-YY-30 |
길이코드 매핑:
| 코드 | mm | 코드 | mm |
|---|---|---|---|
| 12 | 1219 | 40 | 4000 |
| 24 | 2438 | 41 | 4150 |
| 30 | 3000 | 42 | 4200 |
| 35 | 3500 | 43 | 4300 |
2.2 items 테이블 저장 구조
{
"item_type": "PT",
"item_category": "BENDING",
"code": "BD-RS-30",
"name": "가이드레일 마감재 3000mm",
"options": {
"source": "bending_item_seeder",
"lot_managed": true,
"consumption_method": "auto",
"production_source": "self_produced",
"input_tracking": true,
"prefix": "RS",
"length_code": "30",
"length_mm": 3000
}
}
2.3 SAM에서 구현된 기능
| 기능 | 파일 | 설명 |
|---|---|---|
| 동적 BOM 생성 | BendingInfoBuilder.php (1172줄) |
제품코드별 자동 부품 조합 |
| Prefix 자동 결정 | PrefixResolver.php (300줄) |
BD-코드 자동 매핑 |
| 작업지시서 절곡 표시 | GuideRailSection 등 (React) |
가이드레일/하단마감재/셔터박스/연기차단재 테이블 |
| 절곡 검사 (Phase 3) | inspection-config API |
공정 자동 판별, BOM 기반 구성품 로딩 |
| 정적 이미지 | api/public/images/bending/ |
22개 이미지 (6개 모델 × 벽면/측면) |
| 재질 매핑 | BendingInfoBuilder |
제품코드별, 마감재질별 자동 결정 |
2.4 데이터 흐름
Quote (견적)
└─ calculation_inputs: { items[], bomResults[] }
↓ OrderService::store()
OrderNode (개소별)
└─ options: { product_code, bom_result }
↓ OrderService::createWorkOrders()
WorkOrder (작업지시)
└─ work_order_items[].options: {
bending_info: {
productCode, finishMaterial,
guideRail: { wall, side },
bottomBar, shutterBox, smokeBarrier
},
slat_info: { joint_bar, glass_qty }
}
↓ 프론트 렌더링
작업일지
├─ 가이드레일 (이미지 + 테이블)
├─ 하단마감재
├─ 셔터박스
└─ 연기차단재
3. 갭 분석
3.1 핵심 갭 (경동기업에 있고 SAM에 없는 것)
🔴 ① 절곡품 마스터 관리 화면
| 항목 | 경동기업(5130) | SAM |
|---|---|---|
| 관리 화면 | guiderail/list.php — CRUD |
❌ 없음 |
| 필터링 | 대분류/규격/재질/인정여부 복합 필터 | ❌ 없음 |
| 검색 | 키워드 기반 통합 검색 | ❌ 없음 |
BD-XX-XXX 품목이 items 테이블에 등록만 되어 있고, 절곡품 전용 관리 화면이 없다.
🔴 ② 견적 시 가이드레일 이미지 표시
| 항목 | 경동기업(5130) | SAM |
|---|---|---|
| 견적 화면 | 모델 선택 → 전개도 이미지 + 부품 조합 표시 | ❌ 이미지 미표시 |
| 호출 방식 | fetch_guiderail_detail.php |
해당 기능 없음 |
견적 페이지(/sales/quote-management/new)에서 가이드레일 선택은 되지만 이미지가 표시되지 않는다.
🔴 ③ 절곡품 개별 전개도 데이터
| 항목 | 경동기업(5130) | SAM |
|---|---|---|
| 치수 데이터 | inputList JSON |
❌ 없음 |
| 연신율 데이터 | bendingrateList JSON |
❌ 없음 |
| 합계 계산 | sumList JSON |
❌ 없음 |
| 색상 마킹 | colorList JSON |
❌ 없음 |
| 전개도 드로잉 | Canvas 기반 실시간 생성 | ❌ 없음 |
BendingInfoBuilder는 조합 로직만 있고, 개별 절곡품의 전개도 상세 데이터는 저장되지 않는다.
3.2 보조 갭
🟡 ④ 절곡품 속성 풍부도
| 속성 | 경동기업 bending 테이블 |
SAM items.options |
|---|---|---|
| 품명 | ✅ itemName |
✅ name |
| 대분류 | ✅ item_sep (스크린/철재) |
❌ 없음 |
| 중분류 | ✅ item_bending (가이드레일/케이스) |
❌ 없음 |
| 규격 | ✅ item_spec (120*70) |
❌ 없음 |
| 재질 | ✅ material (SUS 1.2T) |
❌ 없음 |
| 모델명 | ✅ model_name (KSS01) |
❌ 없음 |
| 인정여부 | ✅ model_UA |
❌ 없음 |
| 검색키워드 | ✅ search_keyword |
❌ 없음 |
| 레일 폭 | ✅ rail_width |
❌ 없음 |
| prefix | ❌ | ✅ options.prefix |
| 길이코드 | ❌ | ✅ options.length_code |
| 길이(mm) | ❌ | ✅ options.length_mm |
🟡 ⑤ 이미지 업로드/드로잉 기능
| 항목 | 경동기업(5130) | SAM |
|---|---|---|
| 이미지 업로드 | ✅ put_guiderail_image.php |
❌ 없음 |
| Canvas 드로잉 | ✅ drawingTool.js |
❌ 없음 |
| 이미지 저장 | 동적 생성 + 파일 저장 | 정적 파일 22개만 |
3.3 SAM이 우위인 부분
| 영역 | 설명 |
|---|---|
| 동적 BOM | BendingInfoBuilder가 제품코드별 자동 조합 (5130은 하드코딩) |
| Prefix 체계 | PrefixResolver로 BD-코드 자동 결정 (5130은 수동) |
| 작업지시 연동 | work_order_items.options.bending_info로 구조화된 데이터 전달 |
| 검사 동적 구현 | Phase 3에서 API 기반 검사 완료 (5130보다 진보적) |
| 멀티테넌시 | 테넌트별 독립 관리 가능 (5130은 단일) |
4. 종합 비교
경동기업(5130) SAM 시스템
───────────────────────────── ─────────────────────────────
[절곡품 마스터 관리] ─────────────→ ❌ 없음 (items에 등록만)
├─ 이미지/전개도 관리 ├─ 정적 이미지 22개만
├─ 치수/연신율 데이터 ├─ ❌ 없음
├─ 검색/필터 └─ ❌ 없음
└─ CRUD 화면
[가이드레일 조합] ───────────────→ ✅ BendingInfoBuilder (더 체계적)
├─ 모델별 부품 정의 ├─ ✅ 동적 BOM 생성
├─ 재질 자동 매핑 ├─ ✅ PrefixResolver
└─ 견적에서 이미지 표시 └─ ❌ 이미지 미표시
[절곡 검사] ─────────────────────→ ✅ Phase 3 완료 (더 진보적)
├─ 중간검사 ├─ ✅ inspection-config API
└─ 하드코딩 검사 └─ ✅ 동적 검사
5. 결론
SAM은 절곡품의 "계산과 조합"은 잘 되어 있지만, "관리와 시각화"가 빠져 있다.
경동기업처럼 절곡품을 독립적으로 관리하고 견적에서 이미지를 보여주려면, 절곡품 마스터 관리 기능을 새로 구현해야 한다.
필요 작업 (예상)
- 절곡품 마스터 관리 화면 — mng 또는 react에 CRUD + 필터링
- items.options 속성 확장 — 대분류, 중분류, 규격, 재질, 모델명 등
- 견적 화면 이미지 연동 — 모델 선택 시 가이드레일 전개도 이미지 표시
- 전개도 데이터 구조 — 치수/연신율/합계 JSON 저장 방안 설계
- 이미지 업로드 기능 — 절곡품별 전개도 이미지 관리
6. API 구현 완료 현황 (2026-03-16)
6.1 절곡품 마스터 API (/api/v1/bending-items)
| Method | Path | 설명 | 상태 |
|---|---|---|---|
| GET | /api/v1/bending-items |
목록 (필터+페이지네이션) | ✅ 완료 |
| GET | /api/v1/bending-items/filters |
필터 옵션 (드롭다운용) | ✅ 완료 |
| GET | /api/v1/bending-items/{id} |
상세 | ✅ 완료 |
| POST | /api/v1/bending-items |
등록 | ✅ 완료 |
| PUT | /api/v1/bending-items/{id} |
수정 | ✅ 완료 |
| DELETE | /api/v1/bending-items/{id} |
삭제 | ✅ 완료 |
API 파일 목록:
| 파일 | 설명 |
|---|---|
app/Http/Controllers/Api/V1/BendingItemController.php |
컨트롤러 |
app/Services/BendingItemService.php |
서비스 (OPTION_KEYS 정의) |
app/Http/Resources/Api/V1/BendingItemResource.php |
응답 리소스 |
app/Http/Requests/Api/V1/BendingItemIndexRequest.php |
목록 검증 |
app/Http/Requests/Api/V1/BendingItemStoreRequest.php |
등록 검증 |
app/Http/Requests/Api/V1/BendingItemUpdateRequest.php |
수정 검증 |
routes/api/v1/production.php |
라우트 정의 (127~135행) |
6.2 이미지 업로드 API (/api/v1/items/{id}/files)
| Method | Path | 설명 | 상태 |
|---|---|---|---|
| POST | /api/v1/items/{id}/files |
업로드 (field_key=bending_diagram) |
✅ 완료 |
| GET | /api/v1/items/{id}/files |
파일 목록 (?field_key=bending_diagram) |
✅ 완료 |
| DELETE | /api/v1/items/{id}/files/{fileId} |
파일 삭제 | ✅ 완료 |
| GET | /api/v1/files/{id}/view |
인라인 보기 (이미지 표시) | ✅ 완료 |
| GET | /api/v1/files/{id}/download |
다운로드 | ✅ 완료 |
R2 저장 경로: {tenant_id}/items/{year}/{month}/{hex}.{ext}
예시: 287/items/2026/03/1b4eba14ff5a832b.jpg
6.3 API 응답 구조
절곡품 상세 (GET /api/v1/bending-items/{id})
{
"success": true,
"message": "조회 성공",
"data": {
"id": 15862,
"code": "BD-BE-30",
"name": "하단마감재(스크린) EGI 3000mm",
"item_type": "PT",
"item_category": "BENDING",
"unit": "EA",
"is_active": true,
"item_name": "하단마감재",
"item_sep": "스크린",
"item_bending": "하단마감재",
"item_spec": "60*40",
"material": "EGI 1.55T",
"model_name": null,
"model_UA": "인정",
"search_keyword": null,
"rail_width": null,
"registration_date": "2025-07-21",
"author": "개발자",
"memo": "메모",
"exit_direction": null,
"front_bottom_width": null,
"box_width": null,
"box_height": null,
"bendingData": [
{ "no": 1, "input": 15, "rate": null, "sum": 15, "color": false, "aAngle": false },
{ "no": 2, "input": 14, "rate": "-1", "sum": 28, "color": false, "aAngle": false },
{ "no": 3, "input": 40, "rate": "-1", "sum": 67, "color": false, "aAngle": false }
],
"prefix": "BE",
"length_code": "30",
"length_mm": 3000,
"width_sum": 193,
"bend_count": 6,
"created_at": "2026-02-21 19:47:01",
"updated_at": "2026-03-16 21:11:12"
}
}
필터 옵션 (GET /api/v1/bending-items/filters)
{
"success": true,
"data": {
"item_sep": ["스크린", "철재"],
"item_bending": ["가이드레일", "케이스", "하단마감재", "마구리", "L-BAR"],
"material": ["EGI 1.15T", "EGI 1.55T", "SUS 1.2T", "SUS 1.5T"],
"model_UA": ["비인정", "인정"],
"model_name": ["KSS01", "KSS02", "KSE01"]
}
}
6.4 MNG 관리 화면 (완료)
| 화면 | URL | 설명 |
|---|---|---|
| 목록 | /bending/base |
필터 + 페이지네이션 |
| 등록 | /bending/base/create |
폼 + 전개도 테이블 + 이미지 업로드 |
| 상세 | /bending/base/{id} |
읽기 전용 |
| 수정 | /bending/base/{id}/edit |
수정 모드 + 이미지 교체 |
6.5 레거시 분류 조건 분석
item_bending 컬럼으로 타입 구분 (같은 bending 테이블 사용):
item_bending 값 |
전용 필드 | 레거시 디렉토리 |
|---|---|---|
가이드레일 |
rail_width |
/bending/ |
케이스 |
exit_direction, box_width, box_height, front_bottom_width |
/shutterbox/ |
하단마감재 |
없음 (공통 필드만) | /bottombar/ |
마구리 |
없음 | - |
L-BAR |
없음 | - |
보강평철 |
없음 | - |
연기차단재 |
없음 | - |
7. React 연동 시 참고사항
7.1 서버 액션 추가 필요
React에 /api/v1/bending-items 전용 서버 액션이 없음. 추가 필요:
예상 파일: src/components/bending/actions.ts
필요 함수:
- fetchBendingItems(params) → GET /api/v1/bending-items
- fetchBendingFilters() → GET /api/v1/bending-items/filters
- fetchBendingItem(id) → GET /api/v1/bending-items/{id}
- createBendingItem(data) → POST /api/v1/bending-items
- updateBendingItem(id, data) → PUT /api/v1/bending-items/{id}
- deleteBendingItem(id) → DELETE /api/v1/bending-items/{id}
- uploadBendingImage(itemId, file) → POST /api/v1/items/{id}/files
7.2 bendingData 필드 매핑 (API → React)
API 응답의 bendingData와 기존 React BendingDetail 타입 불일치:
| API 필드 | API 타입 | React 기존 타입 (BendingDetail) |
조치 |
|---|---|---|---|
no |
integer | no: number |
✅ 일치 |
input |
numeric | input: number |
✅ 일치 |
rate |
string | null | elongation: number |
⚠️ 이름+타입 다름 |
sum |
numeric | sum: number |
✅ 일치 |
color |
boolean | shaded: boolean |
⚠️ 이름 다름 |
aAngle |
boolean | aAngle?: number |
⚠️ 타입 다름 |
| - | - | id: string |
React에만 존재 (클라이언트 전용) |
| - | - | calculated: number |
React에만 존재 (클라이언트 계산값) |
권장: React 타입을 API에 맞추거나, 변환 레이어 추가
// API → React 변환 예시
function transformBendingData(apiData: ApiBendingData[]): BendingDetail[] {
return apiData.map((d, i) => ({
id: `detail-${i}`,
no: d.no,
input: d.input,
elongation: d.rate ? parseFloat(d.rate) : -1, // rate → elongation
calculated: d.input + (d.rate ? parseFloat(d.rate) : 0),
sum: d.sum,
shaded: d.color, // color → shaded
aAngle: d.aAngle ? 1 : 0, // boolean → number
}));
}
7.3 인증 방식
API는 현재 Bearer 토큰 없이 X-TENANT-ID 헤더로 동작 (화이트리스트):
api/v1/bending-items,api/v1/bending-items/*api/v1/items/*/filesapi/v1/files/*/view,api/v1/files/*/download
React는 HttpOnly Cookie + Next.js 프록시로 인증하므로, Bearer 토큰이 자동 전달됨. React 연동 시 화이트리스트 의존 없이 정상 인증 경로로 동작할 것.
7.4 이미지 표시 경로
React에서 이미지 표시:
프록시 경로: /api/proxy/files/{fileId}/view
→ Next.js API Route가 Bearer 토큰 붙여서
→ API: GET /api/v1/files/{fileId}/view
→ R2에서 stream
7.5 Update 시 code unique 검증
BendingItemUpdateRequest에 자기 자신 제외 unique 체크 누락:
// 현재 (미흡)
'code' => 'sometimes|string|max:100',
// 수정 필요
'code' => 'sometimes|string|max:100|unique:items,code,' . $this->route('id'),
7.6 React API 호환성 검증 결과 (2026-03-17)
호환 항목 (API 수정 불필요)
| 항목 | 상태 | 비고 |
|---|---|---|
응답 래핑 {success, message, data} |
✅ 호환 | ApiResponse 헬퍼 공용 |
| 페이지네이션 구조 | ✅ 호환 | toPaginationMeta() 재사용 가능 |
| 에러 응답 (422/404/500) | ✅ 호환 | 동일 에러 핸들링 구조 |
| Null 처리 | ✅ 호환 | 선택적 필드 패턴 일치 |
| 날짜 형식 | ✅ 호환 | Y-m-d 동일 |
| snake_case → camelCase | ✅ 호환 | 기존 transformItemFromApi() 재사용 |
React 측 작업 필요 항목
1. bendingData 필드 매핑 (Server Action 레벨)
API 응답 (bendingData) |
React 타입 (BendingDetail) |
조치 |
|---|---|---|
rate (string|null) |
elongation (number) |
이름+타입 변환 |
color (boolean) |
shaded (boolean) |
이름 변환 |
aAngle (boolean) |
aAngle (number) |
타입 변환 |
input, sum, no |
동일 | ✅ 일치 |
변환 예시:
function transformBendingData(apiData: ApiBendingData[]): BendingDetail[] {
return apiData.map((d, i) => ({
id: `detail-${i}`,
no: d.no,
input: d.input,
elongation: d.rate ? parseFloat(d.rate) : -1,
calculated: d.input + (d.rate ? parseFloat(d.rate) : 0),
sum: d.sum,
shaded: d.color,
aAngle: d.aAngle ? 1 : 0,
}));
}
2. GuiderailModel 타입 + API 클라이언트 신규 작성
- React에
GuiderailModel관련 타입 없음 components[],material_summary필드 구조 정의 필요- Server Action:
fetchGuiderailModels(),fetchGuiderailModel(id)등
3. 파일 URL 프록시 처리
- API:
/api/v1/files/{id}/view - React:
/api/proxy/files/{id}/view(Next.js 프록시 경로)
인증 방식 차이 (자동 호환)
| 호출자 | X-API-KEY | Bearer | tenant_id 소스 | 비고 |
|---|---|---|---|---|
| MNG | ✅ | ❌ | X-TENANT-ID 헤더 (ensureContext) |
현재 |
| React | ✅ (프록시) | ✅ (쿠키) | Bearer → User → userTenants | 향후 |
React는 Next.js 프록시가 HttpOnly 쿠키에서 Bearer 토큰을 읽어 자동 첨부하므로,
API의 allowWithoutAuth 화이트리스트에 의존하지 않고 정상 인증 경로로 동작함.
ensureContext()는 Bearer 없을 때만 동작하는 fallback이라 충돌 없음.
7.7 MNG 부품 추가 시 리다이렉트 수정 (2026-03-17)
문제: /bending/cases/{id}/edit에서 부품 추가 시 form.submit() → 컨트롤러 update()가 show 페이지로 redirect, edit 모드 종료됨
수정 내용:
form.blade.php:submitAndStayEdit()함수 추가 — hidden input_redirect=edit세팅 후 submitBendingProductController::update():_redirect=edit이면 edit 페이지로 리다이렉트movePart()순서 변경도 동일 패턴 적용 (location.reload()→submitAndStayEdit())
관련 문서
- 통합 마스터 플랜:
docs/dev/dev_plans/integrated-master-plan.md - Phase 2 (절곡 분석/설계):
docs/dev/dev_plans/integrated-phase-2.md - Phase 3 (절곡 검사, 완료):
docs/dev/dev_plans/integrated-phase-3.md - 품목 정책:
docs/rules/item-policy.md
최종 업데이트: 2026-03-17