Skip to content

feat: 사진 없는 슬롯을 지도로 넘긴다 (숙박 45곳 공백) - #252

Merged
sevineleven merged 31 commits into
devfrom
feat/236-stay-presentation
Aug 13, 2026
Merged

feat: 사진 없는 슬롯을 지도로 넘긴다 (숙박 45곳 공백)#252
sevineleven merged 31 commits into
devfrom
feat/236-stay-presentation

Conversation

@sevineleven

Copy link
Copy Markdown
Contributor

머지 순서 4/5#157(#249) → #189(#250) → #140(#251) → #236#172
이 PR 은 #251 위에 쌓여 있다. base 가 feat/140-slot-benefit 이라 앞의 셋을 순서대로 먼저 머지해야 한다.

Situation

"사진 없는 장소는 코스에 넣지 않는다" 를 규칙으로 세웠는데, 숙박만 이 규칙을 못 견딘다.

후보 사진 있음 지역평균 2박3일 미달 지역
볼거리 4,354건 95.5% 46.7건 0곳
맛집 1,516건 79.2% 13.5건 17곳
숙박 466건 66.3% 3.5건 45곳 / 89

상당수가 미달이 아니라 0건이다(전북은 거의 전멸). 원인은 알고 있던 것이다 — TourAPI 숙박은 관광사업체 위주라 지방 숙소가 없어 인허가로 메웠는데(#144), 인허가엔 사진이 없다.

사진을 살 데가 마땅치 않다. 카카오·네이버 검색 API 는 좌표까지만 주고, 공식 API 로 숙소 사진을 주는 곳은 Google Places 뿐이다(유료·캐싱 제약). 이건 기술 선택이 아니라 비용 결정이었다.

Action — A안: 사진을 사는 대신 표현을 바꾼다

여행자가 숙소에 기대하는 건 사진보다 위치·예약인데 우리는 둘 다 못 준다. 사진까지 없으면 카드로 낼 이유가 없다.

사진 없는 슬롯을 지도로 넘긴다.

{ "kind": "STAY", "title": "올인모텔", "imageUrl": null, "tel": "054-...",
  "mapSearchUrl": "https://map.naver.com/p/search/의성군%20올인모텔" }

하지 않은 것

  • 지역 갤러리 사진으로 숙소 카드 채우기. 그 숙소 사진이 아니므로, 규칙이 막으려던 "채운 척" 을 다른 방식으로 하는 것일 뿐이다.
  • Google Places 연동. 유료이고 캐싱 30일 제한이 "미리 받아 DB 에 둔다" 는 우리 방식과 충돌한다.
  • 45곳을 서비스에서 빼기. 인구감소지역 89곳 추천이 서비스의 정의다.

Result

  • 사진 없는 숙소 카드가 빈 이미지 대신 행동할 거리를 갖는다.
  • 45곳 문제가 "사진이 없다" 에서 "사진 없이도 쓸 수 있다" 로 바뀐다.

남는 것 — 숙소 사진은 여전히 없다

이 PR 은 급한 불을 끈 것이고 사진 자체를 얻은 게 아니다. 다음에 붙일 후보를 조사해 이슈에 남겼다.

소스 사진 상태
전국농어촌체험휴양마을표준데이터 체험휴양마을사진 항목 있음 가장 유망 — 공공데이터라 저장·재배포 가능, 대상 지역이 겹친다
한국관광공사 고캠핑 확인 필요 별도 한도 1,000/일. 야영장 한정
전국농어촌민박업소표준데이터 없음 인허가 성격이라 사진이 없다

사진 항목이 있다는 것과 채워져 있다는 것은 다르다. 표준데이터는 지자체가 안 채우는 경우가 흔해, 붙이기 전에 채움률을 실측한다.

자문 셋 (CLAUDE.md)

  1. 운영에서 버티는가 — 응답 시점 문자열 생성. 테이블·조회 변화 없음.
  2. 한도를 갉아먹지 않나외부 호출 0. 키도 필요 없다.
  3. 코스가 나아지는가 — 후보 수는 그대로지만, 45곳에서 비어 있던 숙소 카드가 쓸 수 있는 것으로 바뀐다. 다만 사진 자체는 여전히 없어 완결은 아니다.

연관 이슈

- 슬롯마다 detailIntro2 를 부르면 코스 하나에 20건이 넘는다. 관광정보 한도가 하루 1,000이라
  코스 40개면 마른다. 운영시간은 콘텐츠에 붙는 값이고 거의 안 변하므로 콘텐츠당 한 번이면 된다.
- 일감 목록은 슬롯 테이블이다. 별도 큐를 두지 않는다 — 우리가 알아야 하는 콘텐츠는 정확히
  "코스에 실제로 쓰인 것" 이고 그건 이미 슬롯에 남아 있다. 큐를 만들면 두 곳이 되어 어긋난다.
- 하루 예산을 300(한도의 30%)으로 뒀다. 나머지는 사용자 요청과 장소 상세가 쓴다 — 이 배치가
  한도를 다 먹으면 정작 코스가 안 나온다.
- 값이 비어 와도 기록한다. 안 넣으면 매 회차 같은 콘텐츠를 다시 물어 예산을 태운다.
- 순차로 부른다. 병렬로 밀어붙이면 429 를 맞고, 그건 사용자 요청까지 막는다.
- 요청 경로에서 외부를 부르지 않는다. 받아 둔 것만 DB 에서 한 번에 읽는다(슬롯마다 읽으면 N+1).
- 슬롯이 콘텐츠 타입을 들고 있게 했다. detailIntro2 가 타입마다 다른 필드명을 써서
  (usetime·usetimeculture·opentimefood…) 타입 없이는 무엇을 읽을지 정할 수 없다. 생성 시점에는
  후보가 이미 들고 있는 값이라 추가 조회가 없다.
- 아직 안 받은 장소는 그냥 빈다. 화면은 있으면 보여주고 없으면 그 줄을 지운다 — 없는 것을
  지어내는 것보다 늦게 채워지는 편이 낫다.
- 같은 콘텐츠를 다시 받으면 덮어쓰는지 본다. 행이 늘면 어느 값이 최신인지 알 수 없다.
- 안 받은 콘텐츠는 키가 없는지도 본다 — null 을 주면 "값이 없다" 와 구분되지 않는다.
- 외부 실패가 배치를 죽이지 않는지, 오늘 이미 돌았으면 안 부르는지.
- 관광 API 가 운영시간·휴무일을 자유 텍스트로 준다. 클라이언트마다 파싱하면 클라이언트마다
  다르게 틀린다. 판정을 enum 으로 내려 한 곳에서 책임진다.
- 모르면 모른다고 한다. 실측(공주·정선 30건)에서 확실히 판정 가능한 것이 70% 였고, 계절별·
  복수시설 형식은 UNKNOWN 으로 둔다 — 30% 를 위해 70% 의 신뢰를 깎을 이유가 없다.
- 공휴일 예외 조항을 읽는다. `매주 월요일 (단, 공휴일은 정상운영)` 을 요일만 보고 판정하면
  공휴일 월요일에 "오늘 휴무" 라고 잘못 말해 갈 수 있는 곳을 안 가게 만든다.
- 휴무 판정이 시각 판정보다 먼저다. 문을 아예 안 여는 날에 "운영이 끝났어요" 라고 하면
  내일은 갈 수 있다는 뜻으로 읽힌다.
- Course.covers(LocalDate) 를 되살렸다. #247 에서 대기질을 걷어내며 호출자가 사라져 지웠는데,
  이 이슈가 그 호출자다.
- 지금 시각으로 내리는 판정이라 다음 주 코스에는 붙이지 않는다. 붙이면 사용자가 여행일
  상태로 읽는다.
- 원문(운영시간·휴무일)과 판정을 함께 낸다. 원문만 주면 클라이언트가 파싱해야 하고,
  판정만 주면 "몇 시까지 하는지" 를 못 보여준다.
- 공휴일 조회는 코스당 한 번이다. 슬롯마다 물으면 같은 날짜를 스무 번 묻는다.
- 공휴일 조회가 실패해도 코스는 나간다. 예외 조항 판정만 보수적으로 간다.
- 여기가 틀리면 사용자를 헛걸음시키거나 갈 수 있는 곳을 못 가게 한다.
- 공휴일 예외를 세 갈래로 본다 — 예외 있고 공휴일·예외 있고 평일·예외 없고 공휴일.
- 계절별·복수시설·특정일·자정 넘김이 전부 UNKNOWN 인지 확인한다.
- 숙박세일페스타만 슬롯 종류를 단정한다. 프로그램 이름이 곧 대상이고, 89곳 중 85곳에 걸려 있어
  대부분의 코스에서 숙박 슬롯에 배지가 붙는다.
- 나머지 여섯은 비워 뒀다. 프로그램 약관을 봐야 "이 장소에서 쓸 수 있나" 를 알 수 있는데 그
  데이터가 없다 — 지자체 바우처는 가맹점 목록이, 디지털관광주민증은 제휴처 목록이 필요하다.
  근거 없이 붙이면 사용자가 못 받는 할인을 기대하고 간다. 안 붙이는 것보다 나쁘다.
- 혜택을 새로 조회하지 않는다. 지역 혜택 매칭은 이미 끝나 있고, 그중 슬롯 종류를 단정할 수 있는
  것만 골라 자리를 옮긴다.
- 나머지가 슬롯을 단정하지 않는지 테스트로 잠갔다. 새 혜택을 추가할 때 근거 없이 슬롯을 붙이면
  여기서 깨진다.
- 감성 카피를 주는 외부 출처가 없다. 구석구석은 장소(contentId) 단위라 지역 문구가 없고, 관광
  API 에 지역 소개 엔드포인트가 없으며, RegionTag 는 정책 프로그램용뿐이다. 남는 선택은 89곳을
  사람이 쓰는 것인데 그건 실재하는 지역에 대한 주장이라 틀리면 그대로 사용자에게 나간다.
- 그래서 사실만 조합한다. 그 지역에 실제로 있는 국가유산·볼거리 이름을 쓴다 — 감성은 없지만
  틀리지 않는다.
- 종목 순서가 곧 대표성이다. 사적·명승을 보물보다 앞에 뒀다 — 보물에는 석탑·불상처럼 건물 안의
  작은 것이 많은데 사적·명승은 자리 자체가 목적지다.
- 조사를 받침으로 계산한다. `와(과)` 처럼 둘 다 적으면 화면이 어색해진다.
- 카드에 안 맞는 이름(길거나 `제2로 직봉 - …` 같은 구분자 포함)은 뺀다. 뺄 것이 많아 재료가
  없으면 소개를 안 만든다 — 어색한 문구보다 없는 편이 낫다.
- 부팅 때 한 번 조립한다. 재료가 배포 파일에서 오는 레퍼런스라 요청마다 89곳을 다시 만들 이유가 없다.
- 서비스 dto 가 소개를 들고 온다. 응답 DTO 가 provider 를 직접 부르면 그 지식이 두 곳에 생긴다.
- 재료가 없으면 필드 자체가 사라진다 — 화면이 빈 줄을 그리지 않는다.
- 숙소는 89곳 중 45곳에서 사진 있는 후보가 2곳도 안 된다. 인허가 데이터에 사진이 없고, 공식
  API 로 숙소 사진을 주는 곳은 유료뿐이라 이건 기술 선택이 아니라 비용 결정이었다.
- 사진을 사는 대신 표현을 바꾼다(A안). 사진 없는 카드를 그대로 두지 않고 지도로 넘겨 위치·
  사진·리뷰를 거기서 보게 한다. 비용 0 이고 89곳 전부에서 동작한다.
- 사진이 있으면 링크를 안 붙인다. 카드가 이미 설 수 있어 군더더기다.
- 지역 갤러리 사진으로 숙소 카드를 채우지 않는다. 그 숙소 사진이 아니므로, 규칙이 막으려던
  "채운 척" 을 다른 방식으로 하는 것일 뿐이다.
@sevineleven sevineleven added the feat 새 기능 (외부에 보이는 변화) label Aug 11, 2026
@sevineleven sevineleven self-assigned this Aug 11, 2026
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@sevineleven, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 72 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: d449a65f-896a-4f29-bb4f-e2d132c9cf88

📥 Commits

Reviewing files that changed from the base of the PR and between 080dfd4 and 4bfa65e.

📒 Files selected for processing (3)
  • src/main/java/com/offway/core/itinerary/controller/dto/CourseResponse.java
  • src/test/java/com/offway/core/common/logging/ResponseLogSummaryTest.java
  • src/test/java/com/offway/core/itinerary/controller/dto/SlotMapLinkTest.java

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sevineleven

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

- PoiIntroRepository 를 인터페이스로 바꾸고 SQL·JdbcTemplate 을 PoiIntroRepositoryImpl 로 옮겼다.
  service·provider 는 타입 이름이 그대로라 손대지 않는다
- 레포에는 두 선례가 있다. HeritagePoolSourceRepository·ExternalApiCallRepository 는 엔티티 없는
  JDBC 저장소인데 인터페이스가 없고, PlacePoolSourceRepository 는 같은 조건인데 port/adapter 로
  나뉘어 있다. 가른 기준을 "읽는 쪽이 어느 도메인인가" 로 잡았다 — 앞의 둘은 자기 도메인 안에서만
  쓰이지만 이것은 itinerary 의 OpeningHoursProvider 가 읽는다. 도메인 경계를 넘는 자리는 SQL 이 아니라
  계약에 기대야 한다
- ContentRef 는 조회 계약의 일부라 인터페이스 안에 둔다. 호출부 표기(PoiIntroRepository.ContentRef)가
  그대로라 부수 변경이 없다
- 빈 응답이 오면 poi_intro 에 빈 행이 남고, 일감 조회가 "행이 있으면 제외" 라 그 콘텐츠를 영영 다시
  묻지 않았다. 원본이 나중에 운영시간을 채워도 화면은 계속 빈 채로 굳는다
- 행을 안 남기는 쪽은 택하지 않았다. 그러면 매 회차 같은 콘텐츠를 다시 물어 하루 예산(300)을 빈 것들이
  다 먹는다. 이미 있는 fetched_at 으로 재시도 간격(7일)을 두는 쪽으로 풀었다 — 원본을 채우는 것은
  지자체 정보 갱신이라 일 단위로 바뀌지 않고, 늦어도 일주일 안에는 반영된다
- 값없음을 warn 으로 올렸다. info 로 묻으면 "적재 성공" 으로 읽혀 화면의 운영시간이 왜 비는지 아무도
  모른다
- 일감 조회에 순서를 넣었다. 재시도가 앞줄을 차지하면 아직 아무것도 없는 화면이 방치되므로
  한 번도 안 받은 것 → 최근 슬롯 순으로 준다. 예산이 유한할 때 무엇을 먼저 채우는지가 화면을 가른다
- 같은 조회의 DISTINCT 를 콘텐츠 id GROUP BY 로 바꿨다. 같은 콘텐츠가 타입이 다른 슬롯 둘에 실리면
  DISTINCT 는 두 줄을 주는데 poi_intro 는 콘텐츠당 한 행이라 예산만 두 번 썼다
- 다른 배치(GalleryPhotoRefresh·HubAttractionRefresh·RegionContentRefresh)도 훑었다. 그쪽은 빈 응답에
  이전 값을 유지하고 warn 을 남기고 있어 같은 문제가 없다
- 빈 응답·외부 실패 테스트가 미수집 슬롯을 만들지 않아 refresh() 가 빈 목록에서 곧바로 돌아왔다.
  count() >= 0 과 assertTrue(true) 는 그 상태에서도 통과해, 사실상 아무것도 잠그지 않았다
- 코스에 슬롯을 실제로 저장한 뒤(배치의 일감 목록이 slot 테이블이다) 결과를 단언하게 고쳤다.
  빈 응답은 null 운영시간 행이 남는지, 실패는 아무것도 안 남고 다음 회차가 같은 콘텐츠를 다시
  집는지 확인한다
- 빈 행이 재시도 기간 뒤 다시 일감이 되고 값이 채워지면 빠지는지를 새 테스트로 잠갔다
- 일감을 확인할 때 하루 예산이 아니라 상한 없는 목록을 본다. 예산으로 자르면 다른 테스트가 남긴
  슬롯이 앞자리를 차지했을 때 "일감에 없다" 가 참인지 잘려나간 것인지 구분되지 않는다
- 콘텐츠 id 는 UUID 로 매번 새로 만든다. 통합 테스트가 DB 를 공유해(클래스 @transactional 미사용)
  고정 id 를 쓰면 앞 테스트가 남긴 행이 시나리오를 바꾼다
@sevineleven

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

- RegionLandmarkRepository 를 인터페이스로 두고 JdbcTemplate 구현을
  RegionLandmarkRepositoryImpl 로 옮겼다. region 의 RegionIntroProvider 가
  trip 의 SQL 구현과 Spring JDBC 에 직접 묶여 있던 것을 계약으로 바꾼다
- 가른 기준은 #249 에서 정한 것과 같다 — 읽는 쪽이 어느 도메인인가.
  HeritagePoolSourceRepository 처럼 자기 도메인 안에서만 쓰는 JDBC 저장소는
  구체 클래스로 두지만, 도메인 경계를 넘는 자리는 SQL 이 아니라 계약에 기댄다
- adapter 를 infrastructure 가 아니라 repository 에 둔다. 이 레포에서
  infrastructure 는 외부 API 어댑터 자리이고(CLAUDE.md 도메인·외부 API 소유 표),
  영속 어댑터는 레포 전체가 *RepositoryImpl 로 통일돼 있다
- 계약(무엇을 주는가)은 인터페이스에, 구현 선택(종목 순위·질의 한 번)은 Impl 에
  나눠 적었다. 호출부는 표기가 그대로라 손대지 않았다
- PolicyType 이 들고 있던 SlotKind(itinerary) 를 policy 소유의 BenefitScope 로
  바꿨다. 정책이 코스 슬롯을 알면 policy → itinerary 의존이 생기는데,
  코스는 이미 정책을 참조하므로(GeneratedCourse.Benefit·CourseResponse)
  두 도메인이 서로를 가리키는 순환이 된다
- 대응(LODGING → STAY)은 SlotKind.covering 이 소유한다. "숙박세일페스타를
  숙소에서 쓴다" 는 프로그램의 성질이라 정책이 알지만, 그게 코스의 어느 자리인지는
  코스가 안다. CourseResponse 에 두지 않은 것은 다른 호출부(장소 상세)도 같은
  대응이 필요하기 때문 — DTO 에 있으면 재사용할 수 없다
- switch 가 BenefitScope 상수를 전부 덮으므로 새 대상이 생기면 코스 쪽에서
  컴파일이 깨진다. 자리를 정하지 않은 채로 넘어가지 않는다
- 상수 이름을 STAY 로 맞추지 않고 LODGING 으로 뒀다. 이름이 같으면 나중에
  valueOf(scope.name()) 로 "간단히" 만들 여지가 생겨 경계가 도로 사라진다
- policy → region(RegionTagType) 의존은 그대로 뒀다. region 은 policy 를
  참조하지 않아 순환이 아니고, 정책 매칭은 본래 지역 태그 위에서 도는 규칙이다
- intro 예시가 `탑리리 오층석탑와(과) ... 가운루가(이)` 였다. 조사를 받침으로
  계산하도록 RegionIntro 를 고치기 전에 적어 둔 문구가 남아 있던 것
- RegionIntro 는 종성을 보고 하나만 고른다 — 오층석탑(받침 O) 뒤에 `과`,
  가운루(받침 X) 뒤에 `가`. RegionIntroTest 가 잠그고 있는 형태와 같게 맞췄다
- 나머지 새 예시(useTime·restDate·openingStatus·benefit)도 함께 확인했다.
  CLOSED_TODAY 는 OpeningStatus 상수이고 "숙박 할인" 은 STAY_FESTA 뱃지 문구와
  같아 손댈 것이 없었다
- #255 가 다른 배치에 세운 가드가 이 배치에는 없었다. 로컬과 운영이 같은 data.go.kr 키를 쓰는데
  배치 건너뛰기는 자기 DB 안에서만 중복을 막아, 그대로 두면 두 곳이 각자 하루치를 태운다(#254).
- 새로 만든 배치라 dev 에 있던 그 가드를 못 받았다. 머지하면서 드러났다.
- offway.batch.regions-per-run 이 설정돼 있으면 그만큼으로 줄인다. 이 배치는 지역이 아니라
  콘텐츠 단위로 도는데, 값의 뜻은 "로컬 한 회차 상한" 이라 그대로 쓴다.
@sevineleven

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

- `연중무휴`·`상시개방` 을 find() 로 찾아 바로 확정하던 것이 문제였다. 실제로
  `연중무휴 (단, 설·추석 당일 휴무)` 가 설 당일에 OPEN 이 됐고,
  `매주 월요일, 1월 1일, 설·추석 당일` 은 화요일에 OPEN,
  `매주 월요일(공휴일인 경우 다음 날 휴무)` 도 확정으로 나갔다. 테스트로 8건 재현했다
- `SINGLE_RANGE` 의 `^\D{0,4}...\D{0,4}$` 도 같은 원인이었다. `하절기 09:00~18:00`
  `동절기 09:00~17:00` 이 계절 한정인데 단일 범위로 읽혀 확정됐다.
  범위가 둘 이상인 경우도 이제 UNKNOWN 이다
- **알아본 조각을 지우고 남은 글자가 없을 때만 확정한다**로 규칙을 바꿨다.
  위험한 문구를 골라 막으면(blocklist) 처음 보는 표현이 통과해 틀린 단정이 되지만,
  남기는 쪽을 나열하면(REST_OF_IT) 빠진 표현이 UNKNOWN 이 될 뿐이다 —
  틀린 단정이 침묵보다 나쁘다는 이 기능의 원칙과 같은 방향이다
- 그 대가로 `매주 월요일 휴관` 같은 정상 형식이 UNKNOWN 이 되지 않도록, 뜻을 안 바꾸는
  수식어·조사만 REST_OF_IT 에 열거했다. `단,` 은 공휴일 예외 패턴이 함께 먹게 했다 —
  남겨 두면 예외 조항을 알아본 보람이 사라진다
- 개점 전을 CLOSED_NOW("오늘 운영이 끝났어요") 로 말하던 것을 BEFORE_OPEN 으로 갈랐다.
  09시에 여는 곳을 08:59 에 보고 "운영이 끝났어요" 라고 하면 갈 수 있는 곳을 안 가게 만든다.
  UNKNOWN 으로 두지 않은 이유는 여는 시각을 읽어냈기 때문이다 — 모르는 게 아니라
  알고도 안 말하는 것이 된다. 문구는 "아직 문을 열기 전이에요"
- 쓰이지 않던 DAYS 상수를 지웠다
- isHoliday() 가 예외를 삼키고 false 를 돌려주는데 아무 흔적이 없었다. 그러면 공휴일
  월요일에 "오늘은 휴무일이에요" 가 나가도 아무도 모른다
- 코스 조회마다 찍으면 장애 동안 로그가 요청 수만큼 불어난다. HolidayProvider 가 실패를
  5분간 캐시하므로 그 창 안의 요청은 같은 실패를 즉시 돌려받는다 — 같은 간격으로 눌러
  창당 한 줄만 남기고, 창이 지나면 다시 남겨 장애가 계속되는 것도 보이게 했다
- 예외는 타입만 적는다. 스택·메시지는 HolidayProvider 가 실패 지점에서 이미 남겼고
  여기서 또 풀면 같은 장애가 두 번 쌓인다
@sevineleven

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 13, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

# Conflicts:
#	src/main/java/com/offway/core/itinerary/controller/dto/CourseResponse.java
#	src/main/java/com/offway/core/itinerary/service/OpeningHoursProvider.java
#	src/main/java/com/offway/core/itinerary/service/dto/GeneratedCourse.java
#	src/main/java/com/offway/core/trip/domain/OpeningHours.java
#	src/test/java/com/offway/core/common/logging/ResponseLogSummaryTest.java
# Conflicts:
#	src/main/java/com/offway/core/itinerary/controller/dto/CourseResponse.java
#	src/test/java/com/offway/core/common/logging/ResponseLogSummaryTest.java
Base automatically changed from feat/140-slot-benefit to dev August 13, 2026 15:30
sevineleven and others added 2 commits August 14, 2026 00:32
…tion

# Conflicts:
#	src/main/java/com/offway/core/itinerary/controller/dto/CourseResponse.java
#	src/main/java/com/offway/core/trip/repository/RegionLandmarkRepositoryImpl.java
#	src/test/java/com/offway/core/common/logging/ResponseLogSummaryTest.java
@sevineleven
sevineleven merged commit a3791ce into dev Aug 13, 2026
4 checks passed
@sevineleven
sevineleven deleted the feat/236-stay-presentation branch August 13, 2026 15:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat 새 기능 (외부에 보이는 변화)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

숙박 슬롯: 사진 있는 숙소가 89곳 중 45곳에 없다 — 사진 소스 또는 표현 변경

1 participant