fix(holdings): /holdings/cost-basis WAC row에 fee_amount 편입 (QC보정)

get_holdings_cost_basis 핸들러의 row dict에 fee_amount 누락으로
/holdings/cost-basis의 cost_basis_per_unit이 매수 수수료 미편입값을
반환하던 버그 수정. /pnl/realized 핸들러와 동일하게 e.fee_amount 포함.
테스트: buy fee>0 케이스(1000.5 단언) + fee=0 회귀 케이스 추가.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
This commit is contained in:
2026-06-26 20:34:03 +09:00
co-authored by Claude Sonnet 4.6
parent 73414817e0
commit d224d716f6
2 changed files with 68 additions and 1 deletions
+67 -1
View File
@@ -78,6 +78,7 @@ def _make_entry(
quantity: float,
price: float,
executed_at: datetime,
fee_amount: float = 0.0,
) -> LedgerEntry:
return LedgerEntry(
ledger_entry_id=ledger_entry_id,
@@ -87,7 +88,7 @@ def _make_entry(
side=side,
quantity=quantity,
price=price,
fee_amount=0.0,
fee_amount=fee_amount,
tax_amount=0.0,
executed_at=executed_at,
recorded_at=executed_at,
@@ -535,3 +536,68 @@ def test_portfolio_id_in_response_matches_request() -> None:
resp = client.get(_PATH, headers={"Authorization": "Bearer tok"})
assert resp.status_code == 200
assert resp.json()["portfolio_id"] == _PORTFOLIO_ID
# ---------------------------------------------------------------------------
# QC보정: buy fee>0 케이스 — cost_basis_per_unit이 fee 편입값인지 확인
# buy 10@1000 fee=5 → cost_basis_per_unit = (10*1000 + 5) / 10 = 1000.5
# ---------------------------------------------------------------------------
def test_cost_basis_per_unit_includes_buy_fee() -> None:
"""buy fee>0 케이스: cost_basis_per_unit이 매수 fee 편입값을 반환한다.
buy 10주 @ 1,000원, fee=5원 → WAC = (10*1000 + 5) / 10 = 1000.5
REQ-043 Notes: 매수 fee를 cost basis에 포함.
"""
settings = _make_settings()
trades = [
_make_entry(
ledger_entry_id=1,
side="buy",
quantity=10,
price=1_000,
fee_amount=5.0,
executed_at=datetime(2026, 6, 1, 9, 0, tzinfo=timezone.utc),
),
]
repo = _make_service_repo(
portfolio=_make_portfolio(asset_quantity=10.0),
trades=trades,
)
with _with_repo(repo):
client = _make_client(settings)
resp = client.get(_PATH, headers={"Authorization": "Bearer tok"})
assert resp.status_code == 200
body = resp.json()
# (10 * 1000 + 5) / 10 = 1000.5
assert body["cost_basis_per_unit"] == pytest.approx(1000.5)
assert body["total_cost_basis"] == pytest.approx(10_005.0)
def test_cost_basis_per_unit_zero_fee_unchanged() -> None:
"""buy fee=0 케이스: fee 편입 추가 후에도 fee=0이면 기존 값 그대로.
buy 10주 @ 1,000원, fee=0 → WAC = 1000.0 (회귀 확인)
"""
settings = _make_settings()
trades = [
_make_entry(
ledger_entry_id=1,
side="buy",
quantity=10,
price=1_000,
fee_amount=0.0,
executed_at=datetime(2026, 6, 1, 9, 0, tzinfo=timezone.utc),
),
]
repo = _make_service_repo(
portfolio=_make_portfolio(asset_quantity=10.0),
trades=trades,
)
with _with_repo(repo):
client = _make_client(settings)
resp = client.get(_PATH, headers={"Authorization": "Bearer tok"})
assert resp.status_code == 200
body = resp.json()
assert body["cost_basis_per_unit"] == pytest.approx(1000.0)
assert body["total_cost_basis"] == pytest.approx(10_000.0)