diff --git a/src/main/java/com/howWeather/howWeather_backend/domain/ai_model/service/AiInternalService.java b/src/main/java/com/howWeather/howWeather_backend/domain/ai_model/service/AiInternalService.java index 0b0ed27..f2dc8b2 100644 --- a/src/main/java/com/howWeather/howWeather_backend/domain/ai_model/service/AiInternalService.java +++ b/src/main/java/com/howWeather/howWeather_backend/domain/ai_model/service/AiInternalService.java @@ -58,21 +58,42 @@ public AiPredictionRequestDto makePredictRequest(Member member) { private List getWeatherForecast(Member member) { List targetHours = List.of(9, 12, 15, 18, 21); - String regionName = member.getRegionName() != null ? member.getRegionName() : "서울특별시 용산구"; + LocalDate today = LocalDate.now(); + List forecasts = weatherForecastRepository - .findByRegionNameAndForecastDateAndHourIn(regionName, LocalDate.now(), targetHours); + .findByRegionNameAndForecastDateAndHourInOrderByCreatedAtDesc(regionName, today, targetHours); + + if (forecasts.isEmpty()) { + LocalDate yesterday = today.minusDays(1); + log.warn("[날씨 조회 재시도] 지역 {}에 대해 오늘({}) 데이터가 없어 어제({}) 날짜로 재시도합니다.", + regionName, today, yesterday); + + forecasts = weatherForecastRepository + .findByRegionNameAndForecastDateAndHourInOrderByCreatedAtDesc(regionName, yesterday, targetHours); + + if (forecasts.isEmpty()) { + log.error("[날씨 조회 최종 실패] 지역 {}에 대해 어제, 오늘 모두 예보 데이터가 없습니다.", regionName); + } + } log.info("[날씨 조회 결과] memberId={}, 지역: {}, 조회된 예보 개수: {}", member.getId(), regionName, forecasts.size()); + Map hourToForecastMap = forecasts.stream() + .collect(Collectors.toMap( + WeatherForecast::getHour, + forecast -> forecast, + (oldVal, newVal) -> oldVal + )); - return forecasts.stream() + return hourToForecastMap.values().stream() .map(this::convertToDto) .collect(Collectors.toList()); } + private WeatherPredictDto convertToDto(WeatherForecast forecast) { return WeatherPredictDto.builder() .hour(forecast.getHour()) diff --git a/src/main/java/com/howWeather/howWeather_backend/domain/ai_model/service/RecommendationService.java b/src/main/java/com/howWeather/howWeather_backend/domain/ai_model/service/RecommendationService.java index eb81bf9..1eae214 100644 --- a/src/main/java/com/howWeather/howWeather_backend/domain/ai_model/service/RecommendationService.java +++ b/src/main/java/com/howWeather/howWeather_backend/domain/ai_model/service/RecommendationService.java @@ -116,9 +116,7 @@ private List makeWeatherFeeling(Map predicti ClothingRecommendation recommendation) { List feelingList = new ArrayList<>(); - LocalDate today = LocalDate.now(); - LocalTime now = LocalTime.now(); - LocalDate forecastDate = now.isBefore(LocalTime.of(6, 0)) ? today.minusDays(1) : today; + LocalDate forecastDate = recommendation.getDate(); String regionName = recommendation.getRegionName(); @@ -127,13 +125,13 @@ private List makeWeatherFeeling(Map predicti .collect(Collectors.toList()); List forecasts = weatherForecastRepository - .findByRegionNameAndForecastDateAndHourIn(regionName, forecastDate, hours); + .findByRegionNameAndForecastDateAndHourInOrderByCreatedAtDesc(regionName, forecastDate, hours); Map hourToForecastMap = forecasts.stream() .collect(Collectors.toMap( WeatherForecast::getHour, forecast -> forecast, - (oldVal, newVal) -> newVal + (oldVal, newVal) -> oldVal )); for (Map.Entry entry : predictionMap.entrySet()) { @@ -150,10 +148,9 @@ private List makeWeatherFeeling(Map predicti .build(); feelingList.add(dto); } else { - log.warn("날씨 데이터 없음: region={}, hour={}", regionName, hour); + log.warn("날씨 데이터 없음: region={}, date={}, hour={}", regionName, forecastDate, hour); } } - return feelingList; } diff --git a/src/main/java/com/howWeather/howWeather_backend/domain/weather/repository/WeatherForecastRepository.java b/src/main/java/com/howWeather/howWeather_backend/domain/weather/repository/WeatherForecastRepository.java index 3d0d964..5685ec1 100644 --- a/src/main/java/com/howWeather/howWeather_backend/domain/weather/repository/WeatherForecastRepository.java +++ b/src/main/java/com/howWeather/howWeather_backend/domain/weather/repository/WeatherForecastRepository.java @@ -13,9 +13,13 @@ public interface WeatherForecastRepository extends JpaRepository findByRegionNameAndForecastDate(String regionName, LocalDate now); - List findByRegionNameAndForecastDateAndHourIn( + List findByRegionNameAndForecastDateAndHourInOrderByCreatedAtDesc( String regionName, LocalDate forecastDate, - List hours); + List hours + ); + void deleteByForecastDateGreaterThanEqual(LocalDate baseDate); + + List findByRegionNameAndForecastDateAndHourIn(String regionName, LocalDate now, List targetHours); } diff --git a/src/main/java/com/howWeather/howWeather_backend/domain/weather/service/WeatherService.java b/src/main/java/com/howWeather/howWeather_backend/domain/weather/service/WeatherService.java index c967fd2..c449e91 100644 --- a/src/main/java/com/howWeather/howWeather_backend/domain/weather/service/WeatherService.java +++ b/src/main/java/com/howWeather/howWeather_backend/domain/weather/service/WeatherService.java @@ -11,6 +11,7 @@ import com.howWeather.howWeather_backend.global.exception.CustomException; import com.howWeather.howWeather_backend.global.exception.ErrorCode; import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -20,6 +21,7 @@ @Service @AllArgsConstructor +@Slf4j public class WeatherService { private final WeatherRepository weatherRepository; private final WeatherApiClient weatherApiClient; @@ -64,9 +66,10 @@ public double getTemperature(WeatherSimpleDto dto) { @Transactional public void fetchHourlyForecast() { List regions = regionRepository.findAll(); - LocalDate baseDate = LocalDate.now(); + weatherForecastRepository.deleteByForecastDateGreaterThanEqual(baseDate); + List allForecasts = new ArrayList<>(); for (Region region : regions) { @@ -74,7 +77,19 @@ public void fetchHourlyForecast() { double lon = region.getLon(); String regionName = region.getName(); - List forecasts = weatherApiClient.fetchForecast(lat, lon); + List forecasts = null; + try { + forecasts = weatherApiClient.fetchForecast(lat, lon); + + if (forecasts == null || forecasts.isEmpty()) { + log.warn("[날씨 API 경고] 지역 {}에 대해 유효한 예보 데이터가 없어 저장 생략.", regionName); + continue; + } + + } catch (Exception e) { + log.error("[날씨 API 오류] 지역 {}의 예보 데이터 가져오기 실패: {}", regionName, e.getMessage()); + continue; + } int cnt = 0; for (WeatherPredictDto dto : forecasts) { @@ -96,6 +111,12 @@ public void fetchHourlyForecast() { cnt++; } } - weatherForecastRepository.saveAll(allForecasts); + + if (!allForecasts.isEmpty()) { + weatherForecastRepository.saveAll(allForecasts); + log.info("[날씨 예보 저장 완료] 총 {}개의 예보 데이터가 DB에 저장되었습니다.", allForecasts.size()); + } else { + log.warn("[날씨 예보 저장 실패] 모든 지역에서 API 호출에 실패하여 저장된 데이터가 없습니다."); + } } }