k-skill/docs/features/parking-lot-search.md
Jeffrey (Dongkyu) Kim e1656541a4
Fix parking lot lookups: force HTTPS, cache full dataset, normalize provider fields (#156)
Data.go.kr 이 tn_pubr_prkplce_info_api 를 HTTPS 로만 서비스하고 HTTP 요청은 301 로 리다이렉트하기 때문에 Node fetch 가 `response.ok=false` 로 떨어져 기능이 전체 실패하고 있었다. 이 커밋은 HTTPS 로 직접 호출하도록 수정하면서, 업스트림의 주소/지역 필터가 실제로는 동작하지 않고 페이지당 응답이 1000rows 기준 26s 에 달해 20s fetch timeout 에 꾸준히 걸리던 문제까지 함께 해결한다.

## What changed

- packages/k-skill-proxy/src/parking-lots.js
  - PARKING_LOT_API_URL 을 `http://` → `https://` 로 고정 (root cause).
  - 업스트림 address/geo 필터가 신뢰 불가하므로 full-dataset 을 한 번 로드해 프로세스 메모리에 6시간 TTL 로 캐시하고, 동시 호출자는 in-flight promise 를 공유하도록 한다. nearby 쿼리는 캐시된 행을 좌표 거리로 필터링해 서비스한다.
  - DATASET_PAGE_SIZE=300, fetch timeout 30s 로 페이지당 응답이 20s 를 넘기지 않도록 맞췄다.
- packages/k-skill-proxy/src/server.js
  - 더 이상 의미 없어진 numOfRows / maxPages 쿼리 파라미터를 라우트에서 제거하고, 응답 payload 의 query echo 도 정리했다.
- packages/k-skill-proxy/test/server.test.js
  - 새 캐시 기반 동작을 검증하는 테스트로 교체: (1) full dataset load + 좌표 필터 + 프록시 응답 캐시 재사용, (2) public_only 기본값 및 해제 시 동작, (3) 좌표 검증 실패 400, (4) 업스트림 키 미설정 시 503.
- packages/parking-lot-search/src/index.js
  - OFFICIAL_API_URL 도 HTTPS 로 맞춰 직접 호출 모드 사용자도 같은 버그를 밟지 않게 한다.
- packages/parking-lot-search/src/parse.js
  - 업스트림이 `insttCode` / `insttNm` (camelCase) 를 돌려주는데 parser 가 snake_case (`instt_code`, `instt_nm`) 만 인식해 providerCode/providerName 이 비어 있던 문제를 수정.
- packages/parking-lot-search/test/* 및 fixtures
  - HTTPS URL 매칭으로 업데이트하고, insttCode/insttNm 회귀 테스트를 fixture/assertion 에 추가.
- docs/features/parking-lot-search.md, parking-lot-search/SKILL.md, packages/parking-lot-search/README.md
  - 공식 endpoint 표기를 HTTPS 로 통일.
- .changeset/parking-lot-https-fix.md
  - parking-lot-search 패키지 patch 릴리즈 노트 추가.

## How it was verified

- `npm run ci` (lint + typecheck + tests + pack:dry-run) 통과.
- 로컬에서 실제 `DATA_GO_KR_API_KEY` 로 k-skill-proxy 를 기동해 live 호출 검증:
  - 광화문 (37.573713, 126.978338) cold cache: 30s 내 전체 18,868 rows 로드, 2km 내 47개 공영주차장 반환 (세종로 414m, 서린노외 456m 등).
  - 강남역 (37.497952, 127.027621) warm cache: 31ms 응답, 1.5km 내 13개 반환 (역삼문화공원 380m, 역삼푸른솔도서관 421m 등).
- 업스트림 직접 HTTPS 호출로 `resultCode=00 NORMAL_SERVICE` 정상 동작 확인.
2026-04-22 10:52:57 +09:00

2.2 KiB

근처 공영주차장 찾기

parking-lot-search 스킬은 사용자가 알려준 위치 기준으로 가까운 공영주차장을 찾는다.

핵심 원칙

  • 위치를 자동 추적하지 않는다. 먼저 현재 위치를 질문한다.
  • 기본 결과는 공영 주차장만 포함한다.
  • 데이터 출처는 공공데이터포털 전국주차장정보표준데이터 Open API다.
  • 실시간 잔여 주차면, 만차 여부, 예약 가능 여부는 공식 표준데이터에 없으므로 단정하지 않는다.

사용 예

현재 위치를 알려주세요. 동네/역명/랜드마크/위도·경도 중 편한 형식으로 보내주시면 근처 공영주차장을 찾아볼게요.

위치를 받으면 parking-lot-search 패키지 또는 k-skill-proxy /v1/parking-lots/search를 사용한다.

Node.js 예시

const { searchNearbyParkingLotsByLocationQuery } = require("parking-lot-search");

async function main() {
  const result = await searchNearbyParkingLotsByLocationQuery("광화문", {
    limit: 3,
    radius: 1500
  });

  console.log(result.anchor);
  console.log(result.items.map((item) => ({
    name: item.name,
    distanceMeters: Math.round(item.distanceMeters),
    feeInfo: item.feeInfo,
    basicCharge: item.basicCharge,
    mapUrl: item.mapUrl
  })));
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

Proxy endpoint

GET /v1/parking-lots/search?latitude=37.573713&longitude=126.978338&address_hint=서울특별시%20종로구&limit=3&radius=1500

응답은 가까운 주차장 목록, query echo, cache metadata를 포함한다. 운영 proxy에는 DATA_GO_KR_API_KEY가 필요하다.

모두의주차장

Issue #135에서 모두의주차장 연동 가능성이 언급되었지만 v1은 공식 공공데이터 기반으로 시작한다. 승인된 공식/파트너 API 계약이 확인되기 전에는 모두의주차장 비공식 API 호출이나 scraping을 하지 않는다.

참고 표면