Files
sam-docs/projects/quotation/phase-2-mng-analysis/issues.md
hskwon 3b2f1cefa4 견적 기능 개발 Phase 2: mng 분석 완료
- mng 견적 수식 관리 현재 상태 분석
  - DB 테이블 5개, Models 5개, Services 2개
  - Controllers 3개, Views 9개 구현 완료
- 핵심 이슈 도출
  - 품목 단가 조회 미연동 (getItemPrice TODO)
  - 수식 데이터 미입력 (테이블 비어있음)
  - eval() 보안 취약점
- 5130 vs mng 비교 분석
- PROGRESS.md 업데이트
2025-12-19 15:44:56 +09:00

6.1 KiB

mng 견적 수식 관리 이슈 및 개선사항

분석일: 2025-12-19 대상: mng 프로젝트 quote-formulas 기능


🔴 Critical Issues (필수 해결)

1. 품목 단가 조회 미연동

위치: FormulaEvaluatorService.php:324-328

private function getItemPrice(string $itemCode): float
{
    // TODO: 품목 마스터에서 단가 조회
    return 0;
}

문제점:

  • 품목 출력 시 단가가 항상 0으로 반환
  • 견적 금액 계산 불가

해결 방안:

private function getItemPrice(string $itemCode): float
{
    $tenantId = session('selected_tenant_id');

    // prices 테이블 또는 products 테이블에서 조회
    $price = Price::where('tenant_id', $tenantId)
        ->where('item_code', $itemCode)
        ->where('is_active', true)
        ->first();

    return $price?->unit_price ?? 0;
}

우선순위: 🔴 Critical 예상 작업량: 2시간


2. 수식 데이터 미입력

문제점:

  • quote_formula_categories, quote_formulas 테이블이 비어있음
  • Phase 1에서 분석한 5130 수식이 입력되지 않음

해결 방안:

  • Phase 3에서 5130 수식을 mng DB로 마이그레이션
  • Seeder 또는 관리 UI를 통한 데이터 입력

우선순위: 🔴 Critical 예상 작업량: 4시간


🟡 Important Issues (권장 해결)

3. eval() 사용 보안 취약점

위치: FormulaEvaluatorService.php:291-299

private function calculateExpression(string $expression): float
{
    // 안전한 수식 평가 (숫자, 연산자, 괄호만 허용)
    $expression = preg_replace('/[^0-9+\-*\/().%\s]/', '', $expression);

    try {
        // eval 대신 안전한 계산 라이브러리 사용 권장
        return (float) eval("return {$expression};");
    } catch (\Throwable $e) {
        $this->errors[] = "계산 오류: {$expression}";
        return 0;
    }
}

문제점:

  • eval() 함수 사용은 잠재적 보안 위험
  • 코드 주입 공격 가능성 (현재 정규식 필터로 일부 방어)

해결 방안:

// symfony/expression-language 패키지 사용
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;

private ExpressionLanguage $expressionLanguage;

private function calculateExpression(string $expression): float
{
    try {
        return (float) $this->expressionLanguage->evaluate($expression);
    } catch (\Throwable $e) {
        $this->errors[] = "계산 오류: {$expression}";
        return 0;
    }
}

우선순위: 🟡 Important 예상 작업량: 3시간


4. 5130 수식 vs mng 수식 Gap

5130에서 발견된 수식 중 mng 미지원 항목:

5130 수식 mng 지원 Gap
절곡 옵션에 따른 분기 mapping -
면적별 검사비 계산 range -
모터 용량 자동 선택 ⚠️ 부분지원 범위 조건 복잡
스크린/슬랫 제품 분기 ⚠️ product_id 데이터 없음
단가표 조회 (price_*) 🔴 미지원 getItemPrice TODO

우선순위: 🟡 Important 예상 작업량: Phase 3 전체


5. 중첩 함수 처리 한계

현재 상태:

  • ROUND(SUM(A, B), 2) 같은 중첩 함수 처리 제한적
  • 정규식 기반 파싱으로 복잡한 중첩 처리 어려움

해결 방안:

  • 재귀적 파서 구현 또는 AST 기반 파서 도입
  • 또는 symfony/expression-language로 전환

우선순위: 🟡 Important 예상 작업량: 4시간


🟢 Minor Issues (개선 권장)

6. 변수명 검증 강화

현재 상태:

  • 변수명 중복 체크만 수행
  • 예약어(함수명) 사용 검증 없음

해결 방안:

public function isValidVariableName(string $variable): bool
{
    $reserved = ['SUM', 'ROUND', 'CEIL', 'FLOOR', 'ABS', 'MIN', 'MAX', 'IF', 'AND', 'OR', 'NOT'];

    if (in_array(strtoupper($variable), $reserved)) {
        return false;
    }

    return preg_match('/^[A-Z][A-Z0-9_]*$/', $variable);
}

우선순위: 🟢 Minor 예상 작업량: 30분


7. 수식 의존성 분석

현재 상태:

  • 수식 간 의존성(어떤 변수가 어떤 수식에서 사용되는지) 분석 없음
  • 삭제 시 참조 무결성 검증 없음

해결 방안:

  • 변수 사용처 분석 기능 추가
  • 삭제 전 참조 검사

우선순위: 🟢 Minor 예상 작업량: 2시간


8. 수식 버전 관리

현재 상태:

  • 수식 변경 이력 관리 없음
  • 이전 버전으로 롤백 불가

해결 방안:

  • quote_formula_versions 테이블 추가
  • 변경 시 이전 버전 저장

우선순위: 🟢 Minor (향후) 예상 작업량: 4시간


5130 vs mng 상세 비교

수식 저장 방식

항목 5130 mng
저장 위치 JS 파일 하드코딩 DB 테이블
관리 방식 코드 수정 필요 관리 UI
유연성 낮음 높음
배포 파일 배포 필요 즉시 반영

계산 엔진

항목 5130 mng
실행 환경 브라우저 JavaScript 서버 PHP
함수 지원 JS 내장 함수 전체 11개 제한
성능 클라이언트 부담 서버 부담
보안 수식 노출 수식 보호

단가 조회

항목 5130 mng
조회 방식 PHP에서 직접 SQL TODO 상태
테이블 price_screen, price_slat 등 prices (통합)
캐싱 없음 가능

Phase 3 구현 시 고려사항

  1. 수식 데이터 마이그레이션 순서

    • 카테고리 먼저 생성 (13개)
    • 기본정보 수식부터 순차 입력
    • 의존성 순서 고려
  2. 제품별 수식 분리

    • 공통 수식: product_id = NULL
    • 스크린 전용: product_id = 스크린 ID
    • 슬랫 전용: product_id = 슬랫 ID
  3. 테스트 케이스 준비

    • Phase 1에서 정의한 테스트 케이스 활용
    • 5130과 동일 결과 검증

참조