diff --git a/btc-portfolio/backend/app/routes/stats.py b/btc-portfolio/backend/app/routes/stats.py index ae263e3..c78ad03 100644 --- a/btc-portfolio/backend/app/routes/stats.py +++ b/btc-portfolio/backend/app/routes/stats.py @@ -26,7 +26,7 @@ def get_stats( net_btc = total_btc_bought - total_btc_sold net_invested = total_invested - proceeds_eur average_price = net_invested / net_btc if net_btc > 0 else 0.0 - current_price = get_btc_price_eur() + current_price, price_is_cached = get_btc_price_eur() portfolio_value = net_btc * current_price profit_loss = portfolio_value - net_invested @@ -35,6 +35,7 @@ def get_stats( "total_btc": round(net_btc, 8), "average_price": round(average_price, 2), "current_price": round(current_price, 2), + "price_is_cached": price_is_cached, "portfolio_value": round(portfolio_value, 2), "profit_loss": round(profit_loss, 2), } diff --git a/btc-portfolio/backend/app/services/btc.py b/btc-portfolio/backend/app/services/btc.py index 02f471c..0de2c97 100644 --- a/btc-portfolio/backend/app/services/btc.py +++ b/btc-portfolio/backend/app/services/btc.py @@ -54,7 +54,12 @@ def aggregate_to_daily(raw: list) -> dict: return by_date -def get_btc_price_eur() -> float: +_last_known_price: float = 0.0 + + +def get_btc_price_eur() -> tuple[float, bool]: + """Returns (price, is_cached). is_cached=True when using a stale fallback.""" + global _last_known_price try: resp = requests.get( "https://api.coingecko.com/api/v3/simple/price", @@ -62,7 +67,9 @@ def get_btc_price_eur() -> float: timeout=10, ) resp.raise_for_status() - return float(resp.json()["bitcoin"]["eur"]) + price = float(resp.json()["bitcoin"]["eur"]) + _last_known_price = price + return price, False except Exception as e: logger.error(f"Failed to fetch BTC price: {e}") - return 0.0 + return _last_known_price, True diff --git a/btc-portfolio/frontend/src/pages/Dashboard.js b/btc-portfolio/frontend/src/pages/Dashboard.js index c94aa4f..e38f51d 100644 --- a/btc-portfolio/frontend/src/pages/Dashboard.js +++ b/btc-portfolio/frontend/src/pages/Dashboard.js @@ -28,11 +28,19 @@ const styles = { tabActive: { padding: '0.45rem 1.1rem', borderRadius: '8px', border: '1px solid #f7931a', background: 'rgba(247,147,26,0.1)', color: '#f7931a', cursor: 'pointer', fontSize: '0.9rem', fontWeight: 700 }, }; -function StatCard({ label, value, highlight }) { +function StatCard({ label, value, highlight, warning }) { return (