Files
trex-core/docs/batches/bat-023_20260608_ledger-cash-position-writeback-option-d/implementation.md
T
genichinandClaude Opus 4.8 2bfecd59a8 feat(ledger): dcy-018 option D cash/position write-back + 추정 현금 (BAT-023)
ledger write 응답의 portfolio-hub 권위 cash/quantity 를 스냅샷에 write-back 해
매수/매도 직후 "수량 live·현금 stale" 비대칭 제거(option D 활성화). portfolio-hub#8
(*_after 응답) 동작 중 확인으로 그간 deferred 됐던 REQ-030 을 닫음.

거버넌스: 전부 change-req (신규 REQ 없음, dcy-018 OQ-3 a).
- REQ-017: record_trade → LedgerWriteOutcome{result, cash_balance_after,
  asset_quantity_after}. 어댑터가 응답 root flat *_after 파싱(new+duplicate, 누락 None)
- REQ-019: LedgerWriter 에 SnapshotStore 주입 → new+duplicate write-back
  (best-effort, *_after 절대값이라 멱등). LedgerOutbox.pending_cash_delta()
- REQ-029: 추정 현금 오버레이(_apply_cash_estimate, cash_estimated 라벨, OQ-4 i)
  + 슬롯 오버레이 유지(OQ-1 B). 미정산 outbox delta 기반, write-back 수렴
- REQ-030: option D 활성화 → Approved→Implemented

best-effort 격리(NFR-1): write-back/추정 실패가 ledger 멱등·청산 무차단.
배치 번호: 동시 커밋된 BAT-022(slot-state, dcy-016)와 충돌해 BAT-023 으로 배정.

검증: 단위 350 passed/35 skipped, 인프라 게이트(PG+RabbitMQ) 385 passed, ruff clean.
신규 test_ledger_option_d + adapter/PG 테스트. BAT-023 release-candidate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 21:50:56 +09:00

3.1 KiB

BAT-023 Implementation

  • Status: completed
  • Batch: BAT-023

구현 요약

  • dcy-018 option D 활성화(ledger write 응답 cash/quantity write-back) + 추정 현금 오버레이를 전부 change-req 로 구현(REQ-030 Approved→Implemented).

변경 내역

REQ-017 — 응답 계약 확장

  • trex_core/application/ledger_port.py: LedgerWriteOutcome{result, cash_balance_after?, asset_quantity_after?} 신설; record_trade 반환 타입 → LedgerWriteOutcome.
  • trex_core/adapters/ledger/portfolio_hub.py: 2xx 응답 root flat cash_balance_after/asset_quantity_after 파싱(_opt_num, new+duplicate, 누락 None). 409/404/400/422 예외 유지.
  • trex_core/adapters/ledger/in_memory.py: cash_after/quantity_after 주입 + outcome 반환.

REQ-019/030 — write-back + 추정 source

  • trex_core/application/ledger_outbox.py: LedgerWriter(snapshot_store=None) + _writeback(new+duplicate, *_after None/no-store skip, try/except best-effort); _process 가 outcome.result 소비. trade_cash_delta + LedgerOutbox.pending_cash_delta()(InMemory pending 합).
  • trex_core/adapters/persistence/postgresql.py: pending_cash_delta SQL(SUM CASE by asset_id, status='pending').
  • trex_core/runtime/daemon.py: SnapshotStore 를 LedgerWriter 보다 먼저 생성 + snapshot_store 주입.

REQ-029 — 추정 오버레이 + 슬롯 오버레이 유지

  • trex_core/application/messaging_handlers.py: _apply_cash_estimate(payload, ledger_outbox) — 미정산 자산에 cash_balance += pending delta + cash_estimated:true(best-effort). snapshot 핸들러 ledger_outbox 파라미터. 슬롯 오버레이(build_snapshot_envelope)는 불변.
  • trex_core/runtime/daemon.py: snapshot 핸들러에 ledger_outbox=self.outbox 배선.

REQ-030 — Approved→Implemented

  • docs/srs/Integration/req-030_*.md Status Approved→Implemented + CHG-20260608-01; docs/srs/index.md register REQ-030 → Implemented.

문서

  • docs/interface-contract.md: LedgerWriteOutcome/*_after/write-back/envelope cash_estimated. Last Updated → BAT-023.
  • docs/runtime-flows.md: ledger writer write-back 단계 + snapshot 추정 오버레이. Last Updated → BAT-023.

테스트

  • tests/adapters/ledger/test_portfolio_hub_ledger.py 확장: *_after 파싱(new/duplicate/누락) 3건.
  • 신규 tests/application/test_ledger_option_d.py: write-back(new/duplicate/skip/best-effort/no-store) + pending_cash_delta + estimate overlay + write-back 후 수렴 (11건).
  • 신규 PG 게이트 tests/adapters/persistence/test_postgresql_ledger_outbox.py::test_pending_cash_delta_on_pg.
  • 회귀: test_ledger_outbox_backoff.py programmable ledger → LedgerWriteOutcome 반환 전환.

검증 실행

  • 단위: TREX_BROKER=paper .venv/bin/python -m pytest -q → 350 passed / 35 skipped(::test_sandbox_token_and_submit deselect — LIVE .env 환경 의존, 본 batch 무관).
  • 인프라 게이트: TREX_POSTGRESQL_TEST_DSN=...(trex_core_test) TREX_RABBITMQ_TEST_URL=... pytest -q → 385 passed(pending_cash_delta SQL 포함).
  • ruff check trex_core tests → All checks passed.