feat: add portfolio snapshot read layer

This commit is contained in:
2026-06-06 09:33:00 +09:00
parent 56e977a7ad
commit ca757009f5
51 changed files with 3565 additions and 51 deletions
@@ -0,0 +1,135 @@
# req-027: portfolio-hub read 포트 + 어댑터 + stub
- Status: Implemented
- Type: Integration
- Priority: High
- Owner: project maintainers
## Intent
- 전략 모듈에 제공할 종목 스냅샷의 원천인 portfolio-hub universe(자신이 관리하는 portfolio 집합)를 trex-core 가 read 할 경로를 만든다. dcy-004 write 어댑터/자격증명을 재사용하고 도메인 순수성을 유지한다.
## Requirement
- `PortfolioHubReadPort.get_portfolios(daemon_id)` application 포트 + portfolio-hub read 어댑터(`managed_by_daemon_id` 스코프 조회, portfolio-hub `list_portfolios_v1`) + 결정론 stub 를 제공한다.
- 어댑터는 dcy-004 의 portfolio-hub 자격증명(.env `TREX_PORTFOLIO_HUB_*`)을 재사용한다.
- `daemon_id` 는 portfolio-hub 자격증명/인증 토큰에서 도출한다(단일 진실원). 별도 `TREX_DAEMON_ID` 설정값을 1차 출처로 두지 않으며, 필요 시 whoami 1회로 도출·캐시한다.
- 각 universe 항목은 symbol, asset_id(=portfolio_id), cash_balance, asset_quantity, active_strategy_id, 전략파라미터(opaque JSON)를 담고 가격(price)은 제외한다. 전략파라미터는 trex-core 가 해석하지 않고 통과시킨다.
## Acceptance Criteria
1. Given daemon 자격증명/토큰, When `get_portfolios` 를 호출, Then `managed_by_daemon_id == 토큰 daemon_id` 인 portfolio 집합을 항목당 symbol/asset_id/cash_balance/asset_quantity/active_strategy_id/strategy_params(opaque) 형태로 반환하고 가격 필드는 없다.
2. Given 결정론 stub 어댑터, When 호출, Then 네트워크 없이 고정된 universe 를 반환한다.
3. Given import 스윕, When `trex_core/domain` 을 검사, Then portfolio-hub/네트워크 의존이 0 이다(NFR-1).
4. Given `TREX_DAEMON_ID` 미설정, When daemon 기동·universe 조회, Then 토큰에서 도출한 daemon_id 로 동작한다(OQ-7).
## Impacted Area
- Docs: docs/discovery/dcy-005_20260604_portfolio-hub-asset-snapshot-api.md, docs/interface-contract.md
- Modules: trex_core/application (read 포트), trex_core/adapters/portfolio (read 어댑터 + stub), trex_core/runtime/config (daemon_id 토큰 도출)
- Tests: stub read 통합테스트, 도메인 import 스윕, daemon_id 토큰 도출
## Notes
- 가정: portfolio-hub `list_portfolios_v1`(`GET`)이 `managed_by_daemon_id=auth.daemon_id` 로 스코프 조회를 제공하고 `PortfolioItem` 에 cash_balance/asset_quantity 포함(confirm-discovery 에서 검증). 전략파라미터는 portfolio-hub `strategy_params` JSONB(dcy-005 A-5).
- NFR-1(도메인 순수성)을 본 REQ 의 AC-3 로 흡수한다.
## Change Log
### CHG-20260606-01
- Date: 2026-06-06
- Author: project maintainers
#### Change Summary
- dcy-005 FR-4 + OQ-7 분해로 최초 생성(Proposed). NFR-1 흡수.
#### Intent
- portfolio-hub universe read 경로를 포트/어댑터/stub 로 정의.
#### Acceptance Criteria Delta
- Added:
- AC-1~4 신규
- Updated:
- none
- Removed:
- none
#### Impacted Area Delta
- Docs:
- dcy-005, interface-contract 참조
- Modules:
- application read 포트, adapters/portfolio
- Tests:
- stub read 통합테스트, import 스윕
#### Delivery Trace Delta
- Batches:
- none (미배치)
- Releases:
- none
#### Revalidation Impact
- Reverification Needed: no
- Existing Implementation Invalidated: no
- Status Recommendation: keep-current
- Follow-up Action: confirm-req 로 승인 게이트 점검
#### Validation Plan
- stub read 통합테스트 + 도메인 import 스윕으로 AC 검증.
### CHG-20260606-02
- Date: 2026-06-06
- Author: project maintainers
#### Change Summary
- 승인 게이트 통과 → Proposed → Approved.
#### Acceptance Criteria Delta
- Added: none
- Updated: none
- Removed: none
#### Impacted Area Delta
- 변경 없음
#### Delivery Trace Delta
- Batches: none
- Releases: none
#### Revalidation Impact
- Reverification Needed: no
- Existing Implementation Invalidated: no
- Status Recommendation: keep-current
- Follow-up Action: suggest-batch-reqs / draft-batch
#### Validation Plan
- 승인 기록. 구현 전 재검증 불필요.
### CHG-20260606-03
- Date: 2026-06-06
- Author: Justin Ko
#### Change Summary
- Status 변경: Approved → Implemented. BAT-008 release-candidate verification evidence 기반.
#### Intent
- `PortfolioHubReadPort` + 어댑터(`PortfolioHubReadAdapter`, `StubPortfolioRead`) 구현과 검증 evidence 확보 후 구현 완료 상태로 동기화.
#### Acceptance Criteria Delta
- Added/Updated/Removed: 없음
#### Impacted Area Delta
- Docs/Modules/Tests: 없음
#### Delivery Trace Delta
- Batches:
- BAT-008 (release-candidate)
- Releases:
- none
#### Revalidation Impact
- Reverification Needed: no
- Existing Implementation Invalidated: no
- Status Recommendation: Implemented
- Follow-up Action: release 단계는 별도 진행
#### Validation Plan
- AC-1: tests/adapters/portfolio/test_hub_read.py::test_get_portfolios_scoped_by_managed_by_daemon_id + test_stub_read.py.
- AC-2: tests/adapters/portfolio/test_stub_read.py 전체.
- AC-3: tests/domain/test_domain_import_sweep.py.
- AC-4: tests/adapters/portfolio/test_hub_read.py::test_whoami_returns_token_daemon_id.
@@ -0,0 +1,135 @@
# req-030: 일일 스냅샷 스케줄러 + 옵션 D 현금/포지션 갱신
- Status: Approved
- Type: Integration
- Priority: High
- Owner: project maintainers
## Intent
- universe 멤버십·전략파라미터는 일일 스냅샷으로 고정하고, 현금/포지션은 portfolio-hub 가 ledger write 응답으로 돌려주는 권위 값으로 유지해 로컬 누적 보정 drift 를 제거한다(옵션 D).
## Requirement
- 설정 가능한 시각(기본 07:30 KST, .env)에 스케줄러(신규 daemon 컴포넌트)가 `daemon_id` universe 를 페치해 스냅샷을 갱신한다. universe 멤버십·전략파라미터는 그 일일 스냅샷으로 고정한다.
- 현금/포지션은 스냅샷 baseline 에 더해, 체결 시 portfolio-hub ledger write 응답의 `cash_balance_after` / `asset_quantity_after` 권위 값으로 해당 자산을 갱신한다.
## Acceptance Criteria
1. Given 설정 시각 도래, When 스케줄러 tick, Then universe 를 페치해 스냅샷(멤버십·전략파라미터·baseline 현금/포지션)을 갱신한다.
2. Given 체결 후 ledger write 응답이 `*_after` 를 반환, When 처리, Then 해당 자산의 현금/포지션을 그 권위 값으로 갱신한다.
3. Given `duplicate` write 응답(idempotent), When 처리, Then 현재 권위 `*_after` 값으로 동일하게 갱신한다.
## Impacted Area
- Docs: docs/discovery/dcy-005_20260604_portfolio-hub-asset-snapshot-api.md, docs/runtime-flows.md
- Modules: 일일 스냅샷 스케줄러(런타임 신규), ledger write 응답 소비/스냅샷 갱신 로직, config(스냅샷 페치 시각)
- Tests: 스케줄 tick 페치, `*_after` 갱신, duplicate idempotent 갱신
## Notes
- **의존: portfolio-hub#8 — ledger write 응답에 `cash_balance_after`/`asset_quantity_after` 반환(회계 단일 트랜잭션). portfolio-hub 배포(REL-003 등) 전까지 본 REQ 의 옵션 D 갱신 구현은 대기(dcy-005 A-7).** 그 전까지는 baseline + 스케줄러 페치까지만 선구현 가능.
- A-6(유일 매매 주체·장중 외부 변동 없음) 전제.
- NFR-2(일관성)를 본 REQ 로 흡수한다.
## Change Log
### CHG-20260606-01
- Date: 2026-06-06
- Author: project maintainers
#### Change Summary
- dcy-005 FR-6 + OQ-2 분해로 최초 생성(Proposed). NFR-2 흡수.
#### Intent
- 일일 스냅샷 스케줄러 + 옵션 D 현금/포지션 갱신 정의.
#### Acceptance Criteria Delta
- Added:
- AC-1~3 신규
- Updated:
- none
- Removed:
- none
#### Impacted Area Delta
- Docs:
- dcy-005, runtime-flows
- Modules:
- 스냅샷 스케줄러, write 응답 소비 로직, config
- Tests:
- 스케줄 tick, *_after 갱신
#### Delivery Trace Delta
- Batches:
- none
- Releases:
- none
#### Revalidation Impact
- Reverification Needed: no
- Existing Implementation Invalidated: no
- Status Recommendation: keep-current
- Follow-up Action: portfolio-hub#8 배포 추적 후 옵션 D 구현 착수
#### Validation Plan
- 스케줄 tick 페치 + `*_after` 갱신/idempotent 갱신 테스트로 AC 검증.
### CHG-20260606-02
- Date: 2026-06-06
- Author: project maintainers
#### Change Summary
- 승인 게이트 통과 → Proposed → Approved. 옵션 D 구현은 portfolio-hub#8 배포 후 착수(Notes 의존 유지, 비블로커).
#### Acceptance Criteria Delta
- Added: none
- Updated: none
- Removed: none
#### Impacted Area Delta
- 변경 없음
#### Delivery Trace Delta
- Batches: none
- Releases: none
#### Revalidation Impact
- Reverification Needed: no
- Existing Implementation Invalidated: no
- Status Recommendation: keep-current
- Follow-up Action: suggest-batch-reqs / draft-batch; 옵션 D 구현은 portfolio-hub#8 배포 트래킹 후
#### Validation Plan
- 승인 기록. 스케줄러 baseline 구현 → portfolio-hub#8 배포 후 옵션 D 갱신 통합 검증.
### CHG-20260606-03
- Date: 2026-06-06
- Author: Justin Ko
#### Change Summary
- Status 유지: Approved. BAT-008 에서 AC-1(일일 스냅샷 스케줄러 baseline)은 구현 완료 + evidence 확보, AC-2/AC-3(옵션 D `*_after` 갱신)은 외부 의존(portfolio-hub#8) 배포 대기로 **deferred**. 본 REQ 는 AC 일부 충족이므로 `Implemented` 전환을 보류한다(SRS `Status Transition Evidence` 의 "미충족 Acceptance Criteria 가 있으면 Implemented 로 전환하지 않는다" 규정 준수).
#### Intent
- 스케줄러 baseline 부분 구현 완료를 추적 + 옵션 D 후속 작업의 wiring point 가 노출되어 있음을 기록.
#### Acceptance Criteria Delta
- Added/Updated/Removed: 없음
#### Impacted Area Delta
- Docs/Modules/Tests: 없음 (AC-1 baseline 은 BAT-008 에서 구현 + 검증 완료, AC-2/AC-3 wiring point 노출만 추가)
#### Delivery Trace Delta
- Batches:
- BAT-008 (release-candidate; AC-1 evidence)
- Releases:
- none
#### Revalidation Impact
- Reverification Needed: yes (portfolio-hub#8 배포 후 AC-2/AC-3 통합 검증)
- Existing Implementation Invalidated: no
- Status Recommendation: keep-current (Approved 유지)
- Follow-up Action: portfolio-hub#8 배포 완료 알림 수신 시 별도 minor-change batch 로 옵션 D 구현 (LedgerWriter 의 ledger write 응답 소비 경로에서 `cash_balance_after`/`asset_quantity_after` → `SnapshotStore.update_cash_position(...)` 호출 1줄 추가) + AC-2/AC-3 통합 evidence 확보 → REQ-030 Approved → Implemented 전환.
#### Validation Plan
- AC-1 (현재 완료): tests/application/test_snapshot_scheduler.py::test_run_once_fetches_universe_and_swaps_store + ::test_swap_preserves_warning_for_carried_over_portfolio + 실 daemon boot 후 첫 fetch 동작 확인.
- AC-2 (deferred): portfolio-hub#8 배포 후 ledger write 응답 소비 경로에 wiring 연결 + integration 테스트.
- AC-3 (deferred): duplicate write 응답 idempotent 갱신 테스트.
#### Notes
- BAT-008 verification.md `Human Approval Memo` 에 deferred residual risk 로 명시되어 있고, batch 전체는 release-candidate 로 promote 됨.