[STK8-03] Aggregator: 포트폴리오 분석 API (내 종목 탭)
작업 내용 (설계 의도)
Aggregator에 ManualHoldingApiController와 GetPortfolioAnalysisUseCase를 추가한다. Backend(손익)와 ML(예측)을 병렬로 호출하여 조합한다.
GET /api/v1/portfolio— 포트폴리오 목록 + 각 종목 손익POST /api/v1/portfolio— 포트폴리오 추가 (BE 위임)PUT /api/v1/portfolio/{symbol}— 수정 (BE 위임)DELETE /api/v1/portfolio/{symbol}— 삭제 (BE 위임)GET /api/v1/portfolio/{symbol}/analysis— 손익 + 단기/중기/장기 예측 + 매도 추천
/analysis 엔드포인트는 BE 손익 조회와 ML 예측을 코루틴 async/await로 병렬 호출한다.
다이어그램
처리 흐름
sequenceDiagram participant FE as Frontend participant AGG as Aggregator participant BE as Backend participant ML as ML FE->>AGG: GET /api/v1/portfolio/{symbol}/analysis par 병렬 호출 AGG->>BE: GET /manual-holdings/{symbol}/pnl BE-->>AGG: ManualHoldingWithPnlResponse and AGG->>ML: GET /portfolio-forecast/{symbol} ML-->>AGG: PortfolioForecastResult end AGG-->>FE: PortfolioAnalysisResponse
클래스 의존
flowchart LR ManualHoldingApiController --> BeManualHoldingUseCases ManualHoldingApiController --> GetPortfolioAnalysisUseCase GetPortfolioAnalysisUseCase --> BeDomainService GetPortfolioAnalysisUseCase --> MlDomainService BeDomainService --> BeGateway MlDomainService --> MlGateway
테스트 케이스
- 포트폴리오 추가/수정/삭제가 BE에 정상 위임된다
/analysis호출 시 손익과 단기/중기/장기 예측이 모두 포함된 응답이 반환된다- BE 손익에 이익 금액과 수익률(%)이 포함된다
- 각 horizon(short/mid/long)마다 sell_recommendation이 포함된다
- sell_recommendation에 평균 매수가 기준 예상 손익이 포함된다
- symbol이 포트폴리오에 없으면 404가 반환된다
- ML 응답이 지연되어도 BE 손익은 정상 반환된다 (timeout 설정 검증)