8000 feat: 올리브영 다음 오특 예고와 오특 웹 조회 추가 by chuuminggg · Pull Request #362 · hmmhmmhm/daiso-mcp · GitHub
[go: up one dir, main page]

Skip to content

feat: 올리브영 다음 오특 예고와 오특 웹 조회 추가 - #362

Open
chuuminggg wants to merge 3 commits into
hmmhmmhm:mainfrom
chuuminggg:feat/oliveyoung-coming-soon
Open

chuuminggg wants to merge 3 commits into
hmmhmmhm:mainfrom
chuuminggg:feat/oliveyoung-coming-soon

Conversation

@chuuminggg
Copy link
Copy Markdown
Contributor

변경 요약

#331에서 후속으로 제안했던 오특 coming soon(다음 오특 예고)을 구현하고, /browse/quick에서 오특을 웹으로 조회할 수 있게 했습니다.

  • get_catalog(service=oliveyoung, operation=today_deals) 응답에 upcomingDeals, upcomingDealCount를 추가했습니다. 오특 페이지를 한 번 더 요청하지 않고, 이미 받은 페이지 HTML의 coming soon 배너를 파싱합니다.
  • GET /api/oliveyoung/today-deals를 추가했습니다. MCP와 같은 본문을 반환하며(buildTodayDealsBody 공유), Actions 정의에 등록되어 /browse/oliveyoung/today-deals 웹 조회가 자동으로 생깁니다.
  • /browse/quick 첫 화면에 "오늘의 올리브영 오특 보기" 링크를 추가했습니다. 읽기 세션 링크(/browse/read/{id}/oliveyoung/today-deals)로 이어지고, 결과는 브랜드 특가·오늘의 특가·다음 오특 예고가 상품명과 원본 이미지 카드로 보입니다.
  • 별도 커밋: Windows(core.autocrlf=true)에서 README가 CRLF로 체크아웃되면 tests/pages/discoveryEntry.test.ts가 실패하던 정규식을 \r?\n으로 고쳤습니다. Linux CI 동작은 같습니다.

관련 이슈

동작 방식

다음 오특 예고 (upcomingDeals)

배너(.comingSoonBan .slideItem)는 화면에서 숨겨져 있어도 페이지 HTML에 항상 들어 있습니다. 배너에는 상품명과 이미지만 있어 가격은 반환하지 않습니다.

필드 값
name 배너 <span> 텍스트
imageUrl 배너 background-image
goodsNo 썸네일 파일명에서 추출 (A00000020241475ko.jpg → A000000202414), 없으면 null
productUrl goodsNo가 있을 때만 상세 링크, 없으면 null
  • upcomingDeals는 예고일 뿐이라 예고 파싱 실패가 오특 본 조회를 실패시키지 않습니다. 대신 null(예고 미확인)과 [](예고 상품 없음)를 구분합니다.
  • 배너가 없거나, 항목 수와 분할 결과가 다르거나, 상품명·이미지가 빠진 항목이 있으면 일부만 반환하지 않고 null입니다.

오특 웹 조회

  • 캐시 5분(stale-while-revalidate 60초), 캐시 키에 한국 날짜를 넣어 자정 전후 응답이 섞이지 않게 했습니다. 오류 응답은 캐시하지 않습니다.
  • 원본 형식이 바뀌면 빈 목록 화면이 아니라 조회 실패로 보입니다 (브랜드 특가 섹션 변경 502 OLIVEYOUNG_TODAY_DEALS_PARSE_FAILED, 오특이 아닌 페이지 500).
  • OpenAPI 명세, /prompt 안내(8번 항목), docs/service-reference.md, docs/mcp-tools.md를 함께 갱신했습니다.

실데이터 확인

로컬 서버 → 로컬 브라우저 릴레이(headed Playwright, 보안 확인은 사람이 직접 통과) → 올리브영 원본 경로로 2026-11-03 20시대에 확인했습니다.

항목 결과
MCP get_catalog 오특 성공, 2026-11-03, 브랜드 5 / 오늘 26
다음 오특 예고 31개, 같은 브라우저 화면 배너 DOM 31개와 상품명·이미지 모두 일치
예고와 당일 오특 겹침 0/31 (다음 날 상품)
예고 goodsNo 31개 모두 추출, 표본 3개는 상품 검색 결과의 상품번호와 일치
/browse/quick → 오특 링크 200 조회 성공, 예고 카드 31/31 표시
/api/oliveyoung/today-deals 200, 본문이 MCP 응답과 동일
공개 도구 수 10개 유지

과거 관측: 2026-10-26 21:17 배너 31개는 10-27 오특 31개와 상품번호까지 모두 일치했습니다 (docs/oliveyoung-today-deals-analysis.md).

체크리스트

  • npm run lint, npm run lint:biome 통과
  • npm run typecheck 통과
  • npm run check:source-lines 통과
  • 관련 테스트 통과, 변경한 소스 파일 커버리지 100%
  • 문서 업데이트 (service-reference, mcp-tools, 오특 분석 문서)
  • 민감 정보 미포함 확인

