fix: apply Ganymede review fixes to portfolio code
Some checks are pending
CI / lint-and-test (push) Waiting to run

dashboard_portfolio.py:
- datetime.utcnow() → datetime.now(timezone.utc) (deprecation fix)
- days parameter validation with try/except + min(..., 365) on 2 endpoints

fetch_coins.py:
- isinstance(chain, str) guard prevents AttributeError on string chain values
- Log when adjusted market cap differs from DexScreener value

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
m3taversal 2026-04-20 17:00:02 +01:00
parent ddf3c25e88
commit 5071ecef16
2 changed files with 16 additions and 4 deletions

View file

@ -8,7 +8,7 @@ import json
import sqlite3
import logging
from html import escape as esc
from datetime import datetime
from datetime import datetime, timezone
from aiohttp import web
from shared_ui import render_page
@ -304,7 +304,7 @@ async def handle_portfolio_page(request):
d['nav_per_token'] = nav
d['price_nav_ratio'] = ratio
coins.append(d)
now = datetime.utcnow()
now = datetime.now(timezone.utc)
html = render_portfolio_page(coins, now)
return web.Response(text=html, content_type='text/html')
finally:
@ -315,7 +315,10 @@ async def handle_nav_ratios(request):
"""Server-side computed NAV ratios — only returns dates with valid data."""
conn = _get_db(request)
try:
days = int(request.query.get('days', '90'))
try:
days = min(int(request.query.get('days', '90')), 365)
except (ValueError, TypeError):
days = 90
rows = conn.execute("""
SELECT name, snapshot_date, price_usd, treasury_multisig_usd,
lp_usdc_total, adjusted_circulating_supply
@ -355,7 +358,10 @@ async def handle_nav_ratios(request):
async def handle_portfolio_history(request):
conn = _get_db(request)
try:
days = int(request.query.get('days', '90'))
try:
days = min(int(request.query.get('days', '90')), 365)
except (ValueError, TypeError):
days = 90
rows = conn.execute("""
SELECT * FROM coin_snapshots
WHERE snapshot_date >= date('now', ? || ' days')

View file

@ -92,6 +92,8 @@ def load_ownership_coins():
continue
chain = fm.get("chain") or {}
if isinstance(chain, str):
chain = {}
raise_data = fm.get("raise") or {}
ops = fm.get("operations") or {}
liq = fm.get("liquidation") or {}
@ -563,8 +565,12 @@ def compute_derived(row, coin):
if adj_circ and adj_circ > 0:
row["effective_liq_price"] = cash_total / adj_circ
if price and price > 0:
original_mcap = row.get("market_cap_usd")
row["market_cap_usd"] = price * adj_circ
mcap = row["market_cap_usd"]
if original_mcap and abs(mcap - original_mcap) > 1:
logger.debug("%s: adjusted mcap $%.0f (was $%.0f, protocol_owned=%s)",
row.get("name", "?"), mcap, original_mcap, protocol_tokens)
if price and price > 0 and row.get("effective_liq_price"):
row["delta_pct"] = ((row["effective_liq_price"] / price) - 1) * 100