2.4 KiB
2.4 KiB
구현 완료
포트폴리오 소유자가 manual·broker를 포함한 모든 출처의 원장을 cursor 기반으로 조회하는 통합 API를 로컬 main에 구현·검증·커밋했습니다.
구현 내용
GET /v1/portfolios/{portfolio_id}/ledger를 추가해 모든 source의 원장을recorded_at DESC, ledger_entry_id DESC순서로 반환합니다.- optional exact
sourcefilter, HMAC-signed opaque cursor 및 portfolio/source 조건 결속을 구현했습니다. malformed·tampered·다른 조건의 cursor는 HTTP 422로 거부합니다. - 통합 item은 canonical 대문자
action만 노출하며side는 노출하지 않습니다. 출처별로 없는 사실은 추정값 대신 nullable field로 표현합니다. - PostgreSQL repository keyset query와
(portfolio_id, recorded_at DESC, ledger_entry_id DESC)index migration (20260820_0030)을 추가했습니다. - source filter, owner/service-token 권한 경계, cursor 오류, OpenAPI, release migration-head contract 및
temp/제외 source-surface 검사를 회귀로 보완했습니다.
검증 결과
전체 회귀와 변경 범위 검증을 완료했습니다.
pytest -q→664 passed, 16 skipped- focused API·release·auth-surface 검증 →
29 passed - disposable PostgreSQL fresh migration → head
20260820_0030,idx_portfolio_ledger_portfolio_recorded_entry_desc생성 확인 - 변경 범위 lint 및
git diff --check→ 통과 - 로컬 커밋 →
ac742b1150832f6c1cf58744308b4f3ea6803fd4(feat(portfolios): add unified ledger history API)
비차단 후속 권고
- 운영 환경에서는
PORTFOLIOHUB_LEDGER_CURSOR_SECRET를 장기 랜덤 secret으로 설정하고, cursor secret 교체 시 기존 cursor의 유효기간·무효화 정책을 운영 문서에 명시하는 것을 권고합니다. - 실제 운영 규모의 ledger row가 있는 환경에서
EXPLAIN ANALYZE로 source-filter 포함 query의 index 사용과 latency를 추가 관찰하는 것을 권고합니다.
현재 상태는 로컬 구현·검증·커밋 완료입니다. push·PR·배포·릴리스 완료를 의미하지 않습니다.