When the CoinGecko API fails, fall back to the last successful price
instead of 0.0, and surface a warning indicator on the price card.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Purchase form now includes a date picker (defaults to today)
- New Sell model, CRUD endpoints (/sells), and stats integration
- AddSell and SellList components added to dashboard
- Portfolio chart updated to reflect sells over time
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Chart now plots weekly data points from first purchase to today using
candle/history price data, giving an accurate view of portfolio value
over time rather than just at purchase dates.
Backend seeds up to 365 days of daily close prices from CoinGecko as
synthetic OHLC candles, refreshing stale entries older than 31 days.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Split UserCreate into UserCreate (with min_length constraints) and
UserLogin (no constraints) so existing short passwords can still log in.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add root .gitignore to prevent btc_wallet.py (with RPC credentials) from being committed
- Load JWT SECRET_KEY from environment variable instead of hardcoded value
- Restrict CORS to explicit methods/headers instead of wildcards
- Add Pydantic Field validation (gt=0) to purchase amounts and user credentials
- Add logging to all silent exception handlers in btc.py
- Run backend and frontend Docker containers as non-root appuser
- Add .dockerignore for both backend and frontend
- Pass SECRET_KEY env var through docker-compose; add healthchecks to both services
- Update bcrypt from pinned 3.2.2 to >=4.0.0
- Capture error objects in frontend catch blocks; check admin delete response
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Resolves conflicts: combined admin + candles routers in main.py,
fixed docker-compose port to 3001:3001, restored admin styles in Dashboard.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Store daily BTC OHLC candles in SQLite to avoid hitting CoinGecko on every load
- Seed with 30 days of daily candles on first boot (free tier gives daily granularity for days<=30)
- Auto-detect and replace coarse legacy candle data on startup
- Daily refresh adds new candles on each container restart
- New GET /candles endpoint (supports ?days=365 and ?days=all)
- Switch BTCHistoryChart to BTCCandlestickChart using lightweight-charts (TradingView)
- Purchase markers with nearest-candle matching and multi-purchase merging
- Fullscreen mode showing all stored candles
- Fix frontend port to 3001 and pass REACT_APP_API_URL as build arg
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
First registered user becomes admin automatically. Admins see a
"Manage Users" button in the dashboard header that opens a new
/admin page for listing, creating, and deleting users. Backend
enforces admin-only access on /admin/* routes. Startup migration
adds the is_admin column to existing SQLite databases.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add localhost:3001 to allowed CORS origins to fix local Docker setup
where frontend is mapped to port 3001. Also update stats grid to fixed
3-column layout and reorder stat cards.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New GET /history endpoint fetches 365 days of BTC/EUR data from
CoinGecko, deduplicates by date, and joins the user's purchases.
BTCHistoryChart component renders the price line with orange dot
markers on purchase dates and a dashed cyan avg buy price line.
Tooltip shows purchase details on marked dates.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Backend: PUT /purchases/{id} endpoint accepts updated amount_eur,
price_eur, and created_at. Frontend: inline edit row in PurchaseList
with date picker and number inputs, Save/Cancel actions.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>