Files
portfolio-hub/.proofline/lines/line-0006/dcy-0006.md
T

42 lines
3.0 KiB
Markdown

---
id: "dcy-0006"
status: confirmed
---
# [portfolio-hub] 포트폴리오 전체 원장 조회 API
## Problem
기존 `GET /v1/portfolios/{portfolio_id}/ledger/manual`는 manual source만 반환하므로, portfolio owner가 broker 체결/원장 이벤트를 포함한 전체 원장을 하나의 안정적인 read 계약으로 조회할 수 없었다. 소비자 UI는 owner가 제공한 원장 사실을 표시할 뿐 action·잔고 효과·PnL을 재계산해서는 안 된다.
## Evidence
- 승인 issue: `https://github.com/fourblocks2020/portfolio-hub/issues/29`; 전체 원문은 `evidence/issue-29-approved-discovery.md`에 body SHA-256 `833b5c8e2dd4bb6c90331bef58a0fdee48534fc1458a82b646f1581877428b66`으로 보존했다.
- 진행 comment: `evidence/implementation-progress.md`, body SHA-256 `e90881b5df47b17650169c0858e7f39c300682ab70d3a88032b6fe41d31f65c7`.
- 완료 comment: `evidence/implementation-completion.md`, body SHA-256 `ce25425fa95afad70221be88a8df88fe39b13f706bbc4f8508a0be34a8327187`.
- 구현 commit `ac742b1150832f6c1cf58744308b4f3ea6803fd4`에서 통합 endpoint, repository keyset query, `20260820_0030` index migration 및 회귀가 확인됐다.
- 실행 evidence: 전체 `pytest -q`는 `664 passed, 16 skipped`; disposable PostgreSQL fresh migration에서 head와 `idx_portfolio_ledger_portfolio_recorded_entry_desc` 생성을 확인했다.
## Scope
- owner-only `GET /v1/portfolios/{portfolio_id}/ledger`가 manual과 broker를 포함한 모든 source를 기본 최신순(`recorded_at DESC, ledger_entry_id DESC`)으로 반환한다.
- optional non-empty exact `source` filter, `(recorded_at, ledger_entry_id)` keyset pagination 및 `next_cursor` 종료 계약을 제공한다. cursor는 portfolio/source 조건에 결속되고 malformed·tampered·다른 조건 재사용은 HTTP 422다.
- 통합 item은 canonical 대문자 `action`을 노출하고 internal `side`는 노출하지 않는다. source별로 없는 사실은 0/추정값이 아닌 schema nullable 값이다.
- user/session owner만 허용한다. owner 밖 사용자와 service token은 기존 정책에 따라 거부한다.
- PostgreSQL index/migration, OpenAPI, mixed source/page/cursor/권한/manual 하위호환 회귀를 포함한다.
- AC admission: 기존 active AC는 aggregate 의미를 소유할 뿐 source-neutral unified read contract를 소유하지 않으므로 durable behavior를 `create`한다.
## Out of Scope
- ledger 생성·수정·삭제, REVERSAL 실행 또는 기존 원장 재해석.
- broker order/fill 생성, strategy signal, outbox/producer 변경.
- API/UI가 원장에 없는 경제 효과·잔고·PnL을 추론하는 동작.
- portfolio return aggregate 의미 변경(#28), trex-web UI, push/PR/merge, 배포·릴리스.
## Risks and Unknowns
### Risks
- 운영 cursor secret은 장기 랜덤 값으로 관리해야 하며 교체 시 기존 cursor의 만료·무효화 정책을 운영 문서에 명시해야 한다.
- 운영 규모 row가 있는 환경에서 source-filter query의 `EXPLAIN ANALYZE` index 사용과 latency 관찰이 필요하다.