# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

**QuantEngine v0.1** — A comprehensive quantitative analysis and data collection system for retirement asset portfolio management.

- **Architecture**: .NET 9 + C# (web UI + APIs), Python (legacy data collection/analysis)
- **Web UI**: Blazor Interactive WebAssembly (MudBlazor) + ASP.NET Core Web API (API-First)
- **Database**: PostgreSQL (Npgsql 8.0), single unified database
- **Data Source**: KIS Open API (quotations/ranking read-only), with fallbacks
- **Key Runtimes**: .NET 9, Python 3.9+, Node.js 16+

### Migration Phases Status (2026-06-29)

**Phase 1: Web UI Migration** 🔄 정책 전환 (2026-06-30)
- **신규 표준**: Blazor **Interactive WebAssembly** 렌더 모드 + **MudBlazor** 컴포넌트 + API-First
- **이전 표준(폐기)**: Fluent UI Blazor v5 / InteractiveServer 렌더 모드는 더 이상 사용하지 않음
- Pages: Home, Workspace, Collection, Tables, MainLayout
- 코드 전환 작업은 `docs/WBS_10_DOTNET_MIGRATION_HARDENING_2026_06_30.md` 의 **WBS-A7** 로 추적

**Phase 2: KIS Data Collection Pipeline** ✅ 95% COMPLETE
- ✅ KIS API Client: Full implementation complete
  - IKisApiClient interface (5 quotation methods)
  - KisApiClient with real HTTP implementation + token caching
  - All governance rules enforced (no trading APIs)
  - Windows env var + registry fallback for credentials
  - Build: 0 errors, 0 warnings
- ✅ PostgreSQL Infrastructure: Complete
  - PostgresTokenCache (token management, 10-min skew)
  - CollectionRepository (full CRUD + dashboard aggregations)
  - Auto-creates kis_tokens, kis_collection_runs, kis_collection_snapshots, kis_collection_errors
  - Dapper ORM + parameterized SQL (injection-proof)
- ✅ Web API Endpoints: Complete
  - CollectionEndpoints (6 endpoints: state, runs, snapshots, errors, latest, start)
  - ApiClient for Blazor consumption
- ✅ Blazor UI: Complete
  - Collection.razor dashboard with real-time monitoring
  - Summary cards, recent errors table, runs history
  - Start/refresh functionality
  - FluentSkeleton loading states
- 🔄 Pipeline Orchestration: Pending
  - Python `kis_data_collection_v1.py` → .NET (data fetching + validation)
  - Real KIS API data collection workflow integration
  - E2E test: API → DB → UI validation

**Phase 3: Node.js→.NET CLI Tools** 📋 PLANNED
- Makefile created (npm → make mappings)
- np operations documented

**Status Summary**:
- Python codebase: Operational (1,140 files)
- .NET 9 coverage: Core (✅), Infrastructure (✅), API (✅), Web UI (✅)
- Database: PostgreSQL fully migrated
- Release gates: Python gates remain authority until Phase 2 integration testing complete

## Deployment & Operations

**Production Server**: Hetzner Cloud `178.104.200.7` (kjh2064@178.104.200.7)

Projects on server:
1. **TaxBaik** (홈페이지) — Nginx location `/taxbaik`
2. **QuantEngine** (데이터 수집/분석) — Nginx location `/quantengine`

See [Temp/DEPLOYMENT_GUIDE.md](Temp/DEPLOYMENT_GUIDE.md) for deployment procedures.

### Quick Deploy (QuantEngine)

```powershell
ssh kjh2064@178.104.200.7
systemctl status quantengine-api
journalctl -u quantengine-api -f
sudo systemctl restart quantengine-api
```

### Git Repository

**Gitea Server** (동일 호스트):
- **HTTP**: `http://178.104.200.7/kjh2064/QuantEngineByItz.git`
- **SSH**: `git@178.104.200.7:2222/...`

## UI Design Principles (2026-06-29)

### Framework & Design System

