feat(portfolios): expose ledger investment aggregates

Add reversal-aware grouped manual-ledger aggregates to portfolio list responses and align the single-portfolio return summary with the same semantics.\n\nRefs #23
This commit is contained in:
2026-08-13 13:23:31 +09:00
parent 34792bdb5c
commit 93840800fa
9 changed files with 264 additions and 21 deletions
+13 -2
View File
@@ -67,7 +67,12 @@ def _require_write_token(auth: AuthContext) -> None:
)
def _portfolio_to_item(portfolio: Portfolio) -> PortfolioItem:
def _portfolio_to_item(
portfolio: Portfolio,
*,
return_summary: dict[str, float] | None = None,
) -> PortfolioItem:
summary = return_summary or {}
return PortfolioItem(
portfolio_id=portfolio.portfolio_id,
asset_id=portfolio.asset_id,
@@ -81,6 +86,8 @@ def _portfolio_to_item(portfolio: Portfolio) -> PortfolioItem:
asset_quantity=portfolio.asset_quantity,
price=portfolio.price,
profit_buffer=portfolio.profit_buffer,
net_contributed_capital=summary.get("net_contributed_capital", 0.0),
cumulative_profit_withdrawn=summary.get("cumulative_profit_withdrawn", 0.0),
tag_ids=[str(t) for t in (portfolio.tag_ids or [])],
managed_by_daemon_id=portfolio.managed_by_daemon_id,
created_at=portfolio.created_at,
@@ -295,12 +302,16 @@ def list_portfolios_v1(
market=market,
status=status_filter,
)
return_summaries = repo.get_return_summaries([portfolio.portfolio_id for portfolio in portfolios])
except HTTPException:
raise
finally:
_close_repo(repo)
items = [_portfolio_to_item(p) for p in portfolios]
items = [
_portfolio_to_item(p, return_summary=return_summaries.get(p.portfolio_id))
for p in portfolios
]
return PortfolioListResponse(portfolios=items, total=len(items))