buildrisk-radar

ADR-026 사업장 카드 — 지오코딩 없이 공시 주소의 법정동 · 지번을 실거래와 대조

배경 수주 · 보증 노출은 시군구 단위였다(ADR-016). 부동산 앱은 단지를, 신용평가사는 회사를 보는데 그 사이의 사업장을 보려면 공사 위치를 시군구보다 세밀하게 알아야 한다. 공급계약 공시의 판매 · 공급 지역은 ‘부산광역시 사하구 감천동 94-1번지 일원’처럼 법정동 · 지번까지 적힌 경우가 많다.

지오코딩을 쓰지 않은 이유 (공식 문서 확인)

결정

  1. 실거래 사전과 정확히 대조 — 받은 국토부 실거래(약 110만 건)의 (시군구 · 법정동 · 지번 · 단지)로 사전을 만들고, 공시 주소의 낱말을 그 공시가 해석된 화면 시군구의 일반구들 사전과만 대조한다(다른 구의 같은 동 이름에 끌리지 않음). 새 API · 키 · 저장 제약 없음.
  2. 모르면 고르지 않는다
    • JIBUN: 동 + 지번이 기존 단지와 일치 — 대부분 재건축 · 재개발 대상인 철거 전 단지라 화면에 그렇게 적음
    • UMD: 동 일치. 읍 · 면 지역은 ‘화원읍 천내리’(실거래 표기)로, 같은 이름의 리가 여럿이면 앞의 읍 · 면이 함께 있을 때만. 읍 · 면만 적힌 주소는 그 읍 · 면 전체
    • MULTI: 구간 · 여러 곳 공사(‘만덕동 ~ 재송동’, ‘당수동, 금곡동’) — 한쪽만 거래가 있어도 고르지 않음(단 한 읍 · 면 아래 리들의 구간은 그 읍 · 면 전체)
    • UMD_NO_TRADE: 동 · 읍 · 면 · 리 이름은 있으나 그 이름의 아파트 거래가 없음(농촌 · 산업단지) — 이름을 검증할 수 없어 비움
    • NONE: 시군구까지만 · 도로명주소
  3. 같은 정의 · 같은 기준 월 — 동 시장은 시군구 실거래 집계(ADR-015)와 같은 정의(해제 제외 거래, 해제 제외 ㎡당 중위가, 해제율)로, 기준 월은 그 시군구의 모든 일반구를 받은 마지막 달(mkt.region_stat)부터 최근 12개월 대 그 전 12개월.
  4. 저장 · 재해석 — dart.contract.site_*(V20). standardizeMetricJob 의 siteLocateStep 이 매일 전체를 다시 해석(실거래가 늘면 사전이 넓어지므로, 외부 호출 없음). API /companies/{c}/sites · /regions/{r}/sites(10분 캐시), 화면은 기업 수주·보증 탭과 지역 상세의 사업장 카드.

실데이터 결과 (2026-10-08, 현재 공급계약 653건 · 시군구 해석분)

결과 건수
동 · 지번까지 (JIBUN 20 · UMD 294) 314 (48%)
여러 곳 (MULTI) 105
동 거래 없음 (UMD_NO_TRADE) 69
시군구만 (NONE) 165

PF 사업장(ADR-024)은 원문 사업지역이 ‘서울시’ · ‘서울 마포구’ 수준이라 시군구까지만 잇는다. 해석 규칙을 고칠 때마다 전체를 다시 해석해 이전 결과와 건별로 비교했다 — 이 과정에서 ‘성수동1가’가 ‘성수동’에서 끊기는 회귀를 잡았다(VERIFICATION 99).

성능

동 시장 쿼리는 일반구 단위로 2년치 거래를 읽어 동 이름으로 거른다(계약이 가장 많은 기업 기준 약 60 ms, API 첫 호출 180~320 ms, 캐시 후 약 16 ms). (lawd_cd, umd_nm, deal_ym) 인덱스를 롤백되는 트랜잭션에서 재 보았으나 플래너가 쓰지 않아(64.7 → 61.3 ms) 넣지 않았다 — 읍 · 면 전체를 위한 OR … LIKE 조건 때문.

한계