# BAT-048 Planning - Status: confirmed - Batch: BAT-048 - Profile: standard ## Included REQ - REQ-095: 체결가 0/None 지정가 백필 가드 (슬롯 평단 + 원장 price) - REQ-096: 체결가 백필·0가격 통과 WARN 로깅 - REQ-097: 알람(alert) 능력 검토 스파이크 산출물 ## Delivery Plan REQ-095/096은 같은 코드 경로(`execution.py`)의 같은 함수들에 걸쳐 있어 분리 구현의 이점이 없다. 두 REQ를 묶어 구현한 뒤 테스트에서 값 정정(REQ-095)과 로그 가시성(REQ-096)을 동시에 검증한다. REQ-097은 design 산출물로 완결된다. 구현 순서(run-batch-implementation 기준): 1. **design 확정 사항 선행 (이 planning 이전 게이트)**: - 백필 결정 지점: application 단일화(후술 Design Gate). paper 브로커·dcy-021 재구성 경로 일관성 분석 후 팀장 승인. - 지정가 부재/≤0 최종 폴백 정책: 후보별 분석 → 팀장 승인 (design review 게이트). - REQ-097 알람 분석 산출물: design 문서 내 포함 → design review에서 사장님 결정. 2. **Phase A — `_on_filled` / `_on_partial_cancel` 백필 분기(REQ-095 AC-1/2) + WARN 로그(REQ-096 AC-1)**: - 두 함수 내 `fill_price = float(fs.avg_price) if fs.avg_price is not None else old_avg` 를 백필 헬퍼(`_resolve_fill_price`)로 추출. - `_resolve_fill_price(fs, slot)`: avg_price None/≤0 시 `slot.limit_price` 사용, 지정가도 없으면 폴백 정책 적용. - 백필 시 `_log.warning(...)` 발행(REQ-096 AC-1 필드 집합). 3. **Phase B — `_record_ledger` price 백필(REQ-095 AC-3) + WARN 로그(REQ-096 연동)**: - `price = float(fs.avg_price) if fs.avg_price is not None else 0.0` 라인을 `_resolve_fill_price` 결과로 교체. - 이미 Phase A에서 백필 WARN을 발행했으면 중복 WARN 없음; `_record_ledger` 진입 전에 백필 여부를 파악할 수 있는 컨텍스트 설계 필요 (design에서 결정). 4. **Phase C — 테스트 작성**: - `tests/application/test_execution.py`: AC-1~4(REQ-095) + AC-1~4(REQ-096) 커버. - avg_price=None, avg_price=0, happy_path(정상 양수), limit_price 부재 극단 케이스. - WARN 로그 발생 단언(`caplog` 사용). - 기존 execution 테스트 회귀 유지. 5. **Phase D — baseline 문서 갱신**: - `docs/runtime-flows.md` — 체결 처리 흐름에 백필 분기 추가. - `docs/operations.md` — 백필 WARN 발생 시 운영자 점검 절차. 선행 조건: Phase A~C는 설계 결정(백필 헬퍼 구조, `_record_ledger` 컨텍스트 패싱)이 확정되어야 시작 가능. ## Dependencies - Internal: - `trex_core/application/execution.py` — 변경 대상 핵심 파일(BAT-004에서 도입, 이후 지속 갱신) - `trex_core/adapters/broker/kis.py` — 읽기 참조만(백필은 application에서, adapter 불변) - `trex_core/adapters/broker/paper.py` — 읽기 참조만(paper는 `o.price`를 항상 양수로 반환 → 백필 분기 미진입 정상 케이스) - `tests/application/test_execution.py` — 기존 회귀 스위트 전체 통과 유지 필수 - dcy-029(BAT-045/046) — 구조화 로깅 인프라(`_log`, json formatter) 재사용 - External: - portfolio-hub `LedgerPort` — `price` 필드 타입(float) 불변, 값만 정정. HTTP 계약 변경 없음. - slots RPC(trex-orb-v1, trex-tsl-v1) — `avg_price` 필드 값이 0→정상값으로 바뀌는 것은 wire 계약 변경이 아님(NFR-1). trex-tsl-v1은 avg_price≤0 시 tier 무시 2% 폴백에서 정상 tier 평가로 자동 개선. ## Design Gate - Design Required Before Implementation: yes - Reason: - **백필 결정 지점 (Discovery R-2, REQ-095 Notes)**: adapter(kis.py)에서 처리 vs application(execution.py)에서 처리. paper 브로커·dcy-021 잔고 재구성 경로와의 일관성이 다르다. 설계 없이 구현하면 경로별 일관성 깨짐 리스크. design에서 단일 지점 확정 후 팀장 승인 필수. - **지정가 부재/≤0 폴백 정책 (Discovery OQ-2, REQ-095 AC-6)**: 재폴링 / 직전가 조회 / skip+강알림 등 후보별 구현비용·안전성이 다르다. 설계 확정 없이 구현하면 AC-6가 미완성이다. design review에서 팀장 확정 필수. - **`_record_ledger` 컨텍스트 패싱 설계**: Phase A 백필 결과(`fill_price`, `was_backfilled`)를 `_record_ledger`까지 전달하는 방법(파라미터 확장 vs 재계산)이 함수 시그니처를 변경할 수 있다. - **REQ-097 알람 스파이크 분석**: 알람 채널 후보 B(AMQP 이벤트)가 wire 계약 변경을 수반하는지 여부가 설계에서 확인되어야 한다. wire 변경 수반 시 즉시 팀장 보고·중단. - architecture impact가 `runtime-flows`(체결 처리 흐름 변경)이므로 standard profile design이 필요하다. ## Milestones 1. draft-batch-design 완료 — 백필 결정 지점, 폴백 정책, `_record_ledger` 컨텍스트 패싱, REQ-097 알람 분석 산출물 확정(팀장·사장님 design review 게이트) 2. run-batch-implementation 완료 — Phase A~D 신규 테스트 포함, 기존 execution 회귀 유지 3. draft-batch-verification 완료 — REQ-095/096 AC별 커버, REQ-097 산출물 제출 확인 4. QC reviewer 검증 대기 (confirm-batch-verification은 팀장 게이트) ## Risks - R-1(Medium): 지정가 백필이 추정치라 실제 체결가와 다를 수 있다. 완화: WARN + 추적 가능 플래그, 런북 명시. "0보다 합리적인 근사 + 추적 가능"이 목표(Discovery R-1). - R-2(Medium): 백필 결정 지점을 adapter로 두면 paper 브로커에도 동일 백필 로직 복제가 필요해진다. application 단일화가 권고. design에서 확정. - R-3(Low): `_resolve_fill_price` 헬퍼 추출 시 함수 시그니처 변경이 기존 테스트에 영향 가능. 완화: 기존 테스트 회귀 유지를 verification 기준으로 명시. - R-4(Low): 알람 후보 B 분석 중 wire 계약 변경 필요 여부가 나오면 즉시 중단·팀장 보고.