docs: add Phase 6 finishing design document
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
3a9e5513f9
commit
63ffe2439e
222
docs/plans/2026-02-03-phase6-finishing.md
Normal file
222
docs/plans/2026-02-03-phase6-finishing.md
Normal file
@ -0,0 +1,222 @@
|
||||
# Phase 6: 마무리 단계 설계
|
||||
|
||||
## 1. 개요
|
||||
|
||||
**범위:**
|
||||
|
||||
| 항목 | 구현 방식 |
|
||||
|------|----------|
|
||||
| 스냅샷/수익률 추적 | 수동 + 자동 (배치) |
|
||||
| ETF 시세 연동 | Mock API (추후 실제 연동) |
|
||||
| 테스트 | E2E 테스트 (전체 플로우) |
|
||||
| 배포 | Docker 완성 (로컬 배포 가능) |
|
||||
|
||||
---
|
||||
|
||||
## 2. 파일 구조
|
||||
|
||||
```
|
||||
backend/
|
||||
├── app/api/snapshot.py # 스냅샷 API
|
||||
├── app/services/price_service.py # Mock 시세 서비스
|
||||
├── jobs/
|
||||
│ ├── scheduler.py # APScheduler 설정
|
||||
│ └── snapshot_job.py # 자동 스냅샷 배치
|
||||
├── tests/ # pytest 테스트
|
||||
│ └── e2e/
|
||||
├── Dockerfile # 정리
|
||||
|
||||
frontend/
|
||||
├── src/app/portfolio/[id]/history/page.tsx # 스냅샷 히스토리 페이지
|
||||
├── e2e/ # Playwright E2E 테스트
|
||||
├── Dockerfile # 정리
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 스냅샷 API
|
||||
|
||||
### 3.1 엔드포인트
|
||||
|
||||
| Method | Endpoint | 설명 |
|
||||
|--------|----------|------|
|
||||
| GET | /api/portfolios/{id}/snapshots | 스냅샷 목록 조회 |
|
||||
| POST | /api/portfolios/{id}/snapshots | 스냅샷 수동 생성 |
|
||||
| GET | /api/portfolios/{id}/snapshots/{snapshot_id} | 스냅샷 상세 조회 |
|
||||
| DELETE | /api/portfolios/{id}/snapshots/{snapshot_id} | 스냅샷 삭제 |
|
||||
| GET | /api/portfolios/{id}/returns | 수익률 추이 조회 |
|
||||
|
||||
### 3.2 스냅샷 생성 로직
|
||||
|
||||
```python
|
||||
def create_snapshot(portfolio_id):
|
||||
# 1. 현재 보유 종목 조회
|
||||
# 2. 각 종목 현재가 조회 (PriceService)
|
||||
# 3. 총 평가금액 계산
|
||||
# 4. PortfolioSnapshot 저장
|
||||
# 5. SnapshotHolding 저장 (종목별 상세)
|
||||
```
|
||||
|
||||
### 3.3 수익률 계산
|
||||
|
||||
- 일간/주간/월간/연간 수익률
|
||||
- 첫 스냅샷 대비 누적 수익률
|
||||
- 시간 가중 수익률 (TWR)
|
||||
|
||||
---
|
||||
|
||||
## 4. Mock 시세 서비스
|
||||
|
||||
### 4.1 PriceService 인터페이스
|
||||
|
||||
```python
|
||||
class PriceService:
|
||||
def get_current_price(self, ticker: str) -> Decimal:
|
||||
"""단일 종목 현재가 조회"""
|
||||
|
||||
def get_current_prices(self, tickers: List[str]) -> Dict[str, Decimal]:
|
||||
"""복수 종목 현재가 조회"""
|
||||
|
||||
def get_price_history(self, ticker: str, start_date, end_date) -> List[PriceData]:
|
||||
"""과거 시세 조회"""
|
||||
```
|
||||
|
||||
### 4.2 Mock 구현 방식
|
||||
|
||||
1. DB에 저장된 prices 테이블의 최신 데이터 사용
|
||||
2. DB에 없으면 pykrx로 조회 후 캐시
|
||||
3. 추후 OpenAPI 연동 시 구현체만 교체 (인터페이스 유지)
|
||||
|
||||
### 4.3 기존 코드 리팩토링
|
||||
|
||||
- `RebalanceService.get_current_prices()` → `PriceService` 사용으로 변경
|
||||
- `BacktestEngine` → `PriceService` 사용으로 변경
|
||||
|
||||
---
|
||||
|
||||
## 5. 자동 스냅샷 배치
|
||||
|
||||
### 5.1 APScheduler 설정
|
||||
|
||||
```python
|
||||
# jobs/scheduler.py
|
||||
from apscheduler.schedulers.background import BackgroundScheduler
|
||||
|
||||
scheduler = BackgroundScheduler()
|
||||
|
||||
# 매일 18:30 (장 마감 후) 자동 스냅샷
|
||||
scheduler.add_job(
|
||||
create_daily_snapshots,
|
||||
trigger='cron',
|
||||
hour=18, minute=30,
|
||||
day_of_week='mon-fri',
|
||||
id='daily_snapshots'
|
||||
)
|
||||
```
|
||||
|
||||
### 5.2 배치 작업 로직
|
||||
|
||||
```python
|
||||
def create_daily_snapshots():
|
||||
# 1. 모든 포트폴리오 조회
|
||||
# 2. 각 포트폴리오에 대해 스냅샷 생성
|
||||
# 3. job_logs 테이블에 실행 결과 기록
|
||||
```
|
||||
|
||||
### 5.3 스케줄러 시작
|
||||
|
||||
- FastAPI lifespan 이벤트에서 스케줄러 시작/종료
|
||||
- Docker 환경에서 백엔드 컨테이너와 함께 실행
|
||||
|
||||
---
|
||||
|
||||
## 6. E2E 테스트
|
||||
|
||||
### 6.1 테스트 도구
|
||||
|
||||
| 영역 | 도구 |
|
||||
|------|------|
|
||||
| Backend | pytest + httpx (async client) |
|
||||
| Frontend | Playwright |
|
||||
| 통합 | docker-compose로 전체 환경 실행 |
|
||||
|
||||
### 6.2 테스트 시나리오
|
||||
|
||||
1. **인증 플로우**: 로그인 → 토큰 발급 → 인증된 요청
|
||||
2. **포트폴리오 플로우**: 생성 → 목표비율 설정 → 보유자산 입력 → 리밸런싱 계산
|
||||
3. **전략 플로우**: 전략 선택 → 파라미터 입력 → 결과 조회
|
||||
4. **백테스트 플로우**: 백테스트 생성 → 완료 대기 → 결과 조회
|
||||
5. **스냅샷 플로우**: 스냅샷 생성 → 히스토리 조회 → 수익률 확인
|
||||
|
||||
### 6.3 테스트 데이터
|
||||
|
||||
- pytest fixtures로 테스트용 사용자/포트폴리오 생성
|
||||
- 테스트 완료 후 자동 정리 (rollback)
|
||||
|
||||
---
|
||||
|
||||
## 7. Docker 설정
|
||||
|
||||
### 7.1 Dockerfile
|
||||
|
||||
```dockerfile
|
||||
# backend/Dockerfile
|
||||
FROM python:3.12-slim
|
||||
WORKDIR /app
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
COPY . .
|
||||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||
|
||||
# frontend/Dockerfile
|
||||
FROM node:22-alpine
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
CMD ["npm", "start"]
|
||||
```
|
||||
|
||||
### 7.2 docker-compose.yml 업데이트
|
||||
|
||||
- healthcheck 추가 (postgres, backend)
|
||||
- depends_on 조건 추가 (service_healthy)
|
||||
- 환경변수 .env 파일 분리
|
||||
- volumes 설정 (데이터 영속성)
|
||||
|
||||
### 7.3 실행 명령
|
||||
|
||||
```bash
|
||||
docker-compose up -d # 전체 실행
|
||||
docker-compose logs -f # 로그 확인
|
||||
docker-compose down # 종료
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 구현 순서
|
||||
|
||||
### Batch 1: 기반 서비스
|
||||
1. PriceService 구현 (Mock)
|
||||
2. 스냅샷 Pydantic 스키마 추가
|
||||
3. 스냅샷 API 엔드포인트 구현
|
||||
|
||||
### Batch 2: 배치 및 프론트엔드
|
||||
4. APScheduler 설정 및 스냅샷 배치 작업
|
||||
5. 수익률 계산 서비스
|
||||
6. 스냅샷 히스토리 프론트엔드 페이지
|
||||
|
||||
### Batch 3: Docker
|
||||
7. Backend Dockerfile 정리
|
||||
8. Frontend Dockerfile 정리
|
||||
9. docker-compose.yml 업데이트
|
||||
|
||||
### Batch 4: E2E 테스트
|
||||
10. Backend E2E 테스트 (pytest + httpx)
|
||||
11. Frontend E2E 테스트 (Playwright)
|
||||
|
||||
---
|
||||
|
||||
**문서 버전:** 1.0
|
||||
**작성일:** 2026-02-03
|
||||
Loading…
x
Reference in New Issue
Block a user