외부 연동 정비 TDD

Background

근거 PRD: /Users/biuea/Desktop/dpdpdndn/프로젝트/스포츠앱/외부 연동 정비/PRD.md (검수 PASS) 선행 ① 산출물 인용: ../도메인 경계 재설계/TDD.md, ../도메인 경계 재설계/ADR/ADR-002 도메인 관계 유형과 허용 의존 방향.md

sports-application은 외부 Open API를 이미 domain interface + infrastructure 구현 구조(Gateway 패턴)로 추상화했고, base-url+api-key를 env로 받아 코드 변경 없이 mock↔실연동을 전환하는 메커니즘이 동작 중이다(application.yml:132-148). 이 과제는 새 구현체 개발이 아니라 발급 주체별 무료 한도 조사 → 전환 판정 → 키 발급·env 설정 → 실 응답이 mock 스키마와 일치하는지 검증이다. 코드 변경은 최소(주로 설정·검증)로 제한한다.

Overview

  • 무엇을: (1) 발급 주체 3곳(카카오·공공데이터포털·SOLAPI) 무료 한도 조사표, (2) 전환 판정(일 1,000건 임계) 적용 결과, (3) 실 응답↔mock 스키마 일치를 자동 감시하는 계약 검증 테스트 하네스, (4) mock 영구 유지 분류(SOLAPI·PG), (5) 신규 외부 데이터 소스 3개+ 발굴.
  • : 전환 메커니즘은 존재하지만 “실행”된 적이 없고, 실 API 스키마 회귀를 감시하는 수단이 없다. 키를 발급해 env를 켠 뒤 실 응답이 mock DTO와 어긋나면 조용히 빈 결과가 반환된다(facility/geocoding은 graceful degradation).
  • 어떻게: 실 API를 CI에서 상시 호출하지 않는다(quota·키 노출 리스크). MockWebServer + 녹화 fixture로 Gateway HTTP 경로·역직렬화를 CI에서 상시 검증(스키마 락)하고, 실 키가 있을 때만 도는 live 태그 스모크 테스트를 opt-in gradle task로 분리해 1회성 실 응답 검증에 사용한다. 조사표·발굴·mock 유지 사유는 본 문서(Detail Design)가 SSOT다.

Terminology

용어정의
발급 주체(Issuer)API 키를 발급하는 포털/벤더 단위 — 카카오, 공공데이터포털, SOLAPI. 조사·전환 판정 단위
전환 판정 임계무료 API 일일 요청 한도 ≥ 1,000건이면 실연동 전환, 미만이면 mock 유지(PRD FR-2)
계약 검증(Contract Verification)실 API 응답 스키마가 Gateway DTO(mock 스키마 기준)와 일치하는지 검증하는 테스트
녹화 fixture실 API(또는 스키마 동일 mock) 응답 JSON을 1회 캡처해 CI 계약 테스트의 입력으로 고정한 파일
live 태그실 키가 env에 있을 때만 실 API를 호출하는 스모크 테스트에 부여하는 태그. 기본 test에서 제외
env 스위치base-url+api-key 환경변수. 키 부재→mock host(localhost:910x), 존재→실 API host
generic subdomain자체 소유 Entity 없이 외부 데이터를 조회·반환만 하는 도메인(weather) — ① TDD 분류 인용

Define Problem

AS-IS

실제 코드(backend/src/main/kotlin/com/sportsapp/)를 읽어 확인.

전환 메커니즘 (동작 중): application.yml:132-148에 4개 외부 config.

