1313import org .springframework .stereotype .Component ;
1414import org .springframework .transaction .annotation .Transactional ;
1515
16+ import java .time .LocalDate ;
17+ import java .time .format .DateTimeFormatter ;
18+ import java .time .format .DateTimeParseException ;
1619import java .util .Collections ;
1720import java .util .List ;
1821import java .util .Map ;
2528@ Transactional (readOnly = true )
2629public class RankingFacade {
2730
31+ private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter .ofPattern ("yyyyMMdd" );
32+
2833 private final ProductRankingCache productRankingCache ;
2934 private final ProductRepository productRepository ;
3035 private final BrandRepository brandRepository ;
@@ -37,8 +42,8 @@ public class RankingFacade {
3742 * @return 랭킹 페이지 정보
3843 */
3944 public RankingPageInfo getRankings (String date , int page , int size ) {
40- // 날짜 기본값: 오늘
41- String targetDate = date != null ? date : productRankingCache . getTodayDate ( );
45+ // 날짜 검증 및 기본값 처리
46+ String targetDate = validateAndNormalizeDate ( date );
4247
4348 // 1. ZSET에서 랭킹 조회
4449 List <RankingEntry > rankingEntries = productRankingCache .getTopRankings (targetDate , page , size );
@@ -95,4 +100,23 @@ public RankingPageInfo getRankings(String date, int page, int size) {
95100
96101 return RankingPageInfo .of (rankings , targetDate , page , size , totalCount );
97102 }
103+
104+ /**
105+ * 날짜 파라미터 검증 및 정규화
106+ * @param date 날짜 문자열 (yyyyMMdd 형식) 또는 null
107+ * @return 검증된 날짜 문자열 (null이면 오늘 날짜)
108+ * @throws IllegalArgumentException 유효하지 않은 날짜 형식
109+ */
110+ private String validateAndNormalizeDate (String date ) {
111+ if (date == null || date .isBlank ()) {
112+ return productRankingCache .getTodayDate ();
113+ }
114+
115+ try {
116+ LocalDate .parse (date , DATE_FORMATTER );
117+ return date ;
118+ } catch (DateTimeParseException e ) {
119+ throw new IllegalArgumentException ("Invalid date format. Expected yyyyMMdd, got: " + date );
120+ }
121+ }
98122}
0 commit comments