64 Commits

Author SHA1 Message Date
머니페니
741b7fa7dd feat: add skip/limit pagination to prices, snapshots, and transactions APIs
Add paginated responses (items/total/skip/limit) to:
- GET /api/data/stocks/{ticker}/prices (default limit=365)
- GET /api/data/etfs/{ticker}/prices (default limit=365)
- GET /api/portfolios/{id}/snapshots (default limit=100)
- GET /api/portfolios/{id}/transactions (default limit=50)

Frontend: update snapshot/transaction consumers to handle new response
shape, add "Load more" button to transaction table.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 22:32:34 +09:00
머니페니
98a161574e security: migrate JWT from localStorage to httpOnly cookie
Eliminates XSS token theft by storing JWT in httpOnly Secure cookie
instead of localStorage. Backend sets cookie on login and clears on
logout. Token extraction uses cookie-first with Authorization header
fallback for backward compatibility with existing tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 22:30:47 +09:00
머니페니
60d2221edc feat: add manual transaction entry UI with modal dialog
Add "거래 추가" button to the transactions tab with a modal dialog for
manually entering buy/sell transactions (ticker, type, quantity, price, memo).
Refreshes portfolio and transaction list after successful submission.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 22:22:56 +09:00
머니페니
4ea744ce62 feat: replace simulated sine wave chart with real snapshot data
Portfolio value chart now uses actual snapshot API data instead of
generated simulation. Shows empty state message when no snapshots exist.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 22:22:44 +09:00
머니페니
ee0de0504c feat: add portfolio edit/delete UI with confirmation dialogs
Add hover-visible edit (rename) and delete buttons to portfolio cards
on the list page, with modal dialogs for name editing and delete
confirmation. Uses existing PUT/DELETE API endpoints.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 22:22:37 +09:00
머니페니
815f255ff5 feat: add React ErrorBoundary with retry and reload UI
Add class-based ErrorBoundary component that catches rendering errors
and shows a user-friendly fallback with retry/reload buttons. Wrap in
root layout to protect against full-page crashes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 22:22:29 +09:00
머니페니
f12709ea79 fix: add toast error feedback for API failures in signals and data explorer pages
Replace silent console.error-only handling with user-visible toast notifications
using sonner, while keeping console.error for debugging.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 22:22:22 +09:00
머니페니
01f86298c4 feat: add strategy comparison UI for side-by-side multi-strategy analysis
Add a compare page at /strategy/compare that runs MultiFactor, Quality,
and ValueMomentum strategies simultaneously and displays results side-by-side
with common ticker highlighting and factor score comparison table.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 20:57:38 +09:00
머니페니
9249821a25 feat: add realized/unrealized PnL tracking and position sizing guide
- Add realized_pnl column to transactions table with alembic migration
- Calculate realized PnL on sell transactions: (sell_price - avg_price) * quantity
- Show total realized/unrealized PnL in portfolio detail summary cards
- Show per-transaction realized PnL in transaction history table
- Add position sizing API endpoint (GET /portfolios/{id}/position-size)
- Show position sizing guide in signal execution modal for buy signals
- 8 new E2E tests, all 88 tests passing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 19:04:36 +09:00
머니페니
65618cd957 feat: add signal execution cancel with transaction rollback and holding restore 2026-03-18 18:56:29 +09:00
eb06dfc48b feat: implement scenario gap analysis - core loop completion
All checks were successful
Deploy to Production / deploy (push) Successful in 1m32s
Phase 1 (Critical):
- Add bulk rebalance apply API + UI with confirmation modal
- Add strategy results to portfolio targets flow (shared component)

