STK10-08 마감 후 수집 스케줄러·수동 갱신 트리거

작업 내용

5종 수집을 오케스트레이션하는 UseCase와, 이를 호출하는 두 개의 진입점(자동 스케줄러 + 수동 트리거 API)을 구현한다. 두 진입점 모두 동일한 CollectMarketFlowUseCase를 호출한다.

  • application: CollectMarketFlowUseCaseMarketFlowDomainService.collect(baseDate) 호출 (@Transactional은 통계 단위, 부분 실패 허용)
  • domain: MarketFlowDomainService.collect() — 5개 Gateway·Repository 순차 수집·적재, 통계 단위 실패 격리, 공매도 거래일/공시일 처리
  • presentation: MarketFlowCollectScheduler — 마감 후(예: 19시 KST) cron, 활성/비활성 플래그
  • presentation: MarketFlowCollectApiControllerPOST /market-flow/collect 수동 갱신. baseDate 미지정 시 직전 영업일 기준

수동 트리거는 필요 타이밍(데이터 누락·확정치 지연·당일 재수집)에 갱신하기 위함이다. 멱등 upsert라 중복 호출이 안전하다.

모니터링 (ADR-006)

  • run별·통계별 결과를 marketflow_collect_log에 기록 (상태·행수·소요·에러).
  • 실패·부분 실패 시 DiscordNotificationGateway(alert 도메인)로 알림.
  • Micrometer 메트릭 계측: marketflow.collect.rows{statistic}, marketflow.collect.duration{statistic}, marketflow.collect.total.duration, marketflow.collect.failure{statistic}, marketflow.krx.retry. OTel Java agent가 자동 export → Grafana (청크 전환 시그널).

다이어그램

처리 흐름

sequenceDiagram
    participant Entry as Scheduler / ManualTrigger
    participant UC as CollectMarketFlowUseCase
    participant DS as MarketFlowDomainService
    Entry->>UC: execute(baseDate)
    UC->>DS: collect(baseDate)
    loop 5종 통계
        DS->>DS: fetch + upsert (실패 시 해당 항목만 skip)
    end
    DS-->>UC: collected summary
    UC-->>Entry: result

클래스 의존

flowchart LR
    Scheduler[MarketFlowCollectScheduler] --> UC[CollectMarketFlowUseCase]
    Controller[MarketFlowCollectApiController] --> UC
    UC --> DS[MarketFlowDomainService]
    DS --> Gws[5 Gateways]
    DS --> Repos[(5 Repositories)]

테스트 케이스

  • 스케줄러가 마감 후 cron에 UseCase를 1회 호출한다
  • 수동 트리거 POST /market-flow/collect가 동일 UseCase를 호출한다
  • baseDate 미지정 시 직전 영업일 기준으로 수집한다
  • 5종 중 일부 수집 실패 시 나머지는 적재된다 (부분 실패 허용)
  • 동일 baseDate 재수집(수동) 시 멱등하게 처리된다
  • 비활성 플래그 상태에서는 스케줄러가 수집하지 않는다
  • run별·통계별 결과가 marketflow_collect_log에 기록된다
  • 실패·부분 실패 시 Discord 알림이 호출된다
  • 수집 행수·소요·재시도 메트릭이 계측된다