Repository navigation
feat: 올리브영 오특(오늘의 특가) 조회 추가 - #331
Merged
Merged
Conversation
get_catalog에 service=oliveyoung, operation=today_deals를 추가해 오특 화면의 오늘의 브랜드 특가와 오늘의 특가 전체 목록을 한국 날짜 기준으로 반환합니다. - 오특은 JSON API 없이 HTML로만 제공되어 고정 경로·인수 검증과 카드 파서를 추가 - 브라우저 중계에 today-deals-page, today-deals-list 작업을 추가하고 정상 오특 HTML만 성공으로 감쌈 - get_catalog의 service 생략 호출은 기존처럼 세븐일레븐으로 유지 (공개 도구 10개 유지) - 보안 확인 화면·형식 변경은 빈 목록이 아니라 오류로 반환
Owner
|
감사합니다. 퇴근하면 보겠습니다...! |
Contributor
Author
|
@hmmhmmhm 감사합니다! 확인 후, 부족하거나 필요하신 부분 있으시면 말씀 부탁드립니다! |
오특 상품 카드의 일시품절 표시(status_flag soldout)를 soldOut 필드로 반환합니다. - 2026-10-27 화면에 일시품절로 표시된 실제 카드를 fixture로 추가 - outputSchema, 안내 문구, 서비스 문서와 분석 문서에 soldOut 반영
Contributor
Author
실제 화면 대조 결과 (2일 연속)
새로 확인한 점
|
Owner
|
감사합니다 |
6 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
변경 요약
올리브영 오특(오늘의 특가) 화면을 조회하는 기능을 제안하고 구현했습니다. 공개 도구를 늘리지 않고 기존
get_catalog에 작업을 하나 추가했습니다.오특 화면은 세 섹션으로 되어 있습니다. 이 PR에서는 가격과 상품번호가 있는 두 섹션을 구현했고, coming soon은 후속으로 제안합니다.
todayDealsGET /store/main/getHotdealPagingListAjax.do?date=YYYYMMDD&pageIdx=N&...(HTML 조각, 10개씩)brandDealsGET /store/main/getHotdealList.do페이지 HTML에 처음부터 포함관련 이슈
submit_request(개발자 요청)로 같은 기능 제안과 기여 의사를 먼저 전달했습니다 (요청 ID2c639517-4ffe-4827-86e5-236f44b1af8c).동작 방식
오특에는 JSON API가 없고 HTML로만 제공됩니다. 그래서 고정 경로와 고정 인수만 GET으로 읽고, 상품 카드 HTML을 파싱합니다. 원본 분석은
docs/oliveyoung-today-deals-analysis.md에 정리했습니다.상품마다 반환하는 값:
rank,goodsNo,name,brand,category,price,priceFrom(화면의 "원~", 옵션별 최저가),originalPrice,discountRate,flags(세일/쿠폰/증정/1+1 등),todayDelivery(오늘드림),imageUrl,productUrl정확도 원칙 (
ALIGNS.md)에 맞춰 처리한 부분:_cf_chl, "잠시만 기다려"), 다른 페이지, HTTP 200이 아닌 응답, 필수 값이 빠진 카드는 빈 목록이 아니라 오류로 반환합니다.check_inventory(service=oliveyoung)로 안내합니다.기능 제안: coming soon (다음 오특 예고)
화면 하단의 "잠시 후 12시 새로운 오특 오픈!" 배너는 같은 페이지 HTML(
.csBanInner .slideItem)에 들어 있습니다. 관측 결과는 아래와 같습니다.이번 PR에서 브랜드 특가 파싱에 쓰는 페이지 요청(
today-deals-page)을 그대로 재사용할 수 있습니다. 그래서 추가 원본 요청 없이upcomingDeals: [{ name, imageUrl }]정도로 확장할 수 있습니다. 가격이 없는 예고 정보라서 범위에서 제외했고, 필요하시면 후속 PR로 기여하겠습니다.체크리스트
npm run format:check통과: Windows CRLF 작업 트리에서는main에서도 25개 파일이 실패합니다.--end-of-line auto로 확인했고, 새 문서는 prettier로 정렬했습니다. CI 결과로 확인 부탁드립니다.npm run lint통과 (eslint, biome)npm run typecheck통과npm run check:source-lines통과 (최대 450줄)npm test통과: 이번 변경과 관련된 테스트는 모두 통과했습니다. 아래 "참고 사항"에 Windows 환경에서만 실패하는 테스트를 정리했습니다.docs/mcp-tools.md,docs/service-reference.md,docs/ai-instruction.md, 안내 프롬프트, 새 분석 문서)테스트 방법
단위 테스트
tests/services/oliveyoung/todayDeals.test.ts원~·오늘드림 미제공(B 상품번호)·1+1구분, 문자 참조, 필수 값 누락 거절, KST 자정, 마지막 페이지·빈 페이지·중복 제거·20페이지 잘림, 보안 확인 화면·HTTP201 실패, 중계 작업 이름과 본문, 전체 제한 시간tests/services/oliveyoung/htmlRoute.test.tstests/services/oliveyoung/tools/getTodayDeals.test.tstests/relay/browser.test.tstests/relay/oliveyoung.test.tstests/core/compact/tools.test.tsservice생략 시 세븐일레븐 유지,oliveyoung/today_deals연결, 잘못된 조합 거절, 내부 작업 45개 매핑새로 바꾼 파일(
todayDeals.ts,htmlRoute.ts,getTodayDeals.ts,transport.ts,compact/*,relay/browser.ts추가 분기)의 커버리지는 Statements/Branches/Functions/Lines 모두 100%입니다.실제 원본 통합 테스트 (2026-10-26 KST)
로컬에서 실제 MCP 서버(
/mcp) →get_catalog→ 로컬 브라우저 중계(createOliveyoungRelay+createBrowserRunner, Playwright 화면 브라우저) → 올리브영 경로로 호출했습니다. Cloudflare 보안 확인은 사람이 직접 통과했고 자동으로 우회하지 않았습니다.올리브영 직접 요청 실패오류로 반환되는 것을 확인했습니다.참고 사항
scripts/relay/*변경이 반영되어야 실제로 동작합니다.OY_RELAY_TRANSPORT=http)는 기존 JSON 경로 4개만 허용하므로 오특 작업은 실패로 반환합니다. 2026-10-11 기록상 HTTP 모드도 403이라 이번 범위에서 제외했습니다.oliveyoung_get_today_deals가 추가되어 내부 작업 매핑이 44개에서 45개가 됩니다. 공개 목록에는 노출하지 않고get_catalog로만 안내합니다. 구형 별칭과 같은 방식으로 등록되어[Deprecated]설명과replacement=get_catalog가 붙습니다. 다른 방식을 원하시면 맞추겠습니다.get_catalog스키마 변화:serviceenum(seveneleven,oliveyoung)이 선택 항목으로 추가되고operation은 계속 필수입니다.service를 생략한 기존 호출은 동작이 같습니다. PlayMCP 등록 스키마는 갱신이 필요할 수 있습니다.main의 fix: 올리브영 중계의 안전 복구와 의존성 보안 보완 #311~#330을 받아BrowserRequestError구조 위에서 오특 분기를 다시 적용했습니다. 오특 경로의 HTTP429도 기존 쿨다운 처리를 그대로 탑니다.npm test에서 16개 파일이 실패합니다. 13개는 이 변경 없이main에서도 같은 파일이 실패합니다(tests/relay/*의 macOS 운영용 테스트, 심볼릭 링크 권한 EPERM,cli-output-drain,health-runner,geocode-fallback). 나머지 3개(dtryx-start-cgv,oliveyoung-http-python,workers-chart-entrypoint)는 전체를 함께 돌릴 때 시간 초과로 실패하고 단독으로는 통과합니다. CI 결과로 확인 부탁드립니다.