[BE-58] 자동 슬롯 생성 스케줄러 (멱등, 향후 14일)
작업 내용 (설계 의도)
변경 사항
근거 TDD: “Possible Solutions 자동 슬롯 생성 A·실패 경로 배치 멱등/부분실패·서버 토폴로지”. 운영시간·휴무 기준으로 매일 향후 14일 예약 가능 회차(Slot)를 자동 생성한다(FR-9). 기존 (facility,date,timeRange) 조합은 skip(멱등), 신규 날짜분만 생성 — V14 UNIQUE와 충돌 없이 재실행 안전(Scenario22).
포함 (전부 신규 파일):
- domain:
FacilityScheduleGatewayinterface(booking) +FacilitySchedule/WeeklyHours(booking 소유 DTO — facility import 금지) +SlotGenerationDomainService.generate(schedule, windowDays)— 윈도우 내 기존 슬롯 (date,timeRange) Set 조회 후 미존재분만Slot.create(programId=null, status=OPEN), 생성건수 반환. - application:
GenerateSlotsUseCase.execute()—FacilityScheduleGateway.findSchedulableFacilities()순회, 시설 단위 try-catch로 부분실패 격리, 시설별 생성/skip 집계 반환. - infrastructure:
FacilityScheduleGatewayImpl(MongoFacilityRepository읽어 운영시간·휴무를 booking DTO로 변환,@Profile("!test-jpa")— FacilityOwnershipGatewayImpl 패턴). - presentation:
GenerateSlotsScheduler(@Scheduled(cron)1일1회,McpAnomalyScheduler패턴) +@ConditionalOnProperty(facility.autoslot.enabled)— 초기 OFF로 대량 생성 사고 방지. windowDays는 설정값(default 14). - 시간
ZonedDateTime, 휴무일 skip, 운영시간 없는 요일 skip.
롤백
facility.autoslot.enabled=false로 스케줄러 즉시 정지. 이미 생성된 슬롯은 유지(무해).
의존
- BE-56 (OperatingHours/Holiday VO)
- BE-57 (Slot status/create 확장)
다이어그램
처리 흐름
sequenceDiagram participant Sch as GenerateSlotsScheduler participant U as GenerateSlotsUseCase participant G as FacilityScheduleGateway participant S as SlotGenerationDomainService Sch->>U: execute() U->>G: findSchedulableFacilities() loop 시설별 (try-catch) U->>S: generate(schedule, 14) S->>S: 기존(date,timeRange) skip, 신규만 create end
클래스 의존
flowchart LR Sch[GenerateSlotsScheduler] --> U[GenerateSlotsUseCase] U --> Gw[FacilityScheduleGateway] U --> SGS[SlotGenerationDomainService] SGS --> SlotRepo[SlotRepository] GwImpl[FacilityScheduleGatewayImpl] -.->|implements| Gw
테스트 케이스
- 운영시간 등록된 시설에 향후 14일치 슬롯이 생성된다
- 같은 14일 윈도우로 재실행 시 기존 (시설,날짜,시간대)는 skip되고 중복 슬롯이 생기지 않는다(멱등)
- 휴무일로 지정된 날짜에는 슬롯이 생성되지 않는다
- 브레이크타임 시간대는 슬롯 생성에서 제외된다
- 한 시설의 DB 오류가 다른 시설 슬롯 생성을 막지 않는다(부분실패 격리)
- 새 윈도우에 편입된 날짜분만 신규 생성된다
- facility.autoslot.enabled=false면 스케줄러가 실행되지 않는다