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>
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
- Baseline Seed: .stage-pilot/bootstrap/baseline.yaml
|
||||
- Status: draft
|
||||
- Owner: project maintainers
|
||||
- Last Updated (KST): 2026-06-08 (BAT-021)
|
||||
- Last Updated (KST): 2026-06-08 (BAT-023)
|
||||
- Source Discovery / Batch: bootstrap-baseline (pre-Discovery); HTTP API = dcy-002 / BAT-002
|
||||
- Primary Runtime: daemon (HTTP API) + library (slot 도메인)
|
||||
|
||||
@@ -150,7 +150,8 @@ sell payload 는 `{"intent_type":"sell", "intent_id":..., "slot_id":..., "reason
|
||||
"cash_balance": number,
|
||||
"asset_quantity": number,
|
||||
"active_strategy_id": str | null,
|
||||
"strategy_params": object # opaque, pass-through
|
||||
"strategy_params": object, # opaque, pass-through
|
||||
"cash_estimated": true? # dcy-018/OQ-4 — cash_balance 가 미정산 추정값일 때만(라벨)
|
||||
}, ...
|
||||
],
|
||||
"view": "all" | "buyable" | "held", # echo
|
||||
@@ -379,7 +380,7 @@ resume_kill_switch 요청·응답 (REQ-046):
|
||||
|
||||
### Inputs
|
||||
|
||||
- record_trade(trade: LedgerTrade) :: 단일 체결을 원장에 기록 (`execution_id` 멱등)
|
||||
- record_trade(trade: LedgerTrade) :: 단일 체결을 원장에 기록 (`execution_id` 멱등) → `LedgerWriteOutcome` 반환
|
||||
|
||||
### `LedgerTrade` Fields
|
||||
|
||||
@@ -395,8 +396,12 @@ resume_kill_switch 요청·응답 (REQ-046):
|
||||
|
||||
### Outputs / Outcomes
|
||||
|
||||
- `LedgerWriteResult.NEW` :: 새 원장 엔트리 적재
|
||||
- `LedgerWriteResult.DUPLICATE_OK` :: 같은 execution_id 가 이미 기록되어 있음(서버 멱등)
|
||||
- `LedgerWriteOutcome` (dcy-018/REQ-017) :: `{result, cash_balance_after?, asset_quantity_after?}`
|
||||
- `result = LedgerWriteResult.NEW` :: 새 원장 엔트리 적재
|
||||
- `result = LedgerWriteResult.DUPLICATE_OK` :: 같은 execution_id 가 이미 기록되어 있음(서버 멱등)
|
||||
- `cash_balance_after`/`asset_quantity_after` :: portfolio-hub#8 ledger write 응답 root flat 권위값(option D). `new`(201)·`duplicate`(200) 에 존재, 응답 누락 시 None(write-back skip). 409/422 는 예외(아래)라 outcome 미반환.
|
||||
- write-back(REQ-019/030): `LedgerWriter` 가 `new`·`duplicate` outcome 의 `*_after`(None 아님)를 `SnapshotStore.update_cash_position(asset_id, cash, qty)` 로 반영(best-effort). 절대 권위값이라 duplicate 도 멱등.
|
||||
- 스냅샷 응답 추정 현금(REQ-029/OQ-4): write-back 전 공백 동안 자산에 `cash_balance += 미정산 pending 합` + `cash_estimated: true` 플래그(라벨). write-back 도착 시 권위값으로 수렴(pending 제거).
|
||||
|
||||
### Error Contract
|
||||
|
||||
|
||||
Reference in New Issue
Block a user