fix(ledger): preserve exact decimal amount in manual and unified responses

Co-authored-by: genichin <4282227+genichin@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-09-09 12:41:36 +00:00
committed by GitHub
co-authored by genichin
parent 7fc3386f3a
commit fde5b33f05
5 changed files with 32 additions and 8 deletions
+10 -2
View File
@@ -16,6 +16,7 @@ import json
import logging
import uuid
from datetime import date, datetime, timedelta, timezone
from decimal import Decimal
from fastapi import APIRouter, Depends, HTTPException, Query, Response, status
@@ -687,7 +688,11 @@ def record_ledger_trade_v1(
def _manual_entry_to_response(entry) -> ManualLedgerResponse:
action = (entry.action or entry.side or "").upper()
amount = entry.price if action in {"INVEST", "BUFFER_OUT", "BUFFER_IN", "WITHDRAW", "PROFIT", "DIVIDEND"} else None
amount = (
(entry.price_decimal if entry.price_decimal is not None else Decimal(str(entry.price)))
if action in {"INVEST", "BUFFER_OUT", "BUFFER_IN", "WITHDRAW", "PROFIT", "DIVIDEND"}
else None
)
return ManualLedgerResponse(
ledger_entry_id=entry.ledger_entry_id,
portfolio_id=entry.portfolio_id,
@@ -786,6 +791,9 @@ def _decode_ledger_cursor(cursor: str, *, portfolio_id: str, source: str | None)
def _ledger_entry_to_history_item(entry) -> LedgerHistoryItem:
action = (entry.action or entry.side or "").upper()
amount = None
if action in {"INVEST", "BUFFER_OUT", "BUFFER_IN", "WITHDRAW", "PROFIT", "DIVIDEND"}:
amount = entry.price_decimal if entry.price_decimal is not None else Decimal(str(entry.price))
return LedgerHistoryItem(
ledger_entry_id=entry.ledger_entry_id,
portfolio_id=entry.portfolio_id,
@@ -796,7 +804,7 @@ def _ledger_entry_to_history_item(entry) -> LedgerHistoryItem:
order_id=entry.order_id,
execution_id=entry.execution_id,
quantity=entry.quantity,
amount=entry.price if action in {"INVEST", "BUFFER_OUT", "BUFFER_IN", "WITHDRAW", "PROFIT", "DIVIDEND"} else None,
amount=amount,
price=entry.price,
fee_amount=entry.fee_amount,
tax_amount=entry.tax_amount,
+2 -1
View File
@@ -4,6 +4,7 @@ from __future__ import annotations
from dataclasses import dataclass, field
from datetime import datetime
from decimal import Decimal
from enum import Enum
from typing import Any, Protocol, runtime_checkable
@@ -136,6 +137,7 @@ class LedgerEntry:
portfolio_id: str
quantity: float
price: float
price_decimal: Decimal | None = None
ledger_entry_id: int = 0
order_id: str | None = None
execution_id: str | None = None
@@ -195,4 +197,3 @@ class BrokerCredential:
credential_version: int = 1
last_rotated_at: datetime | None = None
daemon_id: str | None = None
+4 -1
View File
@@ -711,6 +711,7 @@ class PostgresPortfolioRepository:
side=row[2],
quantity=float(row[4]),
price=float(row[3]),
price_decimal=Decimal(str(row[3])) if row[3] is not None else None,
fee_amount=float(row[5]),
tax_amount=float(row[6]),
executed_at=row[1],
@@ -1864,6 +1865,7 @@ class PostgresPortfolioRepository:
def _row_to_ledger_entry(row: Any) -> LedgerEntry:
if row is None:
raise ValueError("원장 항목을 찾을 수 없습니다")
raw_price = row[6]
return LedgerEntry(
ledger_entry_id=int(row[0]),
portfolio_id=row[1],
@@ -1871,7 +1873,8 @@ class PostgresPortfolioRepository:
execution_id=row[3],
side=row[4],
quantity=float(row[5]),
price=float(row[6]),
price=float(raw_price),
price_decimal=Decimal(str(raw_price)) if raw_price is not None else None,
fee_amount=float(row[7]),
tax_amount=float(row[8]),
executed_at=row[9],
+2 -2
View File
@@ -220,7 +220,7 @@ class ManualLedgerResponse(BaseModel):
ledger_entry_id: int
portfolio_id: str
action: str
amount: float | None = None
amount: Decimal | None = None
quantity: float = 0.0
price: float = 0.0
fee: float = 0.0
@@ -254,7 +254,7 @@ class LedgerHistoryItem(BaseModel):
order_id: str | None = None
execution_id: str | None = None
quantity: float | None = None
amount: float | None = None
amount: Decimal | None = None
price: float | None = None
fee_amount: float | None = None
tax_amount: float | None = None