- **Primary Framework**: [MudBlazor](https://mudblazor.com/)
- **Design System**: Material Design (MudBlazor), 고밀도/대량 데이터 성능 우선
- **Render Mode**: **Interactive WebAssembly** 를 기본 렌더 모드로 한다 (API-First). InteractiveServer 는 사용하지 않는다.
- **Deprecation**: **Fluent UI Blazor v5 는 폐기**한다. 기존 Fluent UI 페이지는 MudBlazor 로 점진 이전한다.

### Component Development Rules

1. **All UI Development** (New + Refactored):
   - Use **MudBlazor** components exclusively
   - Fall back to pure HTML/CSS if MudBlazor doesn't provide
   - **Never introduce Fluent UI components** (deprecated)
   - Progressively migrate existing Fluent UI to MudBlazor
   - **API-First**: UI 는 DB/비즈니스 로직에 직접 결합하지 않고 추상화된 API 클라이언트(HTTP)로만 통신 (AGENTS.md §5b 준수)

2. **Loading States** (Priority order):
   - `<MudSkeleton>` — **Default** for lists, cards, dashboards, detail pages
   - Pure HTML `<div class="skeleton">` — For custom layouts
   - `<MudProgressCircular>` / `<MudProgressLinear>` — 명시적 진행 표시가 필요한 경우
   - Blocking spinners — **Avoid**

3. **Data Rendering Pattern**:
   - First render: Skeleton placeholders only
   - On data arrival: Replace skeleton with actual UI
   - Never show blank states while loading

4. **Component Mapping** (MudBlazor):

| UI Element | MudBlazor Component | Alternative |
|-----------|-------------------|-------------|
| Button | `<MudButton>` | - |
| Input field | `<MudTextField>` | HTML `<input>` |
| Dropdown | `<MudSelect>` | HTML `<select>` |
| Data grid | `<MudDataGrid Dense Virtualize>` | HTML `<table>` |
| Card | `<MudCard>` | HTML `<div class="card">` |
| Badge/Status | `<MudBadge>` / `<MudChip>` | HTML `<span>` |
| Layout container | `<MudStack>` / `<MudGrid>` | HTML `<div>` |
| Accordion | `<MudExpansionPanels>` | HTML `<details>` |
| Navigation | `<MudNavMenu>` | HTML `<nav>` |
| Loading | `<MudSkeleton>` | CSS skeleton animation |
| Icons | `<MudIcon>` | SVG inline |
| Modal/Dialog | `<MudDialog>` (CRUD: 모달 패턴, 삭제: ConfirmDialog) | - |

## Development Commands (Phase 1 + 2)

### Python / Node.js (Legacy & Release Gates)
```powershell
npm install
npm run ops:validate              # Warn-only validation
npm run full-gate                 # Strict validation (all gates PASS)
npm run ops:data-collect          # KIS collection (Python subprocess)
npm run ops:release               # Full release DAG
```

### .NET (Primary - Phase 1 + 2)
```powershell
cd src/dotnet
dotnet restore
dotnet build                      # Debug build (0 errors, 0 warnings)
dotnet build -c Release           # Release build
dotnet watch run --project QuantEngine.Web  # Hot-reload (http://localhost:5265)
dotnet run --project QuantEngine.Web        # Run API server
```

### Collection Pipeline Testing (Phase 2)
```powershell
# Set KIS credentials (sandbox account)
$env:KIS_APP_Key_TEST = "your_kis_test_key"
$env:KIS_APP_Secret_TEST = "your_kis_test_secret"

# Start web server (http://localhost:5265)
dotnet run --project QuantEngine.Web

# Verify Collection dashboard
# Navigate to http://localhost:5265/collection
# - Click "Start Collection" to trigger async run
# - Backend uses PostgreSQL-backed data storage
# - Dashboard updates with run status, snapshots, errors

# Verify API endpoints
curl http://localhost:5265/api/collection/state
curl http://localhost:5265/api/collection/runs
curl "http://localhost:5265/api/collection/latest/005930"
```

## API Endpoints (Phase 1 + 2)

### Workspace & History (Phase 1)
All endpoints prefixed with `/api/`:

| Route | Purpose |
|-------|---------|
| `GET /state` | Full UI state snapshot |
| `GET /tables` | Browsable tables list |
| `GET /table-rows` | Paginated rows |
| `POST /settings/save` | Save settings |
| `POST /account-snapshot/save` | Save snapshots |
| `POST /bootstrap` | Seed DB from JSON |
| `POST /account-snapshot/import-tsv` | Import TSV |
| `POST /autofix` | Auto-correct data |

### Collection Pipeline (Phase 2)
| Route | Purpose |
|-------|---------|
| `GET /collection/state` | Dashboard summary (runs, snapshots, errors) |
| `GET /collection/runs` | Recent collection runs (paginated) |
| `GET /collection/runs/{runId}/snapshots` | Snapshots from a run |
| `GET /collection/runs/{runId}/errors` | Errors from a run |
| `GET /collection/latest/{ticker}` | Latest snapshots for ticker |
| `POST /collection/run` | Start new collection run (async) |

## KIS API Client Security (Phase 2)

### Governance Enforcement
- **Read-Only Mandate**: `AssertReadOnly(path, trId)` blocks all trading-related endpoints
- **Forbidden Paths**: `/trading/` substring triggers 🚫 immediate exception
- **Forbidden TR_IDs**: TTTC* / VTTC* prefixes (buy/sell order codes) blocked
- **Source**: `governance/rules/06_no_direct_api_trading.yaml`

### Token Management
- **ITokenCache** abstraction: PostgreSQL-backed in production
- **Credential Loading**:
  - Windows environment variables: `KIS_APP_Key`, `KIS_APP_Secret`, `KIS_APP_Key_TEST`, `KIS_APP_Secret_TEST`
  - Fallback: `HKCU\Environment` registry (Windows only)
  - Account modes: `"real"` (prod) vs `"mock"` (sandbox)

### Quotation Methods (All Read-Only)
1. **GetCurrentPriceAsync** (FHKST01010100) — Current price inquiry
2. **GetAskingPrice10LevelAsync** (FHKST01010200) — Order book (10-level)
3. **GetDailyShortSaleAsync** (FHPST04830000) — Short-sale trends
4. **GetDailyItemChartPriceAsync** (FHKST03010100) — Daily OHLCV data
5. **GetInvestorTrendAsync** (FHKST01010900) — Investor sentiment (개인/외국인/기관)

## Notes for Contributors

- **SQL Safety**: Whitelist-only table access (enum switch)
- **KIS API**: Read-only quotations/ranking; no order/trade endpoints
- **Blazor WASM**: No direct SQLite access; API-only
- **Database**: PostgreSQL contract maintained during migration
- **Release Authority**: Python gates (`full-gate`, `prepare-upload-zip`) remain authority until .NET fully operational
