Files
sam-api/docs/parameter-based-bom-api.md
kent bf8036a64b feat: DB 연결 오버라이딩 및 대시보드 통계 위젯 추가
- DB 연결: 로컬/Docker 환경 오버라이딩 설정 (.env)
- 테넌트 위젯: redirect 버그 수정 (TenantSelectorWidget)
- 통계 위젯: 사용자/제품/자재/주문 카드 추가 (StatsOverviewWidget)
- 리소스 한국어화: Product, Material 모델 레이블 추가
- 대시보드: 위젯 등록 및 캐시 최적화

🤖 Generated with [Claude Code](https://claude.ai/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-30 23:31:14 +09:00

15 KiB

매개변수 기반 BOM 시스템 API 문서

개요

SAM 프로젝트의 매개변수 기반 BOM 시스템은 입력 매개변수를 통해 동적으로 제품 사양과 BOM을 계산하여 자동으로 제품을 생성하는 시스템입니다.

시스템 구조

Model (KSS01)
├── Parameters (W0, H0, installation_type, ...)
├── Formulas (W1 = W0 + margin, area = W1 * H1, ...)
└── BOM Template
    └── Condition Rules (브라켓, 모터, 가이드, ...)

KSS01 모델 시나리오

모델 정의

  • 모델명: KSS01 (전동 스크린 시스템)
  • 제품군: 전동 스크린
  • 특징: 크기와 설치 타입에 따른 다양한 구성

입력 매개변수

매개변수 타입 설명 단위 범위 기본값
W0 DECIMAL 원본 가로 크기 mm 500-2000 1000
H0 DECIMAL 원본 세로 크기 mm 400-1500 800
installation_type STRING 설치 타입 - A, B, C A
power_source STRING 전원 타입 - 220V, 110V 220V
color STRING 색상 - WHITE, BLACK, GRAY WHITE

계산 공식

출력 매개변수 공식 설명
W1 W0 + (installation_type == "A" ? 50 : 30) 최종 가로 크기
H1 H0 + (installation_type == "A" ? 50 : 30) 최종 세로 크기
area W1 * H1 전체 면적
weight area * 0.000025 + 5 예상 무게 (kg)
motor_power weight > 20 ? 150 : 120 모터 파워 (W)

BOM 조건 규칙

규칙명 조건 자재/제품 수량 공식 설명
표준 브라켓 installation_type == "A" BR-001 (브라켓) ceiling(W1 / 500) A타입은 표준 브라켓
경량 브라켓 installation_type != "A" BR-002 (경량 브라켓) ceiling(W1 / 600) B/C타입은 경량 브라켓
고출력 모터 motor_power >= 150 MT-002 (고출력 모터) 1 150W 이상시 고출력
표준 모터 motor_power < 150 MT-001 (표준 모터) 1 150W 미만시 표준
가이드 레일 true GD-001 (가이드 레일) ceiling(H1 / 1000) * 2 항상 필요
컨트롤러 power_source == "220V" CT-001 (220V 컨트롤러) 1 220V 전용
컨트롤러 power_source == "110V" CT-002 (110V 컨트롤러) 1 110V 전용

API 사용 예시

1. 모델 매개변수 설정

매개변수 목록 조회

GET /v1/design/models/1/parameters
Authorization: Bearer {token}
X-API-KEY: {api-key}

매개변수 생성

POST /v1/design/models/1/parameters
Authorization: Bearer {token}
X-API-KEY: {api-key}
Content-Type: application/json

{
  "name": "W0",
  "label": "원본 가로 크기",
  "type": "INPUT",
  "data_type": "DECIMAL",
  "unit": "mm",
  "default_value": "1000",
  "min_value": 500,
  "max_value": 2000,
  "description": "제품의 원본 가로 크기를 입력하세요",
  "is_required": true,
  "display_order": 1
}

2. 공식 설정

공식 생성

POST /v1/design/models/1/formulas
Authorization: Bearer {token}
X-API-KEY: {api-key}
Content-Type: application/json

{
  "name": "최종 가로 크기 계산",
  "target_parameter": "W1",
  "expression": "W0 + (installation_type == \"A\" ? 50 : 30)",
  "description": "설치 타입에 따른 최종 가로 크기 계산",
  "is_active": true,
  "execution_order": 1
}

공식 검증

POST /v1/design/models/1/formulas/1/validate
Authorization: Bearer {token}
X-API-KEY: {api-key}
Content-Type: application/json

{
  "test_values": {
    "W0": 1000,
    "installation_type": "A"
  }
}

응답:

{
  "success": true,
  "message": "formula.validated",
  "data": {
    "is_valid": true,
    "result": 1050,
    "error_message": null
  }
}

3. BOM 조건 규칙 설정

조건 규칙 생성

POST /v1/design/bom-templates/1/condition-rules
Authorization: Bearer {token}
X-API-KEY: {api-key}
Content-Type: application/json

{
  "name": "표준 브라켓 선택",
  "ref_type": "MATERIAL",
  "ref_id": 101,
  "condition_expression": "installation_type == \"A\"",
  "quantity_expression": "ceiling(W1 / 500)",
  "waste_rate_expression": "0.05",
  "description": "A타입 설치시 표준 브라켓 적용",
  "priority": 1,
  "is_active": true
}

4. BOM 미리보기 생성

실시간 BOM 해석

POST /v1/products/models/1/resolve-preview
Authorization: Bearer {token}
X-API-KEY: {api-key}
Content-Type: application/json

{
  "input_parameters": {
    "W0": 1000,
    "H0": 800,
    "installation_type": "A",
    "power_source": "220V",
    "color": "WHITE"
  },
  "include_calculated_values": true,
  "include_bom_items": true
}

응답:

{
  "success": true,
  "message": "bom.preview_generated",
  "data": {
    "input_parameters": {
      "W0": 1000,
      "H0": 800,
      "installation_type": "A",
      "power_source": "220V",
      "color": "WHITE"
    },
    "calculated_values": {
      "W1": 1050,
      "H1": 850,
      "area": 892500,
      "weight": 27.31,
      "motor_power": 150
    },
    "bom_items": [
      {
        "ref_type": "MATERIAL",
        "ref_id": 101,
        "ref_code": "BR-001",
        "ref_name": "표준 브라켓",
        "quantity": 3.0,
        "waste_rate": 0.05,
        "total_quantity": 3.15,
        "unit": "EA",
        "unit_cost": 5000.0,
        "total_cost": 15750.0,
        "applied_rule": "표준 브라켓 선택",
        "calculation_details": {
          "condition_matched": true,
          "quantity_expression": "ceiling(W1 / 500)",
          "quantity_calculation": "ceiling(1050 / 500) = 3"
        }
      },
      {
        "ref_type": "MATERIAL",
        "ref_id": 202,
        "ref_code": "MT-002",
        "ref_name": "고출력 모터",
        "quantity": 1.0,
        "waste_rate": 0.0,
        "total_quantity": 1.0,
        "unit": "EA",
        "unit_cost": 45000.0,
        "total_cost": 45000.0,
        "applied_rule": "고출력 모터",
        "calculation_details": {
          "condition_matched": true,
          "quantity_expression": "1",
          "quantity_calculation": "1"
        }
      },
      {
        "ref_type": "MATERIAL",
        "ref_id": 301,
        "ref_code": "GD-001",
        "ref_name": "가이드 레일",
        "quantity": 2.0,
        "waste_rate": 0.03,
        "total_quantity": 2.06,
        "unit": "EA",
        "unit_cost": 12000.0,
        "total_cost": 24720.0,
        "applied_rule": "가이드 레일",
        "calculation_details": {
          "condition_matched": true,
          "quantity_expression": "ceiling(H1 / 1000) * 2",
          "quantity_calculation": "ceiling(850 / 1000) * 2 = 2"
        }
      },
      {
        "ref_type": "MATERIAL",
        "ref_id": 401,
        "ref_code": "CT-001",
        "ref_name": "220V 컨트롤러",
        "quantity": 1.0,
        "waste_rate": 0.0,
        "total_quantity": 1.0,
        "unit": "EA",
        "unit_cost": 25000.0,
        "total_cost": 25000.0,
        "applied_rule": "220V 컨트롤러",
        "calculation_details": {
          "condition_matched": true,
          "quantity_expression": "1",
          "quantity_calculation": "1"
        }
      }
    ],
    "summary": {
      "total_materials": 4,
      "total_cost": 110470.0,
      "estimated_weight": 27.31
    },
    "validation_warnings": []
  }
}

5. 실제 제품 생성

매개변수 기반 제품 생성

POST /v1/products/create-from-model
Authorization: Bearer {token}
X-API-KEY: {api-key}
Content-Type: application/json

{
  "model_id": 1,
  "input_parameters": {
    "W0": 1000,
    "H0": 800,
    "installation_type": "A",
    "power_source": "220V",
    "color": "WHITE"
  },
  "product_code": "KSS01-1000x800-A",
  "product_name": "KSS01 스크린 1000x800 A타입",
  "category_id": 1,
  "description": "매개변수 기반으로 생성된 맞춤형 전동 스크린",
  "unit": "EA",
  "min_order_qty": 1,
  "lead_time_days": 7,
  "is_active": true,
  "create_bom_items": true,
  "validate_bom": true
}

응답:

{
  "success": true,
  "message": "product.created_from_model",
  "data": {
    "product": {
      "id": 123,
      "code": "KSS01-1000x800-A",
      "name": "KSS01 스크린 1000x800 A타입",
      "type": "PRODUCT",
      "category_id": 1,
      "description": "매개변수 기반으로 생성된 맞춤형 전동 스크린",
      "unit": "EA",
      "min_order_qty": 1,
      "lead_time_days": 7,
      "is_active": true,
      "created_at": "2024-01-01T00:00:00Z"
    },
    "input_parameters": {
      "W0": 1000,
      "H0": 800,
      "installation_type": "A",
      "power_source": "220V",
      "color": "WHITE"
    },
    "calculated_values": {
      "W1": 1050,
      "H1": 850,
      "area": 892500,
      "weight": 27.31,
      "motor_power": 150
    },
    "bom_items": [
      {
        "id": 1,
        "ref_type": "MATERIAL",
        "ref_id": 101,
        "ref_code": "BR-001",
        "ref_name": "표준 브라켓",
        "quantity": 3.0,
        "waste_rate": 0.05,
        "unit": "EA"
      },
      {
        "id": 2,
        "ref_type": "MATERIAL",
        "ref_id": 202,
        "ref_code": "MT-002",
        "ref_name": "고출력 모터",
        "quantity": 1.0,
        "waste_rate": 0.0,
        "unit": "EA"
      },
      {
        "id": 3,
        "ref_type": "MATERIAL",
        "ref_id": 301,
        "ref_code": "GD-001",
        "ref_name": "가이드 레일",
        "quantity": 2.0,
        "waste_rate": 0.03,
        "unit": "EA"
      },
      {
        "id": 4,
        "ref_type": "MATERIAL",
        "ref_id": 401,
        "ref_code": "CT-001",
        "ref_name": "220V 컨트롤러",
        "quantity": 1.0,
        "waste_rate": 0.0,
        "unit": "EA"
      }
    ],
    "summary": {
      "total_bom_items": 4,
      "model_id": 1,
      "bom_template_id": 1
    }
  }
}

6. 제품 매개변수 조회

생성된 제품의 매개변수 확인

GET /v1/products/123/parameters
Authorization: Bearer {token}
X-API-KEY: {api-key}

응답:

{
  "success": true,
  "message": "fetched",
  "data": {
    "product_id": 123,
    "model_id": 1,
    "input_parameters": {
      "W0": 1000,
      "H0": 800,
      "installation_type": "A",
      "power_source": "220V",
      "color": "WHITE"
    },
    "parameter_definitions": [
      {
        "id": 1,
        "name": "W0",
        "label": "원본 가로 크기",
        "type": "INPUT",
        "data_type": "DECIMAL",
        "unit": "mm",
        "default_value": "1000",
        "min_value": 500,
        "max_value": 2000,
        "description": "제품의 원본 가로 크기를 입력하세요"
      }
    ]
  }
}

7. 계산된 값 조회

생성된 제품의 계산값 확인

GET /v1/products/123/calculated-values
Authorization: Bearer {token}
X-API-KEY: {api-key}

응답:

{
  "success": true,
  "message": "fetched",
  "data": {
    "product_id": 123,
    "model_id": 1,
    "calculated_values": {
      "W1": 1050,
      "H1": 850,
      "area": 892500,
      "weight": 27.31,
      "motor_power": 150
    },
    "formula_applications": [
      {
        "formula_name": "최종 가로 크기 계산",
        "target_parameter": "W1",
        "expression": "W0 + (installation_type == \"A\" ? 50 : 30)",
        "calculated_value": 1050,
        "execution_order": 1
      },
      {
        "formula_name": "최종 세로 크기 계산",
        "target_parameter": "H1",
        "expression": "H0 + (installation_type == \"A\" ? 50 : 30)",
        "calculated_value": 850,
        "execution_order": 2
      },
      {
        "formula_name": "면적 계산",
        "target_parameter": "area",
        "expression": "W1 * H1",
        "calculated_value": 892500,
        "execution_order": 3
      },
      {
        "formula_name": "무게 계산",
        "target_parameter": "weight",
        "expression": "area * 0.000025 + 5",
        "calculated_value": 27.31,
        "execution_order": 4
      },
      {
        "formula_name": "모터 파워 계산",
        "target_parameter": "motor_power",
        "expression": "weight > 20 ? 150 : 120",
        "calculated_value": 150,
        "execution_order": 5
      }
    ]
  }
}

시나리오별 테스트 케이스

시나리오 1: 소형 B타입 스크린

입력 매개변수:

{
  "W0": 600,
  "H0": 500,
  "installation_type": "B",
  "power_source": "110V",
  "color": "BLACK"
}

예상 결과:

  • W1: 630 (600 + 30)
  • H1: 530 (500 + 30)
  • area: 333900
  • weight: 13.35 kg
  • motor_power: 120W (경량이므로 표준 모터)
  • 브라켓: 경량 브라켓 2개 (ceiling(630/600) = 2)
  • 컨트롤러: 110V 컨트롤러

시나리오 2: 대형 A타입 스크린

입력 매개변수:

{
  "W0": 1800,
  "H0": 1200,
  "installation_type": "A",
  "power_source": "220V",
  "color": "GRAY"
}

예상 결과:

  • W1: 1850 (1800 + 50)
  • H1: 1250 (1200 + 50)
  • area: 2312500
  • weight: 62.81 kg
  • motor_power: 150W (중량이므로 고출력 모터)
  • 브라켓: 표준 브라켓 4개 (ceiling(1850/500) = 4)
  • 가이드 레일: 4개 (ceiling(1250/1000) * 2 = 4)

시나리오 3: 경계값 테스트

입력 매개변수:

{
  "W0": 500,
  "H0": 400,
  "installation_type": "C",
  "power_source": "220V",
  "color": "WHITE"
}

예상 결과:

  • W1: 530 (500 + 30)
  • H1: 430 (400 + 30)
  • area: 227900
  • weight: 10.70 kg
  • motor_power: 120W
  • 브라켓: 경량 브라켓 1개 (ceiling(530/600) = 1)
  • 가이드 레일: 2개 (ceiling(430/1000) * 2 = 2)

에러 처리

매개변수 검증 실패

POST /v1/design/models/1/validate-parameters
Content-Type: application/json

{
  "input_parameters": {
    "W0": 3000,  // 범위 초과
    "H0": 200,   // 범위 미달
    "installation_type": "D"  // 잘못된 값
  }
}

응답:

{
  "success": true,
  "message": "parameters.validated",
  "data": {
    "is_valid": false,
    "validation_errors": [
      {
        "parameter": "W0",
        "error": "Value must be between 500 and 2000"
      },
      {
        "parameter": "H0",
        "error": "Value must be between 400 and 1500"
      },
      {
        "parameter": "installation_type",
        "error": "Value must be one of: A, B, C"
      }
    ],
    "warnings": []
  }
}

공식 계산 오류

{
  "success": false,
  "message": "error.formula.calculation_failed",
  "errors": {
    "code": "FORMULA_ERROR",
    "message": "Division by zero in formula 'area_calculation'",
    "details": {
      "formula_id": 3,
      "expression": "W1 * H1 / 0",
      "input_values": {"W1": 1050, "H1": 850}
    }
  }
}

성능 고려사항

캐싱 전략

  • 모델별 매개변수 정의: Redis 캐시 (TTL: 1시간)
  • 공식 표현식: 메모리 캐시 (세션 기반)
  • BOM 템플릿: Redis 캐시 (TTL: 30분)

최적화

  • 공식 실행 순서 최적화 (의존성 그래프)
  • BOM 규칙 우선순위 기반 조기 종료
  • 대량 생성시 배치 처리 지원

제한사항

  • 동시 요청 제한: 테넌트당 100 req/min
  • 매개변수 개수 제한: 모델당 최대 50개
  • 공식 복잡도 제한: 중첩 깊이 최대 10단계
  • BOM 항목 제한: 템플릿당 최대 200개

이 API 문서는 KSS01 모델을 예시로 한 완전한 매개변수 기반 BOM 시스템의 사용법을 제공합니다. 실제 구현시에는 각 비즈니스 요구사항에 맞게 매개변수와 규칙을 조정하여 사용할 수 있습니다.