package com.goi.erp.service; import com.goi.erp.entity.ScheduleJobLog; import com.goi.erp.repository.ScheduleJobLogRepository; import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import java.time.LocalDateTime; import java.util.Optional; @Service @RequiredArgsConstructor public class ScheduleJobLogService { private final ScheduleJobLogRepository repository; /** * 최근 성공 실행 시작 시각 조회 * (없으면 Optional.empty) */ @Transactional public Optional getLastSuccessStartedAt(Long jobId) { return repository.findLastSuccessStartedAt(jobId); } /** * 현재 실행 중인지 여부 * (중복 실행 방지) */ @Transactional public boolean isRunning(Long jobId) { return repository.existsBySjlJobIdAndSjlStatus(jobId, "RUNNING"); } /** * 실행 시작 로그 생성 */ @Transactional public ScheduleJobLog createRunningLog( Long jobId, LocalDateTime scheduledAt, Integer lookbackHours, Integer overlapMinutes, Integer maxRecords, String executedBy ) { ScheduleJobLog log = ScheduleJobLog.builder() .sjlJobId(jobId) .sjlStatus("RUNNING") .sjlScheduledAt(scheduledAt) .sjlStartedAt(LocalDateTime.now()) .sjlLookbackHours(lookbackHours) .sjlOverlapMinutes(overlapMinutes) .sjlMaxRecords(maxRecords) .sjlExecutedBy(executedBy) .build(); return repository.save(log); } /** * 실행 성공 처리 */ @Transactional public void markSuccess( Long logId, int processedCount, int successCount, int failCount ) { ScheduleJobLog log = repository.findById(logId) .orElseThrow(() -> new IllegalStateException("ScheduleJobLog not found. id=" + logId) ); log.setSjlStatus("SUCCESS"); log.setSjlFinishedAt(LocalDateTime.now()); log.setSjlProcessedCount(processedCount); log.setSjlSuccessCount(successCount); log.setSjlFailCount(failCount); } /** * 실행 실패 처리 */ @Transactional public void markFailed( Long logId, String errorCode, String errorMessage ) { ScheduleJobLog log = repository.findById(logId) .orElseThrow(() -> new IllegalStateException("ScheduleJobLog not found. id=" + logId) ); log.setSjlStatus("FAILED"); log.setSjlFinishedAt(LocalDateTime.now()); log.setSjlErrorCode(errorCode); log.setSjlErrorMessage(errorMessage); } /** * 실행 스킵 처리 (중복 실행, 비활성화 등) */ @Transactional public ScheduleJobLog markSkipped( Long jobId, LocalDateTime scheduledAt, String reason, String executedBy ) { ScheduleJobLog log = ScheduleJobLog.builder() .sjlJobId(jobId) .sjlStatus("SKIPPED") .sjlScheduledAt(scheduledAt) .sjlStartedAt(LocalDateTime.now()) .sjlFinishedAt(LocalDateTime.now()) .sjlErrorMessage(reason) .sjlExecutedBy(executedBy) .build(); return repository.save(log); } }