[BE-56] facility 운영시간·휴무 VO + Facility 임베드
작업 내용 (설계 의도)
변경 사항
근거 TDD: “Possible Solutions 운영시간 저장 위치 A(임베드)·도메인 모델 OperatingHours/Holiday”.
Facility(MongoDB 문서)에 운영시간·휴무를 시설 속성으로 추가한다(FR-7/8). 자동 슬롯 생성(BE-58)이 읽어갈 계약이라 선행 확립.
포함:
OperatingHours(VO) — dayOfWeek·openTime·closeTime·breaks(복수 TimeRange)·slotDurationMinutes(default 60)·capacity.slotRangesFor(date): List<TimeRange>— 브레이크 제외 슬롯단위 슬라이스 계산 캡슐화.Holiday(VO) — 휴무 날짜 보유.TimeRange(VO) — HH:mm-HH:mm 표현·겹침 판단.Facility문서에operatingHours: List<OperatingHours>·holidays: List<Holiday>임베드 필드 추가 +registerOperatingHours(...)·addHoliday(date)·removeHoliday(date)캡슐화 메서드(소유자 검증은 서비스에서). private-mongodb-convention: 임베딩, validator 갱신은 mongodb-implementer.- application:
RegisterOperatingHoursUseCase·AddHoliday/RemoveHolidayUseCase+ Command/Response. FacilityResponse(시설 상세 조회GET /facilities/{facilityId})에operatingHours·holidays임베드 노출 추가(additive — FR-7/8 app 운영시간 카드·web 폼 프리필 FE 지탱, senior-pm 보강). 전용 GET 경로는 불필요(임베드). 기존 시설 조회 UseCase의 Response 매핑에 두 필드 포함(GetFacility/GetMyFacility Response — 읽기 매핑만 확장, 파일 소유 확인).- presentation:
FacilityScheduleApiController(PUT operating-hours, POST/DELETE holidays) +@ConditionalOnProperty(facility.autoslot.enabled)아님 — 운영시간 등록 자체는 항상 허용, 슬롯 생성 스케줄러만 플래그. Request→Command 변환. ZonedDateTime·시간 규칙 준수, 브레이크는 data class(no-stringified-json).
롤백
Mongo 문서 필드 추가라 무중단·역호환. 롤백은 배포 되돌림(임베드 필드는 무시됨).
의존
- 없음
다이어그램
처리 흐름
sequenceDiagram participant C as FacilityScheduleApiController participant U as RegisterOperatingHoursUseCase participant S as FacilityOwnerDomainService C->>U: execute(command) U->>S: registerOperatingHours(facilityId, ownerId, hours) S-->>C: Response
클래스 의존
flowchart LR Fac[Facility] --> OH[OperatingHours] Fac --> Hol[Holiday] OH --> TR[TimeRange]
테스트 케이스
- 06:00
22:00, 브레이크 12:0013:00, 60분 단위 등록 시 slotRangesFor가 브레이크를 제외한 시간대 목록을 만든다 - 브레이크 경계(12:00·13:00)에 걸친 슬롯이 생성 대상에서 정확히 제외된다
- 휴무일로 지정된 날짜는 holidays에 포함돼 생성 제외 판단이 true다
- 소유자가 아닌 사용자의 운영시간 등록은 시설 소유권 예외를 던진다
- 운영시간이 없는 요일은 slotRangesFor가 빈 목록을 반환한다(에러 아님)
- 동일 휴무일 중복 추가는 멱등하게 처리된다
- 시설 상세 조회 응답에 등록된 operatingHours·holidays가 포함된다
- 운영시간·휴무 미등록 시설의 상세 조회는 빈 배열을 정상 반환한다(에러 아님)