Files
trex-core/docs/batches/bat-053_20260628_daystart-credential-fetch-failsafe/planning.md
T
genichinandClaude Sonnet 4.6 e4e5c70422 feat(bat-053): 그날-시작 KIS 인증정보 fetch + fail-safe 로드 (REQ-112~115)
REQ-112: BrokerCredentialPayload/TradingContext 데이터클래스 + PortfolioHubReadPort.fetch_broker_credential() 포트 메서드 + hub_read 어댑터(_fetch_user_info 헬퍼 추출) + stub_read 결정론 stub
REQ-113: DaemonInstanceConfig/DaemonConfig.credential_fetch_enabled opt-in(기본 False) + TOML 파싱 + break-glass(TREX_KIS_BROKER_BREAK_GLASS) 감지
REQ-114: SnapshotScheduler._maybe_fetch_credential() — fail-closed 3조건(unavailable/broker-null/trading_disabled) + CRITICAL 알람 DAY_START_LOAD_FAILED + IntentService entry_allowed_fn 게이트(BuyIntent 차단, SellIntent 통과)
REQ-115: 그날 고정 캐시(_cached_credential/_credential_date) — 동일 날짜 재fetch 방지 + app_secret 메모리 한정(Redis 미기록)

스텁 기반 구현: 실 portfolio-hub/네트워크 없이 AC 전부 단위 테스트.
회귀: credential_fetch_enabled=False(기본) 경로 byte-for-byte 보존.
745 passed, 47 skipped (0 failed).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
2026-06-28 11:00:18 +09:00

4.0 KiB

BAT-053: Planning

Scope Summary

그날-시작 시 portfolio-hub /v1/user_info에서 KIS 인증정보를 fetch하고, 실패 시 fail-closed로 신규 진입을 차단하며, 성공 시 그날 캐시로 KIS API 장중 연속성을 보장한다.

4개 REQ 모두 같은 delivery 단위:

  • REQ-112: 트랜스포트 계층 (포트 인터페이스 + HTTP 어댑터 + stub)
  • REQ-113: 설정 계층 (TOML opt-in + fetch/break-glass/env-only 우선순위)
  • REQ-114: 그날-시작 로드 게이트 (fail-closed + 알람 + BuyIntent 차단)
  • REQ-115: 그날 고정 캐시 + 장중 무중단 NFR

Task Breakdown

T1: REQ-112 — 포트/어댑터 계층

  • application/portfolio.py: BrokerCredentialPayload, TradingContext 데이터클래스 + PortfolioHubReadPort.fetch_broker_credential() 포트 메서드 추가
  • adapters/portfolio/hub_read.py: _fetch_user_info() 헬퍼 추출 + fetch_broker_credential() 구현
  • adapters/portfolio/stub_read.py: fetch_broker_credential() stub 추가
  • 테스트: tests/adapters/portfolio/test_hub_read.py AC-1~7, test_stub_read.py AC-6

T2: REQ-113 — 설정 계층

  • runtime/config.py: DaemonInstanceConfig.credential_fetch_enabled: bool = False + from_toml() 파싱
  • DaemonConfig.from_config() 또는 new helper: fetch/break-glass/env-only 우선순위 로직
  • 테스트: tests/runtime/test_instance_config.py AC-1~7(추가)

T3: REQ-114 + REQ-115 — 그날-시작 게이트 + 그날 고정 캐시

  • application/snapshot_scheduler.py:
    • run_once() 앞에 credential_fetch_enabled=True 경로에서 fetch_broker_credential() 호출
    • entry_allowed: bool in-process 상태 + _cached_credential: BrokerCredentialPayload | None + _credential_date: date | None
    • fail-closed 3 조건(PortfolioHubUnavailableError / broker None / trading_enabled False) → ERROR 로그 + CRITICAL 알람 DAY_START_LOAD_FAILED
    • 그날 고정 — 장중 재fetch 방지
  • application/alarm_emitter.py: DAY_START_LOAD_FAILED 알람 코드 추가(기존 패턴 재사용 — 실제로 코드 자체는 문자열이므로 사용처 추가)
  • application/intents.py (IntentService): entry_allowed 게이트를 BuyIntent admission에 추가
  • 테스트: tests/application/test_snapshot_scheduler.py AC-19 + REQ-115 AC-16
  • 테스트: tests/application/test_execution.py 또는 test_intent 계열 AC-4, AC-5

Design Gate

design.md 필요함(standard profile): 다음 판단이 필요.

  1. entry_allowed 상태를 어디에 보관할지: SnapshotScheduler 내부 vs 별도 DayStartState 객체 vs IntentService에 주입.
  2. IntentService에 entry_allowed 게이트를 어떻게 연결할지(생성자 주입 callable vs setter vs 공유 객체).
  3. credential_fetch_enabled 플래그가 False(기본)일 때 기존 경로 byte-for-byte 보존 검증 방법.
  4. 중장기 인스턴스(dcy-027)의 그날-시작 후크 위치 확인(현 코드에서 run_once() 위치 분석 필요).
  5. fetch_broker_credential() 반환값이 DaemonConfig.from_config()에서 KISConfig 재조립으로 이어지는 흐름 설계.

Risks

  • R1: IntentService에 entry_allowed 게이트를 연결할 때 기존 pass-through 테스트 회귀 가능성 → credential_fetch_enabled=False 기본 경로에서 게이트를 비활성화하면 회귀 방지
  • R2: app_secret 로그 노출 — 마스킹 로직 누락 주의
  • R3: stub_read.py의 stub이 포트 인터페이스와 불일치 → pytest import sweep으로 조기 발견
  • R4: REQ-113의 DaemonConfig.from_config() 변경이 기존 test_instance_config.py 회귀 유발 가능 → AC-1(opt-in off → env-only, fetch 미호출) 케이스가 핵심 회귀 가드

Dependencies

  • portfolio-hub REQ-049 (dcy-010): /v1/user_info 확장 계약 — 머지 완료(미배포). 스텁 기반으로 실 portfolio-hub 없이 구현.
  • REQ-099/100 (dcy-033, BAT-049): AlarmEmitter trex.alerts 계약 — 이미 구현됨.
  • REQ-019: ledger_outbox 무손실 — 기존 구현 재확인(REQ-115 AC-2).