[BE-40] 수집 진행·예산·지연 운영 조회 계약
작업 내용 (설계 의도)
변경 사항
기존 GET /api/operations/collection-runs에 TDD API Contract의 additive cycle fields와 summary를 추가한다. 기존 runStatus, abnormal, pagination은 하위 호환을 지킨다. closeGuarded는 서버가 권위 있게 제공하는 “마감 판정 제외” 값이며 FE는 상태 매핑을 재구현하지 않는다. BUDGET_EXHAUSTED는 source fault가 아니다. NOT_STARTED는 persisted cycle state이며 disabled source는 cycle status를 바꾸지 않고 claim/SLA eligibility에서만 제외한다. current summary와 별도로 immutable slaSnapshot을 반환한다; 09:00 이후 SLA count/status는 current cycle을 계산하지 않고 CAPTURED snapshot item만 읽는다. 새 write API는 만들지 않는다.
의존
- BE-33
- BE-43
- DBA migration
다이어그램
처리 흐름
sequenceDiagram participant FE as Operations UI participant API as Operation API participant U as List Runs UseCase participant Q as Cycle Query FE->>API: GET collection-runs API->>U: execute(command) U->>Q: find history + live cycles Q-->>U: states/counts U-->>API: additive response
클래스 의존
flowchart LR OperationApiController --> ListCollectionRunsUseCase ListCollectionRunsUseCase --> CycleQueryDomainService CollectionRunResponseMapper --> JobSourceLabelDomainService
테스트 케이스
- 기존 query와 필드만 쓰는 클라이언트는 동일한 응답 의미를 유지한다.
- 08:59:59 KST에는 SLA snapshot captureStatus=PENDING, lateBeforeNotificationCount=0이고 items는 없다.
- DB 내부 CAPTURING은 API에 노출하지 않고 atomic capture commit 전까지 captureStatus=PENDING으로 반환한다.
- 09:00:00 KST CAPTURED snapshot에는 eligible active source의 NOT_STARTED/PENDING/RUNNING/FAILED/BUDGET_EXHAUSTED가 lateBeforeNotificationCount와 immutable item에 모두 포함된다.
- SUCCESS 0건은 late count에서는 제외되지만 abnormal=true와 closeGuarded=true를 노출한다.
- RUNNING cycle은 leaseUntil과 continuationPending, abnormal=false, closeGuarded=true를 노출한다.
- BUDGET_EXHAUSTED cycle은 budgetExhausted=true, abnormal=false, closeGuarded=true이며 broken source 목록에 들어가지 않는다.
- FAILED cycle은 abnormal=true, closeGuarded=true이고 같은 KST 날짜에 재시도 예정으로 표시되지 않는다.
- 09:00 CAPTURED snapshot은 NOT_STARTED/PENDING/RUNNING/FAILED/BUDGET_EXHAUSTED의 count와 source status를 저장하며 09:01 SUCCESS 전이 뒤에도 값이 바뀌지 않는다.
- 09:00 cutoff를 놓친 경우 API는 MISSED reason을 반환하고 later current status를 SLA snapshot으로 채우지 않는다.
- v2 첫 활성화 전·배포 전 날짜는 NOT_APPLICABLE 또는 UNAVAILABLE을 반환하고 historical current run으로 backfill하지 않는다.
- disabled source는 기존 cycle 상태를 API에서 유지하지만 09:00 eligibility와 CAPTURED SLA item에서 제외된다.