feat(slots): additive strategy fields + filter (REQ-116, BAT-055)

trex.slots.req wire 계약 additive 확장 — 기존 소비자(orb/tsl) backward compatible.

- PortfolioItem: strategy_name(Optional[str]) + markets(list) 필드 추가
- hub_read.py: get_portfolios()에서 strategy_name/markets 파싱 추가 (safe default)
- slot_to_dict(): strategy_name/strategy_params/markets 3필드 row에 추가 (SnapshotStore→PortfolioItem 경유)
- make_slots_rpc_handler(): strategy 요청 파라미터 → Python 레벨 후처리 필터 (available_slots 계산 이후, REQ-073 AC-6 불변)
- 테스트: AC-1~8 전수 + hub_read 파싱 + 회귀 갱신 (777 passed, 47 skipped)
- docs/interface-contract.md: 요청 파라미터·응답 행 스키마·소스 테이블·REQ-074 AC-5 주석 갱신

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
This commit is contained in:
2026-07-04 11:10:01 +09:00
co-authored by Claude Fable 5
parent 5267e72efe
commit 690071afad
13 changed files with 714 additions and 12 deletions
+5
View File
@@ -160,6 +160,9 @@ class PortfolioHubReadAdapter:
pid = str(raw.get("portfolio_id") or raw.get("asset_id") or "")
if not pid:
continue
# REQ-116 (BAT-055): parse strategy_name and markets additively.
# Absent keys or wrong types → safe defaults (None / []).
raw_markets = raw.get("markets")
out.append(PortfolioItem(
portfolio_id=pid,
symbol=str(raw.get("symbol") or ""),
@@ -167,6 +170,8 @@ class PortfolioHubReadAdapter:
asset_quantity=float(raw.get("asset_quantity") or 0.0),
active_strategy_id=raw.get("active_strategy_id") or None,
strategy_params=dict(raw.get("strategy_params") or {}),
strategy_name=raw.get("strategy_name") or None,
markets=list(raw_markets) if isinstance(raw_markets, list) else [],
))
return out