- Refresh candles on every /candles request instead of only at startup
- Patch today's candle close/high/low with the live BTC price intraday
- Synthesise today's candle from live price if CoinGecko hasn't published it yet
- Display current BTC price next to the chart title
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Enter a hypothetical BTC price to instantly see predicted portfolio value,
predicted P&L, and difference vs current value — all calculated client-side.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Frontend container now uses nginx to serve static files and proxy
/api/* requests to the backend container internally, eliminating
the hardcoded localhost:8000 build-time URL that caused "Network
error" on any non-local server. CORS origins are also configurable
via ALLOWED_ORIGINS env var.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
Non-root appuser can't write to the host-mounted SQLite data volume —
chown in the image layer doesn't carry over to runtime volume mounts.
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>
Previously the chart stopped at the last purchase date. Now a final
point for today is appended so current portfolio value vs total
invested is always visible.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Resolved conflict by keeping env var approach from main and updating
the default to include both localhost:3000 and localhost:3001.
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>
Defaults to localhost:3000 for local dev. Server deployments can
pass a comma-separated list via the environment.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
REACT_APP_API_URL is baked into the JS bundle at build time, so it
must be passed as a build arg, not a runtime environment variable.
Port changed from 3000 to 3001 to avoid conflict with Gitea.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Tab bar above charts lets the user switch between showing both charts
stacked, or either chart individually.
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>