참고 사항

  • upcomingDeals는 가격이 없는 예고입니다. 화면 표시 시간(대략 한국 시간 9시~자정)과 무관하게 HTML에 있으면 반환합니다.
  • 로컬 Windows 전체 테스트에서 실패하는 macOS 운영용 tests/relay/*, cli-output-drain, health-runner는 main과 목록이 같아 이 PR과 무관합니다.

@chuuminggg
chuuminggg requested a review from hmmhmmhm as a code owner November 3, 2026 13:07
@chuuminggg
8000
Copy link
Copy Markdown
Contributor Author

실데이터 확인 결과 (2026-11-03)

로컬 서버 → 로컬 브라우저 릴레이(headed Playwright, 보안 확인은 사람이 직접 통과) → 올리브영 원본 경로로 조회했습니다.

항목 결과
MCP get_catalog 오특 성공, 2026-11-03, 브랜드 5 / 오늘 26
다음 오특 예고 upcomingDeals 31개
같은 브라우저 화면의 배너 DOM 31개, 상품명·이미지 모두 일치
예고와 당일 오특 겹침 0/31
예고 goodsNo 추출 31/31, 표본 3개는 상품 검색(search_products) 상품번호와 일치
/browse/quick → 오특 링크 200 조회 성공, 예고 카드 31/31 표시
/api/oliveyoung/today-deals 200, 본문이 MCP 응답과 동일
공개 도구 수 10개 유지

상세 페이지 직접 확인은 올리브영 보안 확인 화면에서 멈춰 우회하지 않고, 상품 검색 결과로 대신 대조했습니다.

11-03 예고 상품 31개
# goodsNo 상품명
1 A000000234394 [11월올영픽] 얼터너티브스테레오 립 포션 카라멜 글레이즈 8ml
2 A000000225666 락토핏 다이어트 60포 (1개월분)
3 A000000268571 [호빵맨 콜라보] 스튜디오17 호빵맨 콜라보 5종 중 택 1
4 A000000198339 [블프특가/쫀쫀탄력] 바이오힐보 프로바이오덤 3D 리프팅 앰플 30ml [단품/증정기획]
5 A000000253446 [포켓몬 에디션] 오쏘몰 이뮨 ODP 7입 기획 (+파이리 카메라 키링+ 랜덤 마그넷) (7일분)
6 A000000185115 [1분진정] 브링그린 티트리 시카 트러블 수딩 토너패드 90매 (리필/단품)
7 A000000261918 산리오 캐릭터즈 레이니데이 인형키링 8종
8 A000000166296 [산리오 에디션/한교동]식물나라 보송/쿨링/워터프루프 선 스틱 3종
9 A000000231594 딜라이트 프로젝트 스낵 선물세트 택 1
10 A000000230160 [11월 올영픽] 오센트 행잉/샤쉐/패브릭 퍼퓸 8종 택 1
11 A000000150361 [NEW/단독컬러 출시] 홀리카홀리카 마이페이브 무드 아이 팔레트
12 A000000248829 [도경수 PICK] 이옴 트러블 패치 마스크 3매
13 A000000263745 [시나모롤 에디션] 유닉스 테이크아웃 무선고데기 플랫 기획/단품
14 A000000262995 [산리오콜라보] 투에이엔 러브 포켓 메이크업 키트 2종 중 택 1
15 A000001002235 [인보라 PICK/11월 올영픽] 바이오더마 시카비오 포마드 100ml 더블 기획
16 A000000262942 올리브영 UV 차단 경량 3단 암막 양우산 2종 (헬로키티/한교동)
17 A000000261234 [진정보호막] 헤브블루 살몬 케어링 센텔라 크림 100ml 기획 (+20ml+토너 25ml)
18 A000000232255 [올리브영 단독] 듀오버스터 민트볼 30입 더블기획
19 A000000259560 [11월 올영픽/NEW] MAC 러스터글래스 쉬어-샤인 립스틱 기획/단품
20 A000000180532 [블프특가]웨이크메이크 소프트 블러링 아이팔레트(단품)
21 A000000263033 [NEW] 바디판타지 오리지널 50ml 산리오 기획 (마이멜로디/한교동/포차코 실리콘 키링 증정)
22 B000000248530 스타우브 스테디아이템 20종 모음전 (꼬꼬떼/시스테라/아시아볼/베이비웍 외)
23 A000000240331 [이소원 PICK] 리핀 실내 고체탈취제 300g
24 A000000158965 나트라케어 울트라패드 3종 택 1 ( 소형 14P / 중형 12P / 대형 10P)
25 A000000185046 [11월 올영픽 /NEW 넛츠컬렉션 /OY단독컬러] 투크 워터프루프 슬림 아이라이너 15 colors (단품/기획)
26 A000000263542 피지오겔 사이언수티컬즈 데일리뮨 앰플 세럼 더블 기획 (+마스크1매)
27 A000000234422 [1위 원조 버블팩] 메노킨 30초 퀵 버블 마스크 6종 택1(+30ml 증정)
28 B000000268108 [호빵맨 콜라보]아리울떡공방 굳지않는 앙금가래떡 600g (+띠부씰)
29 A000000223207 AHC 마스터즈 아쿠아리치 선크림 50ml 1+1 기획
30 A000000110505 [10년 연속 약국 1등] 대웅제약 이지덤 스팟패치 단독 기획 택1 (퀵카밍/뷰티/PDRN/모공/릴리프) 트러블패치
31 A000000262620 [산리오캐릭터즈 콜라보] 아누아 어성초 포어 컨트롤 클렌징오일 350ml 포차코 기획(+리무버 패드)

남은 확인

coming soon 배너는 화면에 대략 한국 시간 오후 9시(21시)부터 공개됩니다. 이번 조회(20:27)는 공개 전이라 HTML에 들어 있던 배너를 읽은 것이므로, 공개 이후 배너가 다음 날 오특과 일치하는지는 21시 이후 조회와 다음 날 오특을 비교해 이어서 확인하겠습니다.

@chuuminggg
Copy link
Copy Markdown
Contributor Author

coming soon 매일 대조 cron 추가와 21시 이후 확인 (2026-11-03)

coming soon 배너는 화면에 대략 한국 시간 오후 9시(21시)부터 공개됩니다. 그래서 공개 이후 예고가 다음 날 오특과 같은지 매일 확인하도록 7458c7f에 workflow를 추가했습니다.

Oliveyoung Coming Soon workflow

한국 시간 cron (UTC) 동작
21:10 10 12 * * * 운영 /api/oliveyoung/today-deals의 upcomingDeals를 저장 (snapshot). 21시 전, 오늘이 아닌 날짜, upcomingDeals=null, 0개면 실패
00:20 20 15 * * * 전날 저장한 예고와 그날 오특(브랜드 + 오늘의 특가)을 상품번호로 대조 (compare). 빠지거나 추가된 상품이 있으면 실패하고 목록을 로그에 남김
  • 저장본은 Actions 캐시에 대상 날짜 키(oliveyoung-coming-soon-YYYY-MM-DD-…)로 넘깁니다. 전날 저장이 실패해 저장본이 없으면 같은 실패를 두 번 알리지 않도록 경고만 남깁니다.
  • 판정 로직은 scripts/ops/oliveyoung-coming-soon-check.ts(커버리지 대상, 100%), 실행 진입점은 scripts/ops/oliveyoung-coming-soon.ts입니다. OY_COMING_SOON_URL로 대상 서버를 바꿀 수 있습니다.
  • 배너 순서는 조회마다 바뀔 수 있어 순서는 비교하지 않습니다 (아래 관측).
  • 운영에 /api/oliveyoung/today-deals가 배포되기 전에는 workflow가 실패합니다.

21시 이후 실제 경로 확인 (22:33 KST)

로컬 Worker를 HTTP로 띄우고(로컬 브라우저 릴레이 → 올리브영 원본 8000 ) 위 snapshot 명령을 그대로 실행했습니다.

항목 결과
snapshot 실행 status=ok sourceDate=2026-11-03 targetDate=2026-11-04 upcoming=31
20:27 조회 예고와 비교 같은 상품 31개, 추가·누락 0개, 순서만 다름

다음 확인

이 22:33 저장본(대상 2026-11-04)과 11-04 실제 오특의 대조 결과는 11-04 오후 9시 이후 후속 코멘트로 남기겠습니다.

@chuuminggg
Copy link
Copy Markdown
Contributor Author

coming soon 다음 날 대조 결과 (2026-11-03 예고 → 11-04 오특)

어제 코멘트에서 이어서 확인했습니다. workflow와 같은 scripts/ops/oliveyoung-coming-soon.ts를 로컬 Worker(로컬 브라우저 릴레이 → 올리브영 원본)에 실행했습니다.

1. 11-03 22:33 저장본과 11-04 실제 오특 대조 (11-04 21:16 KST)

항목 결과
compare 실행 status=ok targetDate=2026-11-04 matched=31/31 deals=31
예고 상품 수 (previewCount) 31
11-04 실제 오특 (브랜드 + 오늘의 특가, dealCount) 31
상품번호 일치 (matched) 31/31
예고했지만 실제 오특에 없는 상품 (notInDeals) 없음
실제 오특에 있지만 예고에 없던 상품 (notInPreview) 없음

10-26 → 10-27 관측(31/31)에 이어 이번에도 coming soon 예고가 다음 날 오특 전체와 상품번호까지 일치했습니다.

2. 11-05 대상 예고 저장 (11-04 21:17 KST)

항목 결과
snapshot 실행 status=ok sourceDate=2026-11-04 targetDate=2026-11-05 upcoming=31
goodsNo 추출 31/31
전날(11-04 대상) 예고와 겹침 0

PR이 배포되면 이 대조는 Oliveyoung Coming Soon workflow가 매일 21:10 저장, 00:20 대조로 이어서 수행합니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

0