Phase 2 (Important):
- Show current holdings in signal execute modal with auto-fill
- Add DC pension risk asset ratio warning (70% limit)
- Add KOSPI benchmark comparison to portfolio returns
- Track signal execution details (price, quantity, timestamp)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 18:18:15 +09:00
a7366d053e feat: add manual signal execution to portfolio
Allow users to execute active KJB signals by selecting a portfolio,
entering quantity and price, then creating the corresponding transaction
and updating holdings. Signal status changes to 'executed' after completion.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 16:10:48 +09:00
e6160fffc6 fix: add KJB strategy to frontend strategy list and backtest form
All checks were successful
Deploy to Production / deploy (push) Successful in 1m37s
- Add KJB card to strategy page with Zap icon
- Create /strategy/kjb detail page with ranking table and rules reference
- Add KJB option to backtest strategy dropdown
- Add KJB-specific params UI (max positions, cash reserve, stop-loss, targets)
- Hide rebalance period selector when KJB is selected (uses daily simulation)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 15:53:01 +09:00
2d1983efff feat: add KJB signal dashboard frontend page
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 15:19:54 +09:00
238c4d1caf feat: accept valuation amount instead of price for rebalancing input
For holdings with quantity > 0, the input now accepts the total
valuation amount and derives the current price by dividing by quantity.
Holdings with quantity 0 (target-only) still accept price directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 21:51:05 +09:00
48417a03f5 feat: show stock names as primary display in history, strategy, and backtest pages
All checks were successful
Deploy to Production / deploy (push) Successful in 1m32s
2026-02-16 12:52:56 +09:00
87dff8bfa7 feat: show stock names as primary display in portfolio card, detail, and rebalance pages 2026-02-16 12:51:56 +09:00
c8bb675ba4 feat: add data explorer to sidebar navigation and fix gitignore
All checks were successful
Deploy to Production / deploy (push) Successful in 1m30s
- Add "데이터 탐색" menu item to sidebar with Search icon
- Add "수집 데이터 조회" link button on data management page
- Fix sidebar active state to correctly distinguish /admin/data
  from /admin/data/explorer
- Add page title mapping for data explorer in header
- Fix .gitignore: add negation for frontend/src/app/admin/data/
  so admin data pages are tracked without needing git add -f
- Fix dashboard loading state (return null → skeleton with layout)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 23:54:09 +09:00
0cd1e931b0 feat: display Korean stock names in portfolio views
All checks were successful
Deploy to Production / deploy (push) Successful in 1m35s
The portfolio API was returning only ticker symbols (e.g., "095570")
without stock names. The Stock table already has Korean names
(e.g., "AJ네트웍스") from data collection.

Backend: Add name field to HoldingWithValue schema, fetch stock names
via RebalanceService.get_stock_names() in the portfolio detail endpoint.

Frontend: Show Korean stock name as primary label with ticker as
subtitle in portfolio detail, donut charts, and target vs actual
comparison. Dashboard donut chart also shows names.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 23:22:48 +09:00
51fb812d57 fix: run data collectors in background threads to prevent server blocking
The collect endpoints were defined as async def but called synchronous
collector.run() directly, blocking the single uvicorn event loop for
up to 15+ minutes during price collection. This caused all other
requests (including auth/login) to hang, making the app unusable.

Backend: Run each collector in a daemon thread with its own DB session,
returning HTTP 200 immediately. The collector logs status to JobLog as
before, which the frontend can poll.

Frontend: Auto-poll job status every 3s while any job is "running",
with a visual indicator. Disable collect buttons during active jobs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 23:17:25 +09:00
3d5e695559 fix: resolve multiple frontend/backend bugs and add missing functionality
All checks were successful
Deploy to Production / deploy (push) Successful in 2m7s
Backend:
- Fix Decimal serialization in data_explorer.py (Decimal → FloatDecimal)
- Fix Optional type hints for query parameters in admin.py
- Fix authentication bypass in market.py search_stocks endpoint

Frontend:
- Fix 404 page: link to "/" instead of "/dashboard", proper back button
- Rewrite dashboard with real API data instead of hardcoded samples
- Implement actual equity curve and drawdown charts in backtest detail
- Remove mock data from backtest list, load real results from API
- Fix null dividend_yield display in quality strategy page
- Add skeleton loading states to 7 pages that returned null during load

Infrastructure:
- Fix PostgreSQL 18 volume mount compatibility in docker-compose.yml

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 22:49:17 +09:00
752db2ef1a fix: serialize Decimal as float in API responses and fix transaction field names
All checks were successful
Deploy to Production / deploy (push) Successful in 1m33s
Pydantic v2's model_dump(mode="json") serializes Decimal as strings (e.g.,
"33.33" instead of 33.33), causing frontend crashes when calling .toFixed()
on string values. Introduced FloatDecimal type alias with PlainSerializer
to ensure Decimal fields are serialized as floats in JSON responses.

