Commit Graph

37 Commits

Author SHA1 Message Date
Jonathan 15358c05c3 Merge branch 'development' 2026-04-14 19:58:46 +02:00
Jonathan 59f833d7fd Fix candle chart staleness and show live price on today's candle
- 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>
2026-04-14 19:55:01 +02:00
Jonathan d5197cde14 Update README to reflect all features added since initial docs
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 20:43:06 +02:00
Jonathan 9c0db31580 Merge branch 'development' 2026-04-06 20:32:49 +02:00
Jonathan d90ac5365a Add price prediction feature to dashboard
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>
2026-04-06 20:32:25 +02:00
Jonathan ce9547a623 Merge development into main
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 20:20:08 +02:00
Jonathan 672f5b74a4 Fix production deployment: replace serve with nginx reverse proxy
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>
2026-04-06 20:18:38 +02:00
Jonathan a2ca82062e Cache last known BTC price and show stale warning in UI
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>
2026-04-06 20:01:30 +02:00
Jonathan 5bb67d6663 Add purchase date picker and sells feature
- 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>
2026-04-06 19:52:24 +02:00
Jonathan 33656c4512 Merge development: security hardening, login fix, chart improvements
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-06 19:31:11 +02:00
Jonathan 5cf3726f59 Improve portfolio chart with historical price-based data points
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>
2026-04-06 19:30:48 +02:00
Jonathan ce227e47d6 Fix login blocked by registration password validation
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>
2026-03-26 18:49:43 +01:00
Jonathan 11b020907d Revert backend Dockerfile to run as root
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>
2026-03-26 18:45:41 +01:00
Jonathan 4da23c9def Revert bcrypt version back to 3.2.2
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 18:44:22 +01:00
Jonathan 85455f3271 Security hardening: secrets, validation, Docker, and error handling
- 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>
2026-03-26 18:40:41 +01:00
Jonathan 4616accc63 Merge branch 'development' 2026-03-24 20:28:59 +01:00
Jonathan a0692501b3 Use en-GB locale for dd/mm/yyyy date format in purchases list
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 20:28:51 +01:00
Jonathan cb28979208 Merge feature/btc-history-chart: BTC candlestick chart with local OHLC storage
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>
2026-03-24 20:24:50 +01:00
Jonathan 79b565cfb6 Add BTC candlestick chart with local OHLC storage
- 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>
2026-03-24 20:23:46 +01:00
Jonathan befbe12bcf Merge branch 'development' 2026-03-24 19:39:41 +01:00
Jonathan 0803d86e38 Add admin role with user management (create/delete users)
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>
2026-03-24 19:26:10 +01:00
Jonathan aedc6a8a17 Merge branch 'development' 2026-03-24 19:18:56 +01:00
Jonathan c1371e9c72 Extend portfolio chart to always show today's data point
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>
2026-03-24 19:18:27 +01:00
Jonathan e93b9dfa53 Add git workflow rules to CLAUDE.md
Never work on main directly; always switch back to development after
merging to main.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 19:10:20 +01:00
Jonathan db9624822b Merge development: fix CORS for local dev on port 3001
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>
2026-03-24 18:58:50 +01:00
Jonathan cb6594f463 Fix CORS for local dev and update stats grid layout
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>
2026-03-24 18:51:01 +01:00
Jonathan 470dd80ed8 Make CORS allowed origins configurable via ALLOWED_ORIGINS env var
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>
2026-03-24 18:15:44 +01:00
Jonathan 8982f76d15 Change frontend port to 3001 and fix REACT_APP_API_URL as build arg
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>
2026-03-24 16:54:49 +01:00
Jonathan 22c36eff67 Update README with full project documentation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 16:32:11 +01:00
Jonathan afa74f7d45 Add CLAUDE.md with architecture and dev commands
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 23:49:11 +01:00
Jonathan 39404ca208 Add chart view toggle: Both / Portfolio / 1-Year BTC
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>
2026-03-23 23:22:49 +01:00
Jonathan 541b5f57d2 Add 1-year BTC daily price history chart
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>
2026-03-23 23:18:40 +01:00
Jonathan cb7bbf393c Sort purchase list by date ascending
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 22:28:25 +01:00
Jonathan ff7ba51e84 Add edit purchase feature (date, amount, price)
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>
2026-03-23 22:24:27 +01:00
Jonathan a2dad16f21 Add .gitignore and untrack database file
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 22:16:03 +01:00
Jonathan 3907414742 Add full-stack BTC portfolio web app
Multi-user FastAPI + React app with JWT auth, SQLite storage, and
CoinGecko price integration. Dockerized with docker-compose.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 22:15:40 +01:00
Jonathan 84679639ef first commit 2026-03-23 19:20:15 +01:00