feat: add portfolio item symbol to v1 responses

This commit is contained in:
2026-05-24 13:09:37 +09:00
parent 3a78e5c138
commit 136ae16885
17 changed files with 655 additions and 11 deletions
@@ -20,7 +20,8 @@
- **body 스키마** (`PortfolioCreateRequest` 신규):
- 필수: `asset_id`, `broker`
- 선택: `name`, `cash_balance`, `asset_quantity`, `asset_price`, `profit_buffer`, `strategy_name`, `strategy_params`, `managed_by_daemon_id`, `user_id`(admin 분기 전용)
- 응답: HTTP 201 + 생성된 portfolio의 `PortfolioItem`(`portfolio_id`, `asset_id`, `owner_user_id`, ...).
- 응답: HTTP 201 + 생성된 portfolio의 `PortfolioItem`(`portfolio_id`, `asset_id`, `symbol`, `owner_user_id`, ...).
- 응답의 `symbol` 값은 생성된 `portfolios.asset_id`가 가리키는 `assets.symbol`을 기준으로 server-side join 결과에서 채운다. 클라이언트가 별도 catalog lookup으로 복원하는 방식은 본 REQ 범위의 정식 계약이 아니다.
- catalog 검증 위치(서비스 계층 공통 진입점 vs v1 라우터 레이어 한정)는 본 REQ 구현 시점에 결정. dcy-003 R-5 트레이드오프 reference 참조.
## Acceptance Criteria
@@ -31,6 +32,7 @@
5. Given body `asset_id`가 catalog에 미존재 또는 `status='inactive'`, When `POST /v1/portfolios`, Then HTTP 422 또는 403로 거부되고 portfolio row가 생성되지 않는다.
6. Given Bearer token 없음, When `POST /v1/portfolios`, Then HTTP 401.
7. Given non-admin token + body `user_id` 지정, When `POST /v1/portfolios`, Then `user_id`는 무시되어 `owner_user_id == auth.user_id`로 생성되거나 HTTP 422.
8. Given active catalog asset(`asset_id=<uuid>`, `symbol="005930"`), When `POST /v1/portfolios`, Then HTTP 201 응답의 `PortfolioItem.symbol == "005930"` 이고 값은 해당 asset row join 결과와 일치한다.
## Impacted Area
- Docs:
@@ -54,6 +56,64 @@
## Change Log
### CHG-20260524-02
- Date: 2026-05-24
- Author: Hermes Agent
#### Change Summary
- Status: Approved → Implemented
#### Intent
- BAT-014 verification 완료. `PortfolioItem.symbol` 응답 계약이 코드, 테스트, baseline 문서에 반영되었고 REQ-025 acceptance criteria 전부가 trace 가능해졌다.
#### Acceptance Criteria Delta
- No change
#### Impacted Area Delta
- No change
#### Delivery Trace Delta
- Batches: BAT-014 (release-candidate); BAT-009 response-contract evidence superseded by BAT-014
- Releases: pending
#### Revalidation Impact
- Reverification Needed: no
- Existing Implementation Invalidated: no
- Status Recommendation: promote-to-implemented
- Follow-up Action: release 단계에서 smoke 확인
### CHG-20260524-01
- Date: 2026-05-24
- Author: Hermes Agent
#### Change Summary
- `PortfolioItem.symbol` 응답 계약 추가에 따라 REQ-025 생성 응답 contract를 보강하고 상태를 Implemented → Approved로 되돌림.
#### Intent
- trex-orbit 팀 이슈(`docs/issues/20260524_portfolio-hub-ticket-symbol-in-portfolios.md`) 후속. 생성 응답만 `asset_id`를 반환하고 `symbol`을 생략하면 클라이언트가 별도 asset catalog 조회/캐시를 유지해야 하므로, 생성 직후 응답에서도 joined asset의 `symbol`을 즉시 반환하도록 계약을 확장한다.
#### Acceptance Criteria Delta
- Added:
- AC-8: POST 응답의 `PortfolioItem.symbol` 이 `assets.symbol` join 결과와 일치해야 함
#### Impacted Area Delta
- Docs: `docs/interface-contract.md` 의 POST `/v1/portfolios` 응답 예시에 `symbol` 추가 필요 (REQ-032 후속)
- Modules: `app/schemas/v1.py`, `app/api/v1_portfolios.py` (`_portfolio_to_item`), `app/repositories/postgres.py:get()` join 응답 확인
- Tests: `tests/test_v1_portfolios_crud.py` 에 POST 응답 `symbol` 검증 추가 필요
#### Delivery Trace Delta
- Batches: BAT-009 evidence partially superseded; follow-up BAT-014 예정
- Releases: REL-001 response-contract evidence 일부 재검토 필요
#### Revalidation Impact
- Reverification Needed: yes
- Existing Implementation Invalidated: yes (response schema evidence partial)
- Status Recommendation: revert-to-approved
- Follow-up Action: BAT-014에서 POST/PATCH/DELETE/GET portfolio 응답 `symbol` 회귀 검증 추가
#### Validation Plan
- `tests/test_v1_portfolios_crud.py` 에서 POST 201 응답 body의 `symbol` 존재 및 `asset_id`가 가리키는 asset row의 `symbol` 일치 여부를 검증한다.
### CHG-20260521-01
- Date: 2026-05-21
- Author: Justin Ko