Also fixed frontend Transaction interface to match backend field names
(created_at → executed_at, transaction_type → tx_type).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-12 23:47:48 +09:00
4afd01c947 feat: add data explorer frontend page for viewing collected data
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 23:34:50 +09:00
9fa97e595d feat: rebalance page with manual price input and strategy selection
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 23:32:49 +09:00
ecb3dca571 feat: add ETF data collectors and admin API endpoints
Add ETFCollector (KRX master data) and ETFPriceCollector (pykrx OHLCV)
with corresponding admin API endpoints and frontend collection UI buttons.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 23:00:27 +09:00
1dae2945c3 feat: client-side password hashing and admin user auto-seeding
All checks were successful
Deploy to Production / deploy (push) Successful in 1m31s
- Hash passwords with SHA-256 on frontend before transmission to prevent
  raw password exposure in network traffic and server logs
- Switch login endpoint from OAuth2 form-data to JSON body
- Auto-create admin user on startup from ADMIN_USERNAME/ADMIN_PASSWORD
  env vars, solving login failure after registration was disabled
- Update auth tests to match new SHA-256 + JSON login flow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 22:21:36 +09:00
070f74d978 fix: use 127.0.0.1 instead of localhost in health checks
All checks were successful
Deploy to Production / deploy (push) Successful in 1m35s
Alpine's wget resolves localhost to IPv6 [::1] first, but Next.js
standalone listens on 0.0.0.0 (IPv4 only), causing connection refused.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-08 00:12:59 +09:00
39d2226d95 feat: production deployment setup with Gitea Actions CI/CD
Some checks failed
Deploy to Production / deploy (push) Failing after 46s
- Remove nginx from docker-compose.prod.yml (NPM handles reverse proxy)
- Add Next.js rewrites to proxy /api/* to backend (backend fully hidden)
- Bind frontend to 127.0.0.1:3000 only (NPM proxies externally)
- Replace hardcoded localhost:8000 in history page with api client
- Make CORS origins configurable via environment variable
- Restrict CORS methods to GET/POST/PUT/DELETE
- Add Gitea Actions deploy workflow with secrets-based env management
- Add security headers (X-Frame-Options, X-Content-Type-Options, Referrer-Policy)
- Add BACKEND_URL build arg to frontend Dockerfile for standalone builds

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 23:09:22 +09:00
642514b227 chore: upgrade dependencies to latest compatible versions
- Node.js: 22 → 24 (Active LTS)
- PostgreSQL: 15 → 18
- FastAPI: 0.115.6 → 0.128.2
- Uvicorn: 0.34.0 → 0.40.0
- SQLAlchemy: 2.0.36 → 2.0.46
- Alembic: 1.14.0 → 1.18.3
- Pydantic: 2.10.4 → 2.12.5
- pandas: 2.2.3 → 2.3.3
- pykrx: 1.0.45 → 1.2.3
- React: 19.2.3 → 19.2.4

Breaking changes:
- Migrate from python-jose to PyJWT for JWT handling
- numpy downgraded to 1.26.4 for pykrx compatibility

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-07 11:12:16 +09:00
1dcb381a36 chore: 오류 수정, 실행 시 alembic 적용 2026-02-07 10:25:14 +09:00
d6f7d4a307 refactor: rename project from Galaxy-PO to Galaxis-Po
- Update all references in frontend, backend, and docker configs
- Update README, pyproject.toml, layout, sidebar
- Docker container names updated

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 23:24:53 +09:00
ad7191407f fix(frontend): update package-lock.json
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 23:19:45 +09:00
e14c5181ec fix(frontend): remove unused autoprefixer from postcss config
Tailwind CSS v4 with @tailwindcss/postcss includes autoprefixer

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 23:16:57 +09:00
4498ff9df1 feat(frontend): final polish and cleanup
- Toast notifications with sonner
- Loading skeleton components
- Improved loading states
- 404 page
- Cleanup old components

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 23:11:41 +09:00
3b741e1cfd feat(frontend): improve strategy and backtest pages
- Add StrategyCard component with icon, CAGR range, risk badge, and stock count
- Update strategy list page with improved cards and descriptions
- Redesign backtest page with split layout (form left, results right)
- Add summary cards for CAGR, MDD, Sharpe ratio, and total return
- Integrate charts for equity curve, drawdown, and yearly returns
- Add badge, select, and skeleton UI components
- Toggle between new backtest form and history view

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 23:07:19 +09:00
c3d43c97d0 feat(frontend): improve portfolio pages
- TradingView chart component with lightweight-charts v5 API
- PortfolioCard component with mini pie chart and return display
- Updated portfolio list with cards and empty state
- Portfolio detail with charts, tabs (holdings/transactions/analysis)
- Improved holdings table with progress bars for weight
- Added tabs component from shadcn

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 23:03:45 +09:00
4f432fb85c feat(frontend): add dashboard charts
- Sparkline for summary cards
- AreaChart for asset trends
- DonutChart for sector allocation
- BarChart for portfolio comparison

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 22:58:00 +09:00
eb3ce0e6e7 feat(frontend): apply DashboardLayout to all pages
- Portfolio pages updated with DashboardLayout and shadcn/ui Card components
- Strategy pages updated (multi-factor, quality, value-momentum)
- Backtest pages updated with consistent styling
- Admin data management page updated
- Login page improved with shadcn/ui Card, Input, Button, Label
- All pages now support dark mode via CSS variables
- Removed old Sidebar/Header imports, using unified DashboardLayout
- Added shadcn/ui input and label components

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 22:54:22 +09:00
3e733ec1b8 feat(frontend): add new layout components
- Collapsible Sidebar with navigation
- Header with page titles and logout
- DashboardLayout with responsive design
- Updated dashboard page

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 22:46:54 +09:00
0200ebc7ad test(frontend): add Phase 1 test page
- Verify shadcn/ui components render correctly
- Verify theme toggle works
- Verify Lucide icons display
- Temporary page for Phase 1 verification

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 22:25:12 +09:00
4178744afe feat(frontend): add chart libraries
- recharts for general charts
- lightweight-charts for TradingView financial charts

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 22:24:07 +09:00
c0fc599083 feat(frontend): add ThemeToggle component
- Dropdown menu with light/dark/system options
- Uses Lucide icons for sun/moon

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 22:23:22 +09:00
f4038ef539 feat(frontend): add core shadcn/ui components
- button, card, dropdown-menu, sheet, tooltip

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 22:21:51 +09:00
70bc032575 feat(frontend): add lucide-react icons
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 22:20:37 +09:00
0fce3f03f3 feat(frontend): add next-themes for dark/light mode
- Create ThemeProvider component
- Apply ThemeProvider to root layout
- Enable system theme detection

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 22:19:27 +09:00
6e30ecea03 feat(frontend): initialize shadcn/ui configuration
- Add tailwind.config.ts with shadcn/ui theme colors
- Update globals.css with CSS variables for dark/light mode
- Add utils.ts with cn() helper function
- Add components.json for shadcn/ui CLI
- Update postcss.config.mjs with autoprefixer
- Exclude playwright config from tsconfig to fix build

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-05 22:17:26 +09:00
926958c15a fix: remove unused function and fix lint warning
- Remove unused login helper in portfolio.spec.ts
- Add eslint-disable for useEffect in history page

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 12:30:54 +09:00
efcfc0e090 feat: add E2E tests for backend and frontend
Backend (pytest):
- Auth flow tests (login, token, protected routes)
- Portfolio CRUD and transaction tests
- Strategy endpoint tests
- Backtest flow tests
- Snapshot and returns tests

Frontend (Playwright):
- Auth page tests
- Portfolio navigation tests
- Strategy page tests
- Backtest page tests
- Playwright configuration

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 12:30:13 +09:00
e3b9ec1071 feat: update Docker configuration
- Backend Dockerfile: Python 3.12, non-root user, healthcheck
- Frontend Dockerfile: Multi-stage build, production stage
- docker-compose.yml: env_file, healthchecks, restart policies
- docker-compose.prod.yml: Production config with nginx
- .env.example: Updated with all variables

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 12:27:34 +09:00
89bd8fea53 feat: add scheduler, returns calculator, and history page
- APScheduler for daily snapshots (18:30 weekdays)
- ReturnsCalculator with CAGR, TWR, MDD, volatility
- Portfolio history page with snapshots and returns tabs
- FastAPI lifespan integration for scheduler

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 12:26:16 +09:00