[BE-03] 대기질 도메인 계약 — CAI 등급 VO + Gateway·Cache 인터페이스 + DomainService
작업 내용 (설계 의도)
변경 사항
신규 airquality 바운디드 컨텍스트의 순수 도메인 계약을 확립한다. 대기질 후행 티켓(Gateway 구현·UseCase/Controller)이 import하는 병목이라 wave 1에 배치한다. facility·region과 파일·패키지가 완전히 독립이라 BE-01과 병렬. 근거 TDD: ../TDD.md FR-11 등급 기준·“인터페이스 시그니처”.
domain/airquality/vo/AirQualityGrade.kt— CAI 4단계 enum(GOOD/MODERATE/BAD/VERY_BAD/UNKNOWN).ofPm10(0-30/31-80/81-150/151+),ofPm25(0-15/16-35/36-75/76+),worseOf(a,b),isBadOrWorse(). 경계값·null 처리 캡슐화(매직넘버는 상수).domain/airquality/vo/AirQualityMeasurement.kt— 원시 측정값(pm10/pm25/stationName/measuredAt nullable) +empty().domain/airquality/vo/AirQuality.kt— 등급 포함 값 +of(measurement)(등급 조립·대표 등급) +empty()(UNKNOWN).domain/airquality/gateway/AirQualityGateway.kt—current(lat,lng): AirQualityMeasurement(실패 시 empty 계약 주석).domain/airquality/repository/AirQualityMeasurementCache.kt—findBy(gridKey),save(gridKey, measurement).domain/airquality/service/AirQualityDomainService.kt—current(lat,lng): AirQuality(gateway 위임 +AirQuality.of). 시간 타입은ZonedDateTime.
의존
- 없음
다이어그램
클래스 의존
flowchart LR Grade[AirQualityGrade] AQ[AirQuality VO] M[AirQualityMeasurement VO] Gw[AirQualityGateway iface] Cache[AirQualityMeasurementCache iface] Svc[AirQualityDomainService] AQ --> Grade AQ --> M Svc --> Gw Svc --> AQ
테스트 케이스
- PM10 80은 MODERATE, 81은 BAD로 등급화된다(경계값)
- PM2.5 76은 VERY_BAD, PM10 값이 null이면 UNKNOWN으로 등급화된다
- pm10 BAD·pm25 MODERATE이면 대표 등급은 더 나쁜 BAD가 된다
- pm10만 존재하고 pm25가 null이면 대표 등급은 pm10 등급을 따른다(UNKNOWN 제외)
- AirQualityDomainService는 gateway가 empty를 반환하면 representativeGrade UNKNOWN인 AirQuality를 반환한다