diff --git a/backend/src/main/java/com/zioinfo/mes/common/GlobalExceptionHandler.java b/backend/src/main/java/com/zioinfo/mes/common/GlobalExceptionHandler.java index 1586a58..8aabecb 100644 --- a/backend/src/main/java/com/zioinfo/mes/common/GlobalExceptionHandler.java +++ b/backend/src/main/java/com/zioinfo/mes/common/GlobalExceptionHandler.java @@ -1,6 +1,7 @@ package com.zioinfo.mes.common; import lombok.extern.slf4j.Slf4j; +import org.springframework.dao.DataAccessException; import org.springframework.http.HttpStatus; import org.springframework.security.access.AccessDeniedException; import org.springframework.web.bind.annotation.ExceptionHandler; @@ -39,6 +40,14 @@ public class GlobalExceptionHandler { return ApiResponse.fail(e.getMessage()); } + @ExceptionHandler(DataAccessException.class) + @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) + public ApiResponse handleDataAccess(DataAccessException e) { + // 보안 불변 규칙: SQL/테이블/쿼리/스택 상세 절대 미노출 — 내부 로그만 남기고 일반 메시지 반환 + log.error("DB 오류", e); + return ApiResponse.fail("ERR-MES-DB: 데이터 처리 중 오류가 발생했습니다"); + } + @ExceptionHandler(RuntimeException.class) @ResponseStatus(HttpStatus.BAD_REQUEST) public ApiResponse handleRuntime(RuntimeException e) { diff --git a/backend/src/main/resources/mapper/AnalyticsMapper.xml b/backend/src/main/resources/mapper/AnalyticsMapper.xml index a244b25..af79ba9 100644 --- a/backend/src/main/resources/mapper/AnalyticsMapper.xml +++ b/backend/src/main/resources/mapper/AnalyticsMapper.xml @@ -8,7 +8,7 @@ COALESCE(SUM(good_qty),0) AS total_good, COALESCE(SUM(defect_qty),0) AS total_defect, ROUND( (COALESCE(SUM(defect_qty),0)::numeric - / NULLIF(SUM(good_qty)+SUM(defect_qty),0) * 100), 2) AS defect_rate, + / NULLIF(SUM(good_qty)+SUM(defect_qty),0) * 100)::numeric, 2) AS defect_rate, (SELECT COUNT(*) FROM mes_workorder WHERE status IN ('DONE','CLOSED') AND updated_at >= CURRENT_DATE - (#{days} || ' days')::interval) AS completed_workorders