8000 fix: 이마트24 재고 조회를 공식 v3 경로로 전환 by hmmhmmhm · Pull Request #270 · hmmhmmhm/daiso-mcp · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions docs/emart24-app-scraping-replay-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
- 상품 검색: `POST /stock/stock/search`
- 상품별 재고 조회 준비: `POST /api/stock/v1/search/keyword`
- 상품 기본 재고 메타: `GET /api/stock/v1/stock/goods/{pluCd}`
- 매장별 재고 수량: `GET /api/stock/v2/stock-search/store`
- 매장별 재고 수량: `GET /api/stock/v3/stock-search/store`
- 매장 상세: `GET /api/stock/stock/store/{bizNo}`

베이스 URL:
Expand Down Expand Up @@ -80,7 +80,7 @@ curl -sS 'https://everse.emart24.co.kr/api/stock/v1/stock/goods/8800244010504' \
### D. 매장별 재고 수량 조회

```bash
curl -sS 'https://everse.emart24.co.kr/api/stock/v2/stock-search/store?searchPluCode=8800244010504&bizNoArr=28339%2C05015%2C23233%2C29512%2C24437%2C29109%2C26137%2C29796%2C30200%2C28057%2C27928%2C29570%2C30162%2C28187%2C22579%2C00367%2C28967%2C00737' \
curl -sS 'https://everse.emart24.co.kr/api/stock/v3/stock-search/store?searchPluCode=8800244010504&bizNoArr=28339%2C05015%2C23233%2C29512%2C24437%2C29109%2C26137%2C29796%2C30200%2C28057%2C27928%2C29570%2C30162%2C28187%2C22579%2C00367%2C28967%2C00737' \
-H 'x-requested-with: XMLHttpRequest' \
| jq '{
goods: .storeGoodsInfo | {pluCd,goodsNm,viewPrice},
Expand Down Expand Up @@ -133,7 +133,7 @@ jq -r 'select(.request.path|test("^/api/stock|^/stock/stock/search")) | [.reques

- `emart24_check_inventory`
- 소스:
- `GET /api/stock/v2/stock-search/store` (매장별 수량)
- `GET /api/stock/v3/stock-search/store` (매장별 수량)
- `GET /api/stock/stock/store/{bizNo}` (매장 상세)
- 조합 키: `BIZNO`(매장), `PLU_CD`(상품)

Expand All @@ -150,3 +150,11 @@ jq -r 'select(.request.path|test("^/api/stock|^/stock/stock/search")) | [.reques
3. DNS/네트워크 실패

- 실행 환경 네트워크 정책(샌드박스/사내망) 확인

## 8. 2026-10-15 공식 공개 재고 계약 확인

공식 [재고확인 페이지](https://everse.emart24.co.kr/stock/stock/search)의 inline `fn_getStoreListForGoods`는 현재 `GET /api/stock/v3/stock-search/store`를 호출한다. 파라미터는 `searchPluCode`와 `bizNoArr`이며 HTTP 메서드·호스트·파라미터 이름은 기존과 같다. 연결된 [stockUtil.js](https://everse.emart24.co.kr/assets/js/stock/stockUtil.js)는 `storeGoodsQty` 배열의 `BIZNO`와 `BIZQTY`를 처리한다. 이 문서의 재고 조회 예제도 v3로 갱신했다.

확인 당일 v3 원본 1건에서 HTTP 200, `storeGoodsInfo` 객체와 `storeGoodsQty` 배열을 확인했고 기존 엄격한 응답 스키마를 통과했다. 요청한 상품 코드·매장 코드가 일치하는 행의 숫자 수량 0도 확인했다. 이는 해당 조회의 실제 응답이며 전체 매장이나 상품이 품절이라는 뜻은 아니다.

앞선 v2 조회는 HTTP 200이어도 `storeGoodsInfo`·`storeGoodsQty`·`storeInfo`가 문자열이고 내부 JSON은 숫자여서 정상 재고 객체·배열이 아니었다. 이 응답은 재고 미확인이며 빈 배열이나 0으로 바꾸면 안 된다. v3 전환은 공통 경로 상수만 변경하며 인증 헤더·파라미터·응답 스키마·실패 처리·캐시 정책은 유지한다. 접근 제한이나 알 수 없는 수량은 계속 명시적인 실패 또는 미확인으로 처리한다.
2 changes: 1 addition & 1 deletion src/services/emart24/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ export const EMART24_API = {
EVERSE_BASE_URL: 'https://everse.emart24.co.kr',
STORE_PATH: '/api1/store',
PRODUCT_SEARCH_PATH: '/stock/stock/search',
STOCK_SEARCH_STORE_PATH: '/api/stock/v2/stock-search/store',
STOCK_SEARCH_STORE_PATH: '/api/stock/v3/stock-search/store',
STORE_DETAIL_PATH_PREFIX: '/api/stock/stock/store/',
} as const;
5 changes: 3 additions & 2 deletions tests/relay/emart24.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ describe('이마트24 고정 HTTP 중계', () => {
{ searchPluCode: '8801115139836', bizNoArr: '00940' },
{
storeGoodsInfo: { pluCd: '8801115139836' },
storeGoodsQty: [{ BIZNO: '00940', BIZQTY: '0' }],
storeGoodsQty: [{ BIZNO: '00940', BIZQTY: 0 }],
},
'https://everse.emart24.co.kr/api/stock/v2/stock-search/store',
'https://everse.emart24.co.kr/api/stock/v3/stock-search/store',
],
[
'emart24-store-detail',
Expand All @@ -85,6 +85,7 @@ describe('이마트24 고정 HTTP 중계', () => {
const [url, init] = fetcher.mock.calls[0] as unknown as [URL, RequestInit];
expect(url.href.split('?')[0]).toBe(path);
expect(init.method).toBe('GET');
if (operation === 'emart24-stock') expect(Object.fromEntries(url.searchParams)).toEqual(body);
expect(init.body).toBeUndefined();
});
it('임의 URL·경로·필드와 인증 없는 호출은 원본을 호출하지 않는다', async () => {
Expand Down
10 changes: 10 additions & 0 deletions tests/services/emart24/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,16 @@ describe('searchEmart24StockByStores', () => {

expect(result.storeGoodsQty).toHaveLength(1);
expect(result.storeGoodsQty?.[0].BIZNO).toBe('28339');
const [input, init] = mockFetch.mock.calls[0] as [string, RequestInit];
const endpoint = new URL(input);
expect(endpoint.origin).toBe('https://everse.emart24.co.kr');
expect(endpoint.pathname).toBe('/api/stock/v3/stock-search/store');
expect(Object.fromEntries(endpoint.searchParams)).toEqual({
searchPluCode: '8800244010504',
bizNoArr: '28339',
});
expect(init.method).toBe('GET');
expect(init.body).toBeUndefined();
});
});

Expand Down
Loading
0