config 블록base-url env (기본값)api-key env (기본값)대응 GatewayImpl
external.geocoding (134)EXTERNAL_GEOCODING_BASE_URL (http://localhost:9101)KAKAO_REST_API_KEY (빈값)KakaoGeocodingGatewayImpl
external.public-facility (136)EXTERNAL_PUBLIC_FACILITY_BASE_URL (http://localhost:9102)DATA_GO_KR_SERVICE_KEY (mock-service-key)DataGoKrPublicFacilityGatewayImpl
external.weather (139)EXTERNAL_WEATHER_BASE_URL (http://localhost:9102)DATA_GO_KR_SERVICE_KEY (빈값)KmaWeatherGatewayImpl
external.sms (146)EXTERNAL_SMS_BASE_URL (http://localhost:9103)SOLAPI_API_KEY (mock-api-key)SmsChannelGateway
  • 각 GatewayImpl은 ExternalRestClientFactory.create(baseUrl)로 RestClient를 생성한다. Client는 GatewayImpl에만 DI됨(컨벤션 준수). 타임아웃 강제(connect 3s / read 5s, ExternalRestClientFactory.kt:28-29).
  • facility·weather 키 공유 확인: public-facility.api-key(138)와 weather.api-key(141)가 동일 ${DATA_GO_KR_SERVICE_KEY}. 키 1건으로 두 도메인 동시 전환(PRD FR-3). 단 기본값 비대칭 — public-facility는 mock-service-key, weather는 빈값.

실패 경로 불일치 (실측):

GatewayImpl외부 오류 처리근거
KakaoGeocodingGatewayImpltry/catch(RestClientException)null 반환(graceful)KakaoGeocodingGatewayImpl.kt:42-45
DataGoKrPublicFacilityGatewayImpltry/catch(RestClientException)emptyList() 반환(graceful)DataGoKrPublicFacilityGatewayImpl.kt:39-42
KmaWeatherGatewayImplcatch 없음 → 예외 그대로 전파KmaWeatherGatewayImpl.kt:31-46 (try/catch 부재)

→ 실 API 전환 시 기상청이 5xx/timeout을 내면 weather UseCase가 예외로 깨진다(facility/geocoding은 degrade). 전환 대상 도메인 간 실패 정책 불일치.

검증 수단 부재: Gateway HTTP 경로 통합 테스트가 없다. weather/gateway 테스트는 GridConverterTest.kt(좌표 변환 단위)뿐. facility gateway 통합 테스트 0건. 실 응답↔mock 스키마 회귀를 감시하는 테스트 없음. build.gradle.kts에 MockWebServer/WireMock 의존성 없음(Testcontainers mysql/mongodb/kafka만).

mock 서버 (스키마 정확): mock-servers/{kakao-local,data-go-kr,solapi}가 실 API 스키마를 모사. data-go-kr은 공공체육시설(/openapi/service/publicSportsFacility/getList) + 기상청 단기예보(/getVilageFcst) 2종을 동일 호스트로 서빙. mock-servers/README.md에 전환표 존재.

문제점:

  1. 발급 주체별 무료 한도·인증·전환 가부가 수치로 정리된 적 없음.
  2. 실 응답 스키마 회귀를 자동 감시하는 계약 테스트 없음 → 전환 후 조용한 빈 결과 리스크.
  3. weather 실패 경로가 나머지 두 gateway와 불일치.
  4. env 스위치 기본값 비대칭(weather api-key 빈값) — 전환표와 문서화 부재.
  5. 신규 외부 데이터 소스 발굴 미수행(PRD FR-4).

TO-BE

  • 발급 주체 3곳 조사표(존재·인증·일 한도·요금·상업 활용) + 전환 판정 결과.
  • MockWebServer + 녹화 fixture 계약 테스트로 3개 실연동 대상(공공체육시설·기상청 단기예보·카카오 지오코딩) 스키마를 CI에서 상시 검증(스키마 락).
  • 실 키가 있을 때만 도는 live 태그 스모크 테스트 + verifyExternalLive gradle task로 1회성 실 응답 검증.
  • weather 실패 경로를 facility/geocoding과 동일 graceful degradation으로 정합.
  • env 스위치 기본값 정합 + 전환 runbook·.env.sample 문서화.
  • mock 영구 유지 분류(SOLAPI·PG) 사유표 + 신규 데이터 소스 3개+ 발굴표.

Architecture Benchmarking (의무)

제품/사례해결 방식참고할 패턴미참고 사유
Twelve-Factor App — Config (12factor.net/config)환경별 설정을 코드가 아니라 env에 두고, 배포마다 값만 교체. 코드 무변경으로 backing service 전환① base-url+api-key를 env로 두고 코드 무변경 전환하는 AS-IS 원칙을 정당화 → 현상 유지 채택. ② mock↔real은 “같은 계약을 만족하는 attached resource 교체”로 해석12factor는 런타임 hot-reload를 규정하지 않음 — 우리도 env 반영은 롤링 재기동 수용(Release Scenario)
Consumer-Driven Contract / Pact + WireMock (pact.io, Baeldung Pact)소비자 기대를 concrete request/response 예시(contract-by-example)로 고정하고, provider 응답이 계약을 만족하는지 검증① “contract-by-example” — 실 응답 1건을 녹화 fixture로 고정해 스키마 회귀를 테스트로 락. ② WireMock류 로컬 HTTP 스텁으로 Gateway HTTP 경로·역직렬화를 실 네트워크 없이 검증Pact broker·provider verification(양방향 계약 인프라)은 개인 모놀리스 + 통제 불가 정부/벤더 API 상대로 과함 → 단방향 fixture 계약만 차용
Spring Cloud Contract stub-runner (spring.io/projects/spring-cloud-contract)계약 DSL로 stub을 생성·공유해 소비자/공급자 양쪽 검증계약을 코드로 실행 가능하게 만드는 fitness-function 관점만 참고stub 저장소·플러그인·Groovy DSL 체계가 무겁다. MockWebServer 직접 사용이 더 단순(단순함 우선) → 미채택

Possible Solutions

방안 비교

방안설명왜 채택 / 미채택
A. 순수 문서 + 수동 curl 검증조사표·runbook만 남기고 실 응답 검증은 수동 curl로 1회부분 채택 — 조사표·발굴·mock 유지 사유는 문서(본 TDD)가 SSOT. 단 수동 검증만으론 스키마 회귀를 지속 감시 못함 → B 병행
B. MockWebServer 녹화 fixture 계약 테스트(CI 상시) + live 태그 실 API 스모크(opt-in gradle task)fixture로 Gateway HTTP·역직렬화·매핑을 CI에서 상시 검증(키 불요). 실 키가 env에 있을 때만 verifyExternalLive task로 실 API 1회 호출해 동일 DTO 무손실 역직렬화 확인채택 — 스키마 락(회귀 감시) + 저빈도 실 검증(PRD NFR 정합). CI에 키 없음·quota 소모 없음. contract-by-example 벤치마크와 정합
C. Pact broker + provider verification계약 브로커에 pact 등록, provider CI가 검증미채택 — 정부/벤더 API는 우리가 provider CI를 붙일 수 없다. 브로커 인프라도 개인 프로젝트에 과함(단순함 우선)
D. WireMock record proxy 상시 캡처실 API 앞에 record proxy를 상시 두고 응답을 자동 캡처부분 참고 — fixture는 실 응답 1회 캡처로 seed(권장). 단 상시 proxy 운영은 복잡·불필요 → 미채택
E. 실 API를 CI에서 상시 호출매 빌드가 실 API를 호출해 응답 검증미채택 — quota 소모, CI에 키 노출, 정부 API 장애 시 플레이키. PRD NFR(“저빈도 호출”, “키 평문 노출 0”) 위반

단순함 우선 결론: A(문서 SSOT) + B(MockWebServer fixture 계약 테스트 + live 태그 opt-in). C·D·E는 과하거나 NFR 위반으로 미채택.

Detail Design

발급 주체 무료 API 전환 조사표 (FR-1, FR-2)

전환 판정 임계 = 무료 일일 요청 한도 ≥ 1,000건(PRD FR-2). 수치는 2026-07 조사 기준.

발급 주체API (서비스)존재인증 방식무료 일 한도요금(초과)상업 활용판정
카카오Local REST — 주소→좌표 (/v2/local/search/address.json)OAuthorization: KakaoAK {REST키} (header)100,000/day (좌표변환)초과분 유료(프로모션 건당 10원, 2026)조건부 허용전환 (≥1,000)
공공데이터포털기상청 단기예보 getVilageFcstOserviceKey (query)개발계정 10,000/day운영계정 승인 시 증량조건부 허용전환 (≥1,000)
공공데이터포털공공체육시설 목록 getListOserviceKey (동일 키 공유)개발계정 10,000/day 통상운영계정 승인 시 증량조건부 허용전환 (동일 키)
SOLAPISMS /messages/v4/sendOAuthorization (API키)한도 개념 아님(발송 건당 과금)건당 과금 + 발신번호 사전등록발신번호 필요mock 유지

판정 결과: 카카오(지오코딩 100k/day) + 공공데이터포털(단기예보·체육시설 각 10k/day) → 3개 서비스 전환. 공공데이터포털 키 1건 발급으로 facility·weather 동시 전환(FR-3). SOLAPI는 아래 mock 유지 표로.

참고 출처: Kakao Developers 쿼터, 공공데이터포털 기상청 단기예보, SOLAPI 발신번호.

mock 영구 유지 분류 (FR-5)

항목mock 유지 사유재검토 조건
SOLAPI SMS발신번호 사전등록 필요(개인 명의 인증 가능하나 실발송 건당 과금), 2026 스팸 발신번호 차단 정책, 개인 프로젝트 실발송 실익 없음사업자 발신번호 확보 시
PG 6사 (kakao·toss·naver·danal·bank_transfer·card)실 결제 연동에 사업자 가맹 계약 필요 — 개인 프로젝트 불가(PRD Non-Goals)사업자 계약 시

신규 외부 데이터 소스 발굴 (FR-4) — 발급 주체 재사용 우위 강조

3개 모두 공공데이터포털 발급 주체 → 이미 발급한 계정으로 활용신청만 추가하면 됨(신규 발급 주체 온보딩 불요). PRD Non-Goals에 따라 발굴·문서화까지이며 구현은 별도 과제.

#소스 (제공기관)발급 주체무료 일 한도스포츠앱 유즈케이스 연계상태
1에어코리아 대기오염정보 (한국환경공단)공공데이터포털개발계정 500/day야외 시설(축구장·테니스장) 조회/예약 시 미세먼지 지수 노출 → weather 도메인 부가정보 또는 facility 상세 보강발굴 대기
2전국체육시설 상세정보 (국민체육진흥공단, 15113986)공공데이터포털개발계정 통상 10,000/day현재 공공체육시설 목록보다 상세(면적·수용인원·좌석·관리기관) → facility Aggregate 상세 보강발굴 대기
3기상청 초단기실황 getUltraSrtNcst (기상청)공공데이터포털개발계정 10,000/day단기예보(6시간 단위)를 보완하는 실시간 현재 날씨 → weather 조회 정밀화. 기존 단기예보와 동일 계열 서비스로 키 재사용발굴 대기
(보너스)생활체육 강좌정보 (국민체육진흥공단)공공데이터포털개발계정지역 생활체육 강좌 → post/booking 확장 아이디어발굴 대기

참고 출처: 에어코리아 대기오염정보, 국민체육진흥공단 전국체육시설 정보.

시스템 역할 경계 (의무)

신규 도메인·신규 서버 없음. 기존 facility·weather infrastructure + 공통 test 하네스에 작업이 합류한다.

단위역할소유 데이터/책임노출 인터페이스의존
KakaoGeocodingGatewayImpl (infra/facility)주소→좌표 (실/mock 전환)무소유(조회)GeocodingGateway.geocode(address)RestClient, GeocodingProperties
DataGoKrPublicFacilityGatewayImpl (infra/facility)공공체육시설 목록 조회무소유(조회)PublicSportsFacilityGateway.fetchPage(pageNo,numOfRows)RestClient, PublicFacilityProperties
KmaWeatherGatewayImpl (infra/weather)단기예보 조회 (실패 경로 정합 대상)무소유(조회)WeatherGateway.shortForecast(lat,lng)RestClient, WeatherProperties
ExternalContractSupport (test 신규, infra/external test)계약 테스트 공통 하네스 — MockWebServer 기동·fixture 로더·live 태그 스킵 판정테스트 fixture 규약MockWebServer 세팅 헬퍼, requireLiveKey(envName)okhttp MockWebServer
verifyExternalLive gradle task (build.gradle.kts)live 태그 스모크만 실행하는 opt-in 태스크태스크 정의./gradlew verifyExternalLiveKotest tag filter
env 스위치 config (application.yml + 3 Properties)mock↔real 전환 스위치설정값ConfigurationPropertiesenv

서버 토폴로지 판단: 신규 워커·스케줄러·소켓 서버 없음. 단일 API 서버 유지. 근거 — 이 과제는 설정·검증·조사이며 신규 런타임 처리가 없다. 대량 조회 트래픽은 상시 트래픽 시뮬레이터가 계속 mock을 사용(PRD Non-Goals)하므로 실연동 API에 부하 서버가 필요 없다. 실 응답 검증은 test-time(CI fixture) + 개발 머신 1회성 gradle task로 충분.

바운디드 컨텍스트 판단: 신규 도메인 분리하지 않음 → 기존 facility·weather에 합류. 근거 — 이 작업은 독립 라이프사이클·독립 데이터 소유가 없는 “기존 Gateway의 검증·설정”이다. 신규 데이터 소스는 발굴만 하고 구현하지 않으므로(Non-Goals) 도메인/Gateway 신설도 없다. ① TDD 컨텍스트 맵을 변경하지 않는다(facility=코어, weather=지원/generic subdomain 유지).

인터페이스 시그니처 — 계약 테스트 대상 (동결 확인)

계약 테스트는 아래 domain interface 시그니처를 통해 GatewayImpl을 호출한다. 시그니처 변경 없음 — 검증만 추가.

// domain/facility/gateway/GeocodingGateway
fun geocode(address: String): Coordinate?          // 실패·미스 시 null

// domain/facility/gateway/PublicSportsFacilityGateway
fun fetchPage(pageNo: Int, numOfRows: Int): List<PublicFacility>   // 실패 시 emptyList

// domain/weather/gateway/WeatherGateway
fun shortForecast(lat: Double, lng: Double): Forecast              // 실패 시 빈 Forecast (BE-03에서 정합)

신규 test 하네스 시그니처(BE-01 확정):

// test infrastructure/external/ExternalContractSupport
fun startMockServer(): MockWebServer                       // fixture 응답 enqueue용
fun loadFixture(path: String): String                      // test/resources/fixtures/external/** 로드
fun requireLiveKey(envName: String): String?               // null이면 live 스펙 스킵(태그 기반)

실패 경로·동시성·멱등 (시니어 관점)

상황현재TO-BE 결정
외부 타임아웃/네트워크 오류geocoding→null, facility→emptyList, weather→예외 전파weather도 graceful degradation(빈 Forecast)로 정합(BE-03). connect 3s/read 5s 타임아웃은 유지
5xx / quota 초과(data.go.kr resultCode≠00)미검사 (역직렬화 실패 시 빈 결과)계약 테스트에 resultCode≠00·빈 items 케이스 추가(BE-02/03) — degrade 동작 검증
재시도없음(단일 시도)추가하지 않음 — 개발용 저빈도 호출이라 재시도 불요(단순함 우선). Observability 대시보드(별도 과제)로 실패율만 관측
멱등조회 전용 GET자연 멱등 — 별도 멱등 키 불요. SMS(POST)는 mock 유지라 무관
동시성조회 전용, 공유 상태 쓰기 없음락 불요

상태 전이 표

이 과제는 도메인 상태 머신을 추가하지 않는다(조회·설정·검증). 유일한 준-상태는 env 스위치 상태다.

현재 상태 × 이벤트다음 상태비고
mock(키 부재) × api-key env 주입 + 재기동real(실 API host)base-url도 실 host로 함께 교체 필요
real × api-key env 제거 + 재기동mock(localhost:910x)롤백 경로
mock/real × 무효 키로 real 전환real(degrade)401/403 → graceful 빈 결과(geocoding null / facility·weather empty)

Component Diagram (Mermaid flowchart LR)

flowchart LR
    subgraph Domain["domain (facility·weather)"]
        GG["GeocodingGateway"]
        PF["PublicSportsFacilityGateway"]
        WG["WeatherGateway"]
    end
    subgraph Infra["infrastructure"]
        KG["KakaoGeocodingGatewayImpl"]
        DG["DataGoKrPublicFacilityGatewayImpl"]
        KM["KmaWeatherGatewayImpl"]
        RF["ExternalRestClientFactory"]
    end
    subgraph Ext["외부/mock"]
        MW["MockWebServer (계약 테스트)"]
        RA["실 API / mock host"]
    end
    KG -.implements.-> GG
    DG -.implements.-> PF
    KM -.implements.-> WG
    KG --> RF
    DG --> RF
    KM --> RF
    RF --> RA
    RF --> MW

Sequence Diagram — 계약 검증 (CI fixture + live 스모크)

sequenceDiagram
    participant T as ContractTest
    participant S as ExternalContractSupport
    participant M as MockWebServer
    participant G as GatewayImpl
    participant R as 실 API
    T->>S: loadFixture(recorded.json)
    T->>M: enqueue(fixture)
    T->>G: geocode/fetchPage/shortForecast
    G->>M: HTTP GET
    M-->>G: fixture 응답
    G-->>T: 도메인 객체 (스키마 락 검증)
    Note over T,R: live 태그 스펙 (opt-in)
    T->>S: requireLiveKey(env)
    S-->>T: 키 없으면 스킵
    T->>G: (실 host) 호출
    G->>R: HTTP GET
    R-->>G: 실 응답
    G-->>T: 무손실 역직렬화 확인

ERD

이 과제는 스키마를 변경하지 않는다(설정·검증·조사 전용). 신규 테이블·컬럼 없음 → 해당 없음. env 스위치 상태는 위 “상태 전이 표” 참조.

Testing Plan

계약 검증 테스트가 중심이다. 신규 비즈니스 로직은 weather 실패 경로 정합 1건뿐.

레벨대상범위도구
infrastructure (신규)3개 GatewayImpl 계약 검증fixture 역직렬화·매핑·HTTP 경로가 mock 스키마와 일치Kotest + MockWebServer(okhttp)
infrastructure (신규, live 태그)3개 GatewayImpl 실 API 스모크키 존재 시 실 응답 무손실 역직렬화 (opt-in verifyExternalLive)Kotest tag + 실 env
infrastructure (신규)KmaWeatherGatewayImpl 실패 경로5xx/timeout/빈 items → 빈 Forecast degradeKotest + MockWebServer
domain/application/presentation신규 로직 없음 → 신규 테스트 없음

핵심 실패 경로 시나리오(테스트가 잡아야 하는 것):

  • 카카오 실 응답 documents[].x/y 필드가 mock과 동일 → Coordinate(lat=y, lng=x) 정확 매핑. documents 빈 배열 → null.
  • data.go.kr 실 응답 response.body.items.item[]PublicFacility 매핑. resultCode≠00 또는 5xx → emptyList degrade.
  • 기상청 실 응답 category(TMP/SKY/PTY/POP/REH/WSD) 그룹핑 → ForecastSlot. 5xx/timeout → Forecast(정합 후). 빈 items → 빈 Forecast.
  • live 스모크는 키 부재 시 스킵되고 CI를 붉게 만들지 않는다.

Release Scenario — 무중단 배포 (의무)

이 과제의 코드 변경은 3종이며 모두 런타임 하위 호환이다.

  1. 계약 테스트 추가 — 런타임 무영향(테스트 전용). 단일 PR 배포.
  2. weather 실패 경로 정합 — happy-path 동작 불변. 실패 시 예외 대신 빈 Forecast 반환(더 안전). 하위 호환.
  3. env 스위치 config 정합 — env 우선이므로 프로덕션 값에 영향 없음. weather api-key 기본값을 public-facility와 동일 규약으로 맞추는 것뿐.

env 전환(mock→real) 무중단 절차 — expand-contract:

  • expand: KAKAO_REST_API_KEY·DATA_GO_KR_SERVICE_KEY와 실 base-url env를 배포 환경에 추가(기존 인스턴스는 아직 mock 기본값 → no-op).
  • switch: 인스턴스를 롤링 재기동해 실 host 반영(ConfigurationProperties는 hot-reload가 아니므로 재기동 필요). 블루그린/롤링으로 무중단. 전환 조건 = verifyExternalLive가 실 응답 무손실 역직렬화 확인.
  • contract: 전환 확정 후 mock 서버는 개발·시뮬레이터용으로 계속 유지(제거하지 않음 — 시뮬레이터가 mock 사용).
  • 롤백: 실 API 이상 시 실 base-url/api-key env 제거 후 재기동 → mock host 복귀. env 존재 여부가 피처 플래그 등가. weather 실패 경로/계약 테스트 변경은 커밋 revert(런타임 무영향).

Observability (조건부 — PRD Operations)

  • 실연동 전환 API의 호출 실패율·레이턴시를 옵저버빌리티 대시보드에 노출(별도 과제 옵저버빌리티 스택 도입과 조율). 이 과제는 지표 소스(gateway 실패 로그 — 이미 logger.warn)만 확인하고 대시보드 구성은 위임.
  • 무료 API 일 한도 80% 도달 알림은 별도 과제(지능형 장애 알림) 채널과 조율(PRD Operations). 이 과제 범위 밖.

Open Questions

  • (PRD Open Q1) 신규 발굴 소스의 실제 기능 개발 여부·편입 과제 → 보류. 발굴표까지가 이 과제. 에어코리아·초단기실황은 weather 도메인 확장 후보로 기록.
  • (PRD Open Q2) 전환 임계 1,000건 적정성 → 실 사용량 관측(옵저버빌리티) 후 재조정. 현재 조사 대상 무료 한도(10k~100k)가 임계를 크게 상회해 판정에 영향 없음.
  • 녹화 fixture를 실 응답으로 seed할지 mock 응답으로 seed할지 → 실 응답 1회 캡처 권장(키 발급 후). 키 발급 전에는 스키마 동일한 mock 응답으로 seed하고, verifyExternalLive 최초 실행 시 실 응답과 대조해 승격.

Document History

날짜변경 내용
2026-07-03최초 작성 — 실측 AS-IS(env 스위치 4블록·키 공유·weather 실패 경로 불일치·검증 부재), 발급 주체 조사표, 전환 판정(1,000건 임계), MockWebServer fixture 계약 검증 + live 태그 설계, mock 유지 분류, 신규 소스 3+ 발굴, 무중단 전환 절차