fix(배치관리): 대시보드 NaN 제거 + 24시간 차트 더미데이터 → 실데이터

- 백엔드: getBatchManagementGlobalSparklineData 쿼리 추가 (generate_series 로
  24개 슬롯 고정, 회사 전체 배치 LEFT JOIN 집계)
- 백엔드: GET /api/batch-management/sparkline 엔드포인트 추가
- 프론트: BatchStats/SparklineData 타입을 백엔드 mapper 의 snake_case 응답키와
  일치시킴 (today_count, today_failed_count, hour_slot, success_count, ...).
  키 미스매치로 stats 카드가 NaN 으로 표시되던 버그 해소
- 프론트: GlobalSparkline 컴포넌트의 Math.random() 더미 막대를 실데이터 prop 으로
  교체. row-level Sparkline 도 동일 키 정렬로 정상 렌더되도록 수정

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
hjjeong
2026-05-20 09:59:52 +09:00
parent 8a10edd8e1
commit 067193efa9
5 changed files with 109 additions and 28 deletions
@@ -136,6 +136,15 @@ public class BatchManagementController {
return ResponseEntity.ok(ApiResponse.success(batchManagementService.getBatchSparkline(params)));
}
/** GET /api/batch-management/sparkline — 회사 전체 배치의 최근 24시간 1시간 단위 실행 집계 (24개 슬롯 고정) */
@GetMapping("/sparkline")
public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getGlobalSparkline(
@RequestAttribute("company_code") String companyCode) {
Map<String, Object> params = new HashMap<>();
params.put("company_code", companyCode);
return ResponseEntity.ok(ApiResponse.success(batchManagementService.getGlobalSparkline(params)));
}
/** GET /api/batch-management/batch-configs/:id/recent-logs — 최근 실행 로그 (최대 20건) */
@GetMapping("/batch-configs/{id}/recent-logs")
public ResponseEntity<ApiResponse<List<Map<String, Object>>>> getBatchRecentLogs(
@@ -296,6 +296,11 @@ public class BatchManagementService extends BaseService {
return sqlSession.selectList(NS + "getBatchManagementSparklineData", params);
}
public List<Map<String, Object>> getGlobalSparkline(Map<String, Object> params) {
commonService.applyCompanyCodeFilter(params);
return sqlSession.selectList(NS + "getBatchManagementGlobalSparklineData", params);
}
public List<Map<String, Object>> getBatchRecentLogs(Map<String, Object> params) {
return sqlSession.selectList(NS + "getBatchManagementRecentLogList", params);
}
@@ -87,6 +87,32 @@
ORDER BY hour_slot
</select>
<!-- 글로벌 스파크라인: 회사 전체 배치의 최근 24시간 1시간 단위 실행 집계 (빈 슬롯 포함 24개 고정) -->
<select id="getBatchManagementGlobalSparklineData" parameterType="map" resultType="map">
WITH hours AS (
SELECT generate_series(
DATE_TRUNC('hour', NOW() - INTERVAL '23 hours'),
DATE_TRUNC('hour', NOW()),
INTERVAL '1 hour'
) AS hour_slot
),
filtered_logs AS (
SELECT DATE_TRUNC('hour', start_time) AS hour_slot,
execution_status
FROM batch_execution_logs
WHERE start_time >= NOW() - INTERVAL '24 hours'
<include refid="common.companyCodeFilter"/>
)
SELECT h.hour_slot,
COUNT(l.execution_status) AS total_count,
COALESCE(SUM(CASE WHEN l.execution_status = 'SUCCESS' THEN 1 ELSE 0 END), 0) AS success_count,
COALESCE(SUM(CASE WHEN l.execution_status = 'FAILED' THEN 1 ELSE 0 END), 0) AS failed_count
FROM hours h
LEFT JOIN filtered_logs l ON l.hour_slot = h.hour_slot
GROUP BY h.hour_slot
ORDER BY h.hour_slot
</select>
<!-- 최근 실행 로그 목록 (최대 20건) -->
<select id="getBatchManagementRecentLogList" parameterType="map" resultType="map">
SELECT id,