diff --git a/apps/user-service/src/main/java/site/icebang/domain/workflow/controller/WorkflowController.java b/apps/user-service/src/main/java/site/icebang/domain/workflow/controller/WorkflowController.java index 650a2bcf..fd42ea13 100644 --- a/apps/user-service/src/main/java/site/icebang/domain/workflow/controller/WorkflowController.java +++ b/apps/user-service/src/main/java/site/icebang/domain/workflow/controller/WorkflowController.java @@ -1,5 +1,7 @@ package site.icebang.domain.workflow.controller; +import java.math.BigInteger; + import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -9,8 +11,8 @@ import site.icebang.common.dto.PageParams; import site.icebang.common.dto.PageResult; import site.icebang.domain.workflow.dto.WorkflowCardDto; +import site.icebang.domain.workflow.dto.WorkflowDetailCardDto; import site.icebang.domain.workflow.service.WorkflowExecutionService; -import site.icebang.domain.workflow.service.WorkflowHistoryService; import site.icebang.domain.workflow.service.WorkflowService; @RestController @@ -19,7 +21,6 @@ public class WorkflowController { private final WorkflowService workflowService; private final WorkflowExecutionService workflowExecutionService; - private final WorkflowHistoryService workflowHistoryService; @GetMapping("") public ApiResponse> getWorkflowList( @@ -34,4 +35,10 @@ public ResponseEntity runWorkflow(@PathVariable Long workflowId) { workflowExecutionService.executeWorkflow(workflowId); return ResponseEntity.accepted().build(); } + + @GetMapping("/{workflowId}/detail") + public ApiResponse getWorkflowDetail(@PathVariable BigInteger workflowId) { + WorkflowDetailCardDto result = workflowService.getWorkflowDetail(workflowId); + return ApiResponse.success(result); + } } diff --git a/apps/user-service/src/main/java/site/icebang/domain/workflow/dto/ScheduleDto.java b/apps/user-service/src/main/java/site/icebang/domain/workflow/dto/ScheduleDto.java new file mode 100644 index 00000000..397285cb --- /dev/null +++ b/apps/user-service/src/main/java/site/icebang/domain/workflow/dto/ScheduleDto.java @@ -0,0 +1,16 @@ +package site.icebang.domain.workflow.dto; + +import java.time.LocalDateTime; + +import lombok.Data; + +@Data +public class ScheduleDto { + private Long id; + private String cronExpression; + private Boolean isActive; + private String lastRunStatus; + private LocalDateTime lastRunAt; + private String scheduleText; + private LocalDateTime createdAt; +} diff --git a/apps/user-service/src/main/java/site/icebang/domain/workflow/dto/WorkflowDetailCardDto.java b/apps/user-service/src/main/java/site/icebang/domain/workflow/dto/WorkflowDetailCardDto.java new file mode 100644 index 00000000..a2ef46b8 --- /dev/null +++ b/apps/user-service/src/main/java/site/icebang/domain/workflow/dto/WorkflowDetailCardDto.java @@ -0,0 +1,16 @@ +package site.icebang.domain.workflow.dto; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Map; + +import lombok.Data; + +@Data +public class WorkflowDetailCardDto extends WorkflowCardDto { + private String defaultConfig; + private LocalDateTime updatedAt; + private String updatedBy; + private List schedules; + private List> jobs; +} diff --git a/apps/user-service/src/main/java/site/icebang/domain/workflow/mapper/WorkflowMapper.java b/apps/user-service/src/main/java/site/icebang/domain/workflow/mapper/WorkflowMapper.java index 00afbebc..82381737 100644 --- a/apps/user-service/src/main/java/site/icebang/domain/workflow/mapper/WorkflowMapper.java +++ b/apps/user-service/src/main/java/site/icebang/domain/workflow/mapper/WorkflowMapper.java @@ -4,7 +4,9 @@ import java.util.*; import site.icebang.common.dto.PageParams; +import site.icebang.domain.workflow.dto.ScheduleDto; import site.icebang.domain.workflow.dto.WorkflowCardDto; +import site.icebang.domain.workflow.dto.WorkflowDetailCardDto; public interface WorkflowMapper { List selectWorkflowList(PageParams pageParams); @@ -12,4 +14,10 @@ public interface WorkflowMapper { int selectWorkflowCount(PageParams pageParams); WorkflowCardDto selectWorkflowById(BigInteger id); + + WorkflowDetailCardDto selectWorkflowDetailById(BigInteger workflowId); + + List selectSchedulesByWorkflowId(BigInteger workflowId); + + List> selectWorkflowWithJobsAndTasks(BigInteger workflowId); } diff --git a/apps/user-service/src/main/java/site/icebang/domain/workflow/service/WorkflowService.java b/apps/user-service/src/main/java/site/icebang/domain/workflow/service/WorkflowService.java index 71600b4b..b994c82e 100644 --- a/apps/user-service/src/main/java/site/icebang/domain/workflow/service/WorkflowService.java +++ b/apps/user-service/src/main/java/site/icebang/domain/workflow/service/WorkflowService.java @@ -1,5 +1,9 @@ package site.icebang.domain.workflow.service; +import java.math.BigInteger; +import java.util.List; +import java.util.Map; + import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -8,7 +12,9 @@ import site.icebang.common.dto.PageParams; import site.icebang.common.dto.PageResult; import site.icebang.common.service.PageableService; +import site.icebang.domain.workflow.dto.ScheduleDto; import site.icebang.domain.workflow.dto.WorkflowCardDto; +import site.icebang.domain.workflow.dto.WorkflowDetailCardDto; import site.icebang.domain.workflow.mapper.WorkflowMapper; @Service @@ -25,4 +31,23 @@ public PageResult getPagedResult(PageParams pageParams) { () -> workflowMapper.selectWorkflowList(pageParams), () -> workflowMapper.selectWorkflowCount(pageParams)); } + + @Transactional(readOnly = true) + public WorkflowDetailCardDto getWorkflowDetail(BigInteger workflowId) { + + // 1. 워크플로우 기본 정보 조회 (단일 row, 효율적) + WorkflowDetailCardDto workflow = workflowMapper.selectWorkflowDetailById(workflowId); + if (workflow == null) { + throw new IllegalArgumentException("워크플로우를 찾을 수 없습니다: " + workflowId); + } + + // 2. 스케줄 목록 조회 (별도 쿼리로 성능 최적화) + List schedules = workflowMapper.selectSchedulesByWorkflowId(workflowId); + workflow.setSchedules(schedules); + + List> jobs = workflowMapper.selectWorkflowWithJobsAndTasks(workflowId); + workflow.setJobs(jobs); + + return workflow; + } } diff --git a/apps/user-service/src/main/resources/mybatis/mapper/WorkflowMapper.xml b/apps/user-service/src/main/resources/mybatis/mapper/WorkflowMapper.xml index dacade96..63a9f6db 100644 --- a/apps/user-service/src/main/resources/mybatis/mapper/WorkflowMapper.xml +++ b/apps/user-service/src/main/resources/mybatis/mapper/WorkflowMapper.xml @@ -39,4 +39,94 @@ LEFT JOIN user u ON w.created_by = u.id WHERE w.id = #{id} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/user-service/src/main/resources/sql/03-insert-workflow.sql b/apps/user-service/src/main/resources/sql/03-insert-workflow.sql index fc9f39c2..0660b31f 100644 --- a/apps/user-service/src/main/resources/sql/03-insert-workflow.sql +++ b/apps/user-service/src/main/resources/sql/03-insert-workflow.sql @@ -14,10 +14,13 @@ DELETE FROM `workflow`; -- =================================================================== -- 워크플로우 생성 (ID: 1) -INSERT INTO `workflow` (`id`, `name`, `description`, `created_by`) VALUES - (1, '상품 분석 및 블로그 자동 발행', '키워드 검색부터 상품 분석 후 블로그 발행까지의 자동화 프로세스', 1) - ON DUPLICATE KEY UPDATE name = VALUES(name), description = VALUES(description), updated_at = NOW(); - +INSERT INTO `workflow` (`id`, `name`, `description`, `created_by`, `default_config`) VALUES + (1, '상품 분석 및 블로그 자동 발행', '키워드 검색부터 상품 분석 후 블로그 발행까지의 자동화 프로세스', 1, + JSON_OBJECT('keyword_search',json_object('tag','naver'),'blog_publish',json_object('tag','naver_blog','blog_id', 'wtecho331', 'blog_pw', 'testpass'))) +ON DUPLICATE KEY UPDATE + name = VALUES(name), + description = VALUES(description), + updated_at = NOW(); -- Job 생성 (ID: 1, 2) INSERT INTO `job` (`id`, `name`, `description`, `created_by`) VALUES (1, '상품 분석', '키워드 검색, 상품 크롤링 및 유사도 분석 작업', 1),