Files
sam-docs/front/[API-REQUEST-2025-11-28] dynamic-page-rendering-api.md
hskwon 08a8259313 docs: 5130 레거시 분석 문서 및 기존 문서 초기 커밋
- 5130 레거시 시스템 분석 (00_OVERVIEW ~ 08_SAM_COMPARISON)
- MES 프로젝트 문서
- API/프론트엔드 스펙 문서
- 가이드 및 레퍼런스 문서
2025-12-04 18:47:19 +09:00

27 KiB

품목관리 페이지 전체 API 요청서

작업 일자: 2025-11-28

문서 버전

버전 날짜 작성자 내용
1.0 2025-11-28 Claude 초안 작성 (동적 렌더링만)
2.0 2025-11-28 Claude 전체 CRUD + 리스트 + 페이징 추가
3.0 2025-11-28 Claude 백엔드 스키마/기존 API 기반 재검토

🔴 백엔드 검토 결과 요약

기존 API와의 정합성 분석

항목 기존 백엔드 요청서 v2.0 조정 필요
품목 수정/삭제 /{code} (코드 기반) /{id} (ID 기반) 코드 기반으로 통일
품목 조회 item_type 파라미터 필수 자동 감지 파라미터 추가
페이징 파라미터 size per_page size로 변경
item-master init 이미 구현됨 별도 요청 기존 활용
BOM API /items/{code}/bom /items/{id}/bom 코드 기반으로 통일
파일 API /items/{code}/files /files/upload 기존 구조 활용
테넌트 격리 tenant_id 자동 미언급 서버 자동 처리

주요 백엔드 아키텍처 특성 (반영 필요)

multi_tenancy:
  - 모든 테이블에 tenant_id 필수
  - BelongsToTenant 글로벌 스코프 적용
  - API 레벨에서 자동 격리 (클라이언트 처리 불필요)

soft_delete:
  - deleted_at, deleted_by 컬럼 사용
  - 삭제 시 실제 삭제가 아닌 soft delete

audit_columns:
  - created_by, updated_by, deleted_by
  - 사용자 추적 자동 처리

api_response_format:
  success: true/false
  data: {} | []
  message: string (i18n key)

작업 체크리스트

Phase 1: 분석 단계

  • 품목기준관리 API 저장/수정/삭제 검토
  • 현재 품목관리 페이지 구조 분석
  • 품목기준관리 저장 데이터 구조 확인
  • 품목관리 리스트/상세/등록/수정 페이지 분석

Phase 2: 설계 단계

  • 품목 리스트 API (페이징, 필터, 검색)
  • 품목 CRUD API (생성, 조회, 수정, 삭제)
  • 동적 페이지 렌더링 API
  • BOM 관리 API
  • 파일 업로드 API
  • 통계/대시보드 API

Phase 3: 검토 단계 완료

  • 백엔드 DB 스키마 검토 (database-schema.md)
  • 기존 item-master-spec 검토 (item-master-spec.md)
  • sam-api 기존 API 구조 확인 (api.php, Controllers)
  • API 스펙 정합성 조정

Phase 4: 확정 단계

  • 백엔드 팀 최종 리뷰
  • API 스펙 확정
  • 프론트엔드 연동 테스트

1. 개요

1.1 목적

품목관리 페이지(/items/*)에서 필요한 모든 API를 정의합니다:

  • 품목 목록 조회 (페이징, 필터, 검색)
  • 품목 CRUD (생성, 조회, 수정, 삭제)
  • 동적 폼 렌더링 (품목기준관리 연동)
  • BOM 관리
  • 파일 업로드/다운로드
  • 통계 정보

1.2 관련 페이지

경로 페이지 필요 API
/items 품목 목록 리스트, 검색, 필터, 페이징, 통계, 삭제
/items/create 품목 등록 동적 폼 구조, 생성, BOM 검색, 파일 업로드
/items/[id] 품목 상세 단건 조회, BOM 조회
/items/[id]/edit 품목 수정 단건 조회, 수정, BOM 관리, 파일 업로드

2. 품목 목록 API (List)

API 2.1: 품목 목록 조회 (페이징)

⚠️ 기존 API 존재: ItemsController@index - 파라미터명 조정 필요

GET /api/v1/items

Query Parameters (기존 백엔드 기준):

파라미터 타입 필수 기본값 설명
page number N 1 페이지 번호
size number N 20 페이지당 항목 수 (기존: size, 변경 금지)
type string N - 품목유형 필터 (FG, PT, SM, RM, CS)
search string N - 검색어 (품목코드, 품목명)
q string N - 검색어 (search와 동일, 호환용)
category_id number N - 카테고리 ID 필터
is_active boolean N - 활성 상태 필터 (신규 요청)
sort_by string N created_at 정렬 기준 (신규 요청)
sort_order string N desc 정렬 순서 (신규 요청)

Request Example:

GET /api/v1/items?page=1&size=20&type=FG&search=스크린

Response:

{
  "success": true,
  "data": {
    "items": [
      {
        "id": 1,
        "item_code": "KD-FG-001",
        "item_name": "스크린 제품 A",
        "item_type": "FG",
        "unit": "EA",
        "specification": "2000x2000",
        "is_active": true,
        "category1": "본체부품",
        "category2": "가이드시스템",
        "sales_price": 150000,
        "purchase_price": 100000,
        "product_category": "SCREEN",
        "current_revision": 0,
        "is_final": false,
        "created_at": "2025-01-10T00:00:00Z",
        "updated_at": "2025-01-10T00:00:00Z"
      }
    ],
    "pagination": {
      "current_page": 1,
      "per_page": 20,
      "total_items": 150,
      "total_pages": 8,
      "has_next": true,
      "has_prev": false
    }
  }
}

API 2.2: 품목 통계 조회

🆕 신규 API 요청

GET /api/v1/items/stats

Response:

{
  "success": true,
  "data": {
    "total_count": 500,
    "by_item_type": {
      "FG": 50,
      "PT": 200,
      "SM": 100,
      "RM": 100,
      "CS": 50
    },
    "active_count": 450,
    "inactive_count": 50
  },
  "message": "message.fetched"
}

API 2.3: 품목 검색 (BOM용 자동완성)

GET /api/v1/items/search

Query Parameters:

파라미터 타입 필수 설명
q string Y 검색어 (최소 2자)
item_type string N 품목유형 필터 (복수 가능: PT,SM)
limit number N 결과 개수 제한 (기본 10, 최대 50)

Request Example:

GET /api/v1/items/search?q=가이드&item_type=PT&limit=10

Response:

{
  "success": true,
  "data": [
    {
      "id": 2,
      "item_code": "KD-PT-001",
      "item_name": "가이드레일(벽면형)",
      "item_type": "PT",
      "unit": "EA",
      "specification": "2438mm",
      "sales_price": 50000
    }
  ]
}

3. 품목 CRUD API

API 3.1: 품목 단건 조회 (ID 기반)

⚠️ 기존 API 존재: ItemsController@show - item_type 파라미터 필수

GET /api/v1/items/{id}

Path Parameters:

파라미터 타입 필수 설명
id number Y 품목 ID

Query Parameters (기존 백엔드 기준):

파라미터 타입 필수 기본값 설명
item_type string Y PRODUCT 품목 유형 (PRODUCT, MATERIAL)
include_price boolean N false 가격 정보 포함 여부
client_id number N - 고객별 가격 조회 시
price_date string N - 가격 기준일 (YYYY-MM-DD)

API 3.1.1: 품목 단건 조회 (Code 기반)

기존 API 존재: ItemsController@showByCode

GET /api/v1/items/code/{code}

Path Parameters:

파라미터 타입 필수 설명
code string Y 품목 코드 (예: KD-FG-001)

Query Parameters:

파라미터 타입 필수 설명
include_bom boolean N BOM 정보 포함 여부

Response:

{
  "success": true,
  "data": {
    "id": 1,
    "item_code": "KD-FG-001",
    "item_name": "스크린 제품 A",
    "item_type": "FG",
    "unit": "EA",
    "specification": "2000x2000",
    "is_active": true,
    "product_category": "SCREEN",
    "lot_abbreviation": "KD",

    "category1": "본체부품",
    "category2": "가이드시스템",
    "category3": null,

    "purchase_price": 100000,
    "sales_price": 150000,
    "margin_rate": 50,
    "processing_cost": 10000,
    "labor_cost": 5000,
    "install_cost": 3000,

    "certification_number": "인정번호-001",
    "certification_start_date": "2025-01-01",
    "certification_end_date": "2028-01-01",
    "specification_file": "/files/spec-001.pdf",
    "specification_file_name": "시방서.pdf",
    "certification_file": "/files/cert-001.pdf",
    "certification_file_name": "인정서.pdf",
    "note": "비고 내용",

    "current_revision": 0,
    "is_final": false,
    "finalized_date": null,
    "finalized_by": null,

    "bom": [
      {
        "id": 1,
        "child_item_code": "KD-PT-001",
        "child_item_name": "가이드레일(벽면형)",
        "quantity": 2,
        "unit": "EA",
        "unit_price": 50000,
        "quantity_formula": "H / 1000",
        "note": "높이에 따라 수량 변동"
      }
    ],

    "revisions": [],
    "created_at": "2025-01-10T00:00:00Z",
    "updated_at": "2025-01-10T00:00:00Z",
    "created_by": 1,
    "updated_by": 1
  }
}

API 3.2: 품목 생성

POST /api/v1/items

Request Body:

{
  "item_type": "FG",
  "item_name": "스크린 제품 신규",
  "unit": "EA",
  "specification": "2500x2500",
  "is_active": true,
  "product_category": "SCREEN",
  "lot_abbreviation": "KD",

  "category1": "본체부품",
  "category2": "가이드시스템",

  "purchase_price": 120000,
  "sales_price": 180000,

  "certification_number": "인정번호-002",
  "certification_start_date": "2025-01-01",
  "certification_end_date": "2028-01-01",
  "note": "신규 제품",

  "bom": [
    {
      "child_item_id": 2,
      "quantity": 2,
      "unit": "EA",
      "quantity_formula": "H / 1000",
      "note": "높이에 따라 수량 변동"
    }
  ]
}

Response:

{
  "success": true,
  "data": {
    "id": 10,
    "item_code": "KD-FG-010",
    "item_name": "스크린 제품 신규",
    "message": "품목이 성공적으로 생성되었습니다."
  }
}

API 3.3: 품목 수정

⚠️ 기존 API 존재: ItemsController@update - 코드 기반 경로

PUT /api/v1/items/{code}

Path Parameters:

파라미터 타입 필수 설명
code string Y 품목 코드 (예: KD-FG-001)

Request Body: (생성과 동일, 변경할 필드만 전송)

{
  "item_name": "스크린 제품 A (수정)",
  "sales_price": 160000,
  "note": "가격 조정됨",
  "bom": [
    {
      "id": 1,
      "quantity": 3
    },
    {
      "child_item_id": 5,
      "quantity": 10,
      "unit": "EA"
    }
  ]
}

Response:

{
  "success": true,
  "data": {
    "id": 1,
    "item_code": "KD-FG-001",
    "message": "품목이 성공적으로 수정되었습니다."
  }
}

API 3.4: 품목 삭제

⚠️ 기존 API 존재: ItemsController@destroy - 코드 기반 경로

DELETE /api/v1/items/{code}

Path Parameters:

파라미터 타입 필수 설명
code string Y 품목 코드 (예: KD-FG-001)

Response:

{
  "success": true,
  "data": {
    "message": "품목이 성공적으로 삭제되었습니다."
  }
}

Error Response (사용 중인 품목):

{
  "success": false,
  "error": {
    "code": "ITEM_IN_USE",
    "message": "해당 품목은 다른 BOM에서 사용 중이므로 삭제할 수 없습니다.",
    "details": {
      "used_in": [
        {"item_code": "KD-FG-001", "item_name": "스크린 제품 A"}
      ]
    }
  }
}

API 3.5: 품목 일괄 삭제

🆕 신규 API 요청 - 코드 기반 일괄 삭제

DELETE /api/v1/items/batch

Request Body:

{
  "codes": ["KD-FG-001", "KD-PT-002", "KD-SM-003"]
}

Response:

{
  "success": true,
  "data": {
    "deleted_count": 2,
    "failed_count": 1,
    "failed_items": [
      {
        "id": 3,
        "item_code": "KD-PT-003",
        "reason": "BOM에서 사용 중"
      }
    ],
    "message": "2개 품목이 삭제되었습니다. 1개 품목은 삭제할 수 없습니다."
  }
}

4. 동적 폼 렌더링 API

API 4.1: 품목 유형별 폼 구조 조회

GET /api/v1/item-master/form-structure/{item_type}

Path Parameters:

파라미터 타입 필수 설명
item_type string Y 품목 유형 (FG, PT, SM, RM, CS)

Query Parameters:

파라미터 타입 필수 기본값 설명
include_conditions boolean N true 조건부 필드 포함 여부

Response:

{
  "success": true,
  "data": {
    "page": {
      "id": 1,
      "page_name": "제품 등록",
      "item_type": "FG",
      "description": "제품(완제품) 등록 페이지"
    },
    "sections": [
      {
        "id": 101,
        "title": "기본 정보",
        "section_type": "BASIC",
        "order_no": 1,
        "is_collapsible": false,
        "is_default_open": true,
        "fields": [
          {
            "id": 1001,
            "field_name": "품목명",
            "field_key": "item_name",
            "field_type": "textbox",
            "order_no": 1,
            "is_required": true,
            "placeholder": "품목명을 입력하세요",
            "validation_rules": {
              "maxLength": 100
            },
            "grid_row": 1,
            "grid_col": 1,
            "grid_span": 2
          },
          {
            "id": 1002,
            "field_name": "품목 상태",
            "field_key": "status",
            "field_type": "dropdown",
            "order_no": 2,
            "is_required": true,
            "default_value": "DEV",
            "options": [
              {"label": "개발", "value": "DEV"},
              {"label": "양산", "value": "PROD"},
              {"label": "단종", "value": "EOL"}
            ],
            "grid_row": 2,
            "grid_col": 1,
            "grid_span": 1
          }
        ]
      },
      {
        "id": 102,
        "title": "인정 정보",
        "section_type": "BASIC",
        "order_no": 2,
        "is_collapsible": true,
        "is_default_open": false,
        "fields": [
          {
            "id": 1010,
            "field_name": "인정번호",
            "field_key": "certification_number",
            "field_type": "textbox",
            "order_no": 1,
            "is_required": false
          },
          {
            "id": 1011,
            "field_name": "시방서",
            "field_key": "specification_file",
            "field_type": "file",
            "order_no": 2,
            "is_required": false,
            "component_type": "file-upload",
            "properties": {
              "accept": ".pdf,.doc,.docx",
              "max_size_mb": 10
            }
          }
        ]
      },
      {
        "id": 103,
        "title": "부품 구성 (BOM)",
        "section_type": "BOM",
        "order_no": 3,
        "is_collapsible": true,
        "is_default_open": false,
        "bom_config": {
          "columns": [
            {"key": "child_item_code", "label": "품목코드", "width": 120, "editable": false},
            {"key": "child_item_name", "label": "품목명", "width": 200, "editable": false},
            {"key": "quantity", "label": "수량", "width": 80, "type": "number", "editable": true},
            {"key": "unit", "label": "단위", "width": 60, "editable": false},
            {"key": "quantity_formula", "label": "수량식", "width": 120, "editable": true},
            {"key": "note", "label": "비고", "width": 150, "editable": true}
          ],
          "allow_search": true,
          "search_endpoint": "/api/v1/items/search",
          "searchable_item_types": ["PT", "SM", "RM"]
        }
      }
    ],
    "conditional_sections": [
      {
        "condition": {
          "field_key": "needs_bom",
          "operator": "equals",
          "value": true
        },
        "show_sections": [103]
      }
    ]
  }
}

API 4.2: 부품(PT) 조건부 필드 조회

GET /api/v1/item-master/form-structure/PT/conditional

Query Parameters:

파라미터 타입 필수 설명
part_type string Y 부품유형 (ASSEMBLY, BENDING, PURCHASED)
category1 string N 대분류 값

Request Example:

GET /api/v1/item-master/form-structure/PT/conditional?part_type=BENDING&category1=가이드레일

Response:

{
  "success": true,
  "data": {
    "part_type": "BENDING",
    "category1": "가이드레일",
    "additional_sections": [
      {
        "id": 201,
        "title": "절곡품 정보",
        "section_type": "CUSTOM",
        "order_no": 2,
        "fields": [
          {
            "id": 2001,
            "field_name": "재질",
            "field_key": "material",
            "field_type": "dropdown",
            "is_required": true,
            "options": [
              {"label": "EGI 1.55T", "value": "EGI_155"},
              {"label": "SUS 1.2T", "value": "SUS_12"},
              {"label": "SPCC 1.6T", "value": "SPCC_16"}
            ]
          },
          {
            "id": 2002,
            "field_name": "길이",
            "field_key": "length",
            "field_type": "dropdown",
            "is_required": true,
            "options": [
              {"label": "2438mm", "value": "2438"},
              {"label": "3000mm", "value": "3000"},
              {"label": "4000mm", "value": "4000"}
            ]
          }
        ]
      },
      {
        "id": 202,
        "title": "전개도",
        "section_type": "CUSTOM",
        "order_no": 3,
        "fields": [
          {
            "id": 2010,
            "field_name": "전개도 이미지",
            "field_key": "bending_diagram",
            "field_type": "custom",
            "component_type": "drawing-canvas",
            "is_required": false,
            "properties": {
              "width": 800,
              "height": 400,
              "tools": ["pen", "line", "eraser", "text"]
            }
          },
          {
            "id": 2011,
            "field_name": "전개도 상세",
            "field_key": "bending_details",
            "field_type": "custom",
            "component_type": "bending-detail-table",
            "is_required": false
          }
        ]
      }
    ]
  }
}

5. BOM 관리 API

API 5.1: 품목 BOM 조회

GET /api/v1/items/{id}/bom

Response:

{
  "success": true,
  "data": {
    "item_id": 1,
    "item_code": "KD-FG-001",
    "item_name": "스크린 제품 A",
    "bom_lines": [
      {
        "id": 1,
        "child_item_id": 2,
        "child_item_code": "KD-PT-001",
        "child_item_name": "가이드레일(벽면형)",
        "quantity": 2,
        "unit": "EA",
        "unit_price": 50000,
        "total_price": 100000,
        "quantity_formula": "H / 1000",
        "note": "높이에 따라 수량 변동",
        "order_no": 1
      }
    ],
    "total_cost": 250000
  }
}

API 5.2: BOM 항목 추가

POST /api/v1/items/{id}/bom

Request Body:

{
  "child_item_id": 5,
  "quantity": 10,
  "unit": "EA",
  "quantity_formula": null,
  "note": "추가 부품"
}

API 5.3: BOM 항목 수정

PUT /api/v1/items/{item_id}/bom/{bom_id}

Request Body:

{
  "quantity": 15,
  "note": "수량 증가"
}

API 5.4: BOM 항목 삭제

DELETE /api/v1/items/{item_id}/bom/{bom_id}

6. 파일 관리 API

API 6.1: 파일 업로드

POST /api/v1/files/upload

Content-Type: multipart/form-data

Form Data:

필드 타입 필수 설명
file File Y 업로드할 파일
type string Y 파일 유형 (specification, certification, bending_diagram)
item_id number N 연결할 품목 ID (수정 시)

Response:

{
  "success": true,
  "data": {
    "file_id": "uuid-1234-5678",
    "file_name": "시방서.pdf",
    "file_url": "/files/uuid-1234-5678/시방서.pdf",
    "file_size": 1024000,
    "mime_type": "application/pdf"
  }
}

API 6.2: 파일 다운로드

GET /api/v1/files/{file_id}/download

API 6.3: 파일 삭제

DELETE /api/v1/files/{file_id}

7. 마스터 데이터 조회 API

API 7.1: 단위 목록 조회

GET /api/v1/master/units

Response:

{
  "success": true,
  "data": [
    {"value": "EA", "label": "EA (개)"},
    {"value": "SET", "label": "SET (세트)"},
    {"value": "M", "label": "M (미터)"},
    {"value": "KG", "label": "KG (킬로그램)"},
    {"value": "L", "label": "L (리터)"}
  ]
}

API 7.2: 카테고리 목록 조회

GET /api/v1/master/categories

Query Parameters:

파라미터 타입 필수 설명
item_type string N 품목유형별 필터
parent_id number N 상위 카테고리 ID

API 7.3: 재질 목록 조회

GET /api/v1/master/materials

Response:

{
  "success": true,
  "data": [
    {"value": "EGI_155", "label": "EGI 1.55T", "thickness": "1.55"},
    {"value": "SUS_12", "label": "SUS 1.2T", "thickness": "1.2"},
    {"value": "SPCC_16", "label": "SPCC 1.6T", "thickness": "1.6"}
  ]
}

API 7.4: 규격 목록 조회 (원자재/부자재)

GET /api/v1/master/specifications

Query Parameters:

파라미터 타입 필수 설명
item_type string Y RM 또는 SM
item_name string N 품목명 필터 (예: SPHC-SD)

8. API 요약 테이블

8.1 필수 API (MVP)

우선순위 메서드 엔드포인트 설명 상태
🔴 P0 GET /api/v1/items 품목 목록 조회 (페이징) ⚠️ 기존
🔴 P0 GET /api/v1/items/{id} 품목 단건 조회 (ID) ⚠️ 기존
🔴 P0 GET /api/v1/items/code/{code} 품목 단건 조회 (코드) ⚠️ 기존
🔴 P0 POST /api/v1/items 품목 생성 ⚠️ 기존
🔴 P0 PUT /api/v1/items/{code} 품목 수정 (코드 기반) ⚠️ 기존
🔴 P0 DELETE /api/v1/items/{code} 품목 삭제 (코드 기반) ⚠️ 기존
🔴 P0 GET /api/v1/items/search 품목 검색 (BOM용) 🆕 신규

8.2 중요 API

우선순위 메서드 엔드포인트 설명
🟡 P1 GET /api/v1/item-master/form-structure/{type} 동적 폼 구조 조회
🟡 P1 GET /api/v1/items/stats 품목 통계
🟡 P1 DELETE /api/v1/items/batch 품목 일괄 삭제
🟡 P1 POST /api/v1/files/upload 파일 업로드

8.3 추가 API

우선순위 메서드 엔드포인트 설명
🟢 P2 GET /api/v1/item-master/form-structure/PT/conditional PT 조건부 필드
🟢 P2 GET /api/v1/items/{id}/bom BOM 조회
🟢 P2 POST /api/v1/items/{id}/bom BOM 항목 추가
🟢 P2 PUT /api/v1/items/{id}/bom/{bom_id} BOM 항목 수정
🟢 P2 DELETE /api/v1/items/{id}/bom/{bom_id} BOM 항목 삭제
🟢 P2 GET /api/v1/master/units 단위 목록
🟢 P2 GET /api/v1/master/categories 카테고리 목록
🟢 P2 GET /api/v1/master/materials 재질 목록
🟢 P2 GET /api/v1/master/specifications 규격 목록
🟢 P2 GET /api/v1/files/{id}/download 파일 다운로드
🟢 P2 DELETE /api/v1/files/{id} 파일 삭제

9. 에러 응답 형식

공통 에러 응답

{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "사용자 친화적 에러 메시지",
    "details": {}
  }
}

에러 코드 목록

코드 HTTP Status 설명
VALIDATION_ERROR 400 입력값 검증 실패
ITEM_NOT_FOUND 404 품목을 찾을 수 없음
ITEM_IN_USE 409 품목이 다른 곳에서 사용 중
DUPLICATE_ITEM_CODE 409 중복된 품목코드
FILE_TOO_LARGE 413 파일 크기 초과
UNAUTHORIZED 401 인증 필요
FORBIDDEN 403 권한 없음
INTERNAL_ERROR 500 서버 내부 오류

10. 데이터 모델 참조

10.1 품목(Item) 테이블 필드

CREATE TABLE items (
  id SERIAL PRIMARY KEY,
  tenant_id INTEGER NOT NULL,
  item_code VARCHAR(50) UNIQUE NOT NULL,
  item_name VARCHAR(200) NOT NULL,
  item_type VARCHAR(10) NOT NULL, -- FG, PT, SM, RM, CS
  unit VARCHAR(20) NOT NULL,
  specification VARCHAR(200),
  is_active BOOLEAN DEFAULT true,

  -- 제품(FG) 전용
  product_category VARCHAR(20), -- SCREEN, STEEL
  lot_abbreviation VARCHAR(10),
  certification_number VARCHAR(100),
  certification_start_date DATE,
  certification_end_date DATE,
  specification_file VARCHAR(500),
  specification_file_name VARCHAR(200),
  certification_file VARCHAR(500),
  certification_file_name VARCHAR(200),

  -- 부품(PT) 전용
  part_type VARCHAR(20), -- ASSEMBLY, BENDING, PURCHASED
  part_usage VARCHAR(50),
  installation_type VARCHAR(50),
  assembly_type VARCHAR(10),
  assembly_length VARCHAR(20),
  side_spec_width VARCHAR(20),
  side_spec_height VARCHAR(20),
  material VARCHAR(50),
  length VARCHAR(20),
  bending_diagram TEXT, -- Base64 이미지
  bending_details JSONB, -- 전개도 상세 데이터

  -- 분류
  category1 VARCHAR(100),
  category2 VARCHAR(100),
  category3 VARCHAR(100),

  -- 가격
  purchase_price DECIMAL(15,2),
  sales_price DECIMAL(15,2),
  margin_rate DECIMAL(5,2),
  processing_cost DECIMAL(15,2),
  labor_cost DECIMAL(15,2),
  install_cost DECIMAL(15,2),

  -- 재고
  safety_stock INTEGER,
  lead_time INTEGER,

  -- 버전 관리
  current_revision INTEGER DEFAULT 0,
  is_final BOOLEAN DEFAULT false,
  finalized_date TIMESTAMP,
  finalized_by INTEGER,

  note TEXT,
  created_by INTEGER,
  updated_by INTEGER,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

10.2 BOM 테이블

CREATE TABLE item_bom (
  id SERIAL PRIMARY KEY,
  tenant_id INTEGER NOT NULL,
  parent_item_id INTEGER REFERENCES items(id),
  child_item_id INTEGER REFERENCES items(id),
  quantity DECIMAL(10,3) NOT NULL,
  unit VARCHAR(20),
  unit_price DECIMAL(15,2),
  quantity_formula VARCHAR(100), -- 예: "H / 1000"
  note TEXT,
  order_no INTEGER DEFAULT 0,
  created_at TIMESTAMP DEFAULT NOW(),
  updated_at TIMESTAMP DEFAULT NOW()
);

11. 참고 문서

  • src/components/items/ItemListClient.tsx - 품목 목록 UI
  • src/components/items/ItemForm/index.tsx - 품목 등록/수정 폼
  • src/contexts/ItemMasterContext.tsx - 품목기준관리 데이터 구조
  • [API-2025-11-25] item-master-data-management-api-request.md - 품목기준관리 API

변경 이력

날짜 버전 변경 내용
2025-11-28 1.0 초안 작성 (동적 렌더링만)
2025-11-28 2.0 전체 CRUD + 리스트 + 페이징 + BOM + 파일 + 마스터 데이터 추가
2025-11-28 3.0 백엔드 스키마/기존 API 기반 재검토: /{id}/{code} 경로 변경, per_pagesize 파라미터 변경, 기존 API 주석 추가, 일괄삭제 코드 기반 변경