# BAT-022 Design - Status: draft - Batch: BAT-022 - Profile: standard ## 설계 목표 - snapshot envelope 에 슬롯 단위 read-only `slots[]` 를 additive 추가해, `trex-core slots` 가 universe 가 아닌 데몬의 실제 슬롯 상태를 표시하게 한다. strategy-facing `assets[]` 계약은 비파괴. ## 1. snapshot envelope `slots[]` 스키마 (REQ-028 AC-4) - envelope top-level 에 `slots` 키 추가(additive). 항상 배열, 비면 `[]`(null 금지). - 각 항목(per Slot, `slot_repo.list_slots(trading_date)` 기준): - `slot_id`: str (UUID) - `status`: str — `idle`|`pending_buy`|`holding`|`pending_sell`|`closed` (SlotState 값) - `symbol`: str|null - `qty`: float|null - `limit_price`: float|null (pending 주문 지정가; dcy-012 의 side-무관 필드) - `avg_price`: float|null (매수 체결가/평단) - `portfolio_id`: str|null (= asset_id) - **경계**: `assets[]`(portfolio 단위, strategy-facing, no-price)와 독립. `slots[]` 는 operator-facing 이라 가격(`limit_price`/`avg_price`) 노출 허용(REQ-028 AC-3 의 no-price 는 `assets[]` 한정). - meta(`view`/`available_slots`/`degraded`/`reason`)·`assets[]`·`watchdog[]` 불변. ## 2. envelope 산출 (`build_snapshot_envelope`, portfolio.py) - 기존 `assets[]`/`available_slots`/degraded 산출 유지. - `slots = [ _slot_to_dict(s) for s in slot_repo.list_slots(trading_date) ]` 추가, `to_dict()` payload 에 `"slots": slots` 동봉. - `_slot_to_dict` 는 Slot 모델 필드를 위 스키마로 매핑(없는 값은 null). - best-effort 불필요(순수 read, 외부 I/O 없음) — 단 예외가 envelope 산출 전체를 깨지 않도록 슬롯 매핑은 방어적으로. ## 3. CLI `slots` (REQ-032, cli.py `_cmd_slots`) - 요청 payload 는 기존대로 `actor="operator"`, `touch_watchdog=False`(비침습) 유지. - 응답에서 `slots = resp.get("slots", [])` 를 읽는다(기존 `assets` 대신). - `--status` 필터를 **슬롯 status 기준**으로 적용: - `all` → 전체, `holding`/`held` → status==holding, `buyable` → status==idle (가용 슬롯), (추가) `pending` → pending_buy|pending_sell 고려. - 매핑 표는 구현에서 확정(planning Design Gate (d)). - 출력: `instance=… view=… count= watchdog_owned=` 헤더 + 슬롯별 `slot_id status symbol qty limit_price/avg_price portfolio_id` + watchdog-owned 태그(slot.portfolio_id ↔ watchdog expired 매칭). - `--json` 은 envelope(또는 `slots`) 그대로 JSON. - `_cmd_universe` 는 `assets[]` 유지(변경 없음) — 두 명령 표면 분리. ## 4. watchdog 결합 - 기존 `watchdog[]`(expired by portfolio_id, dcy-017)와 `slots[]` 를 CLI 에서 결합: 슬롯의 `portfolio_id` 가 watchdog expired 집합에 있으면 `[WATCHDOG-OWNED: strategy absent]` 태그. ## 5. 문서 (interface-contract) - snapshot 응답 계약에 `slots[]` 필드(스키마 위와 동일) 추가. `assets[]` vs `slots[]` 구분(universe vs 데몬 슬롯) 명시. ## best-effort / 안전 - 본 변경은 read-only 노출 + CLI 표시라 매매·청산·워치독 판정에 영향 없음. 슬롯 도메인/전이 불변. ## 미해결/구현 확정 항목 - `--status` → 슬롯 status 매핑 최종표(특히 `buyable`/`pending` 의미). - `slots[]` 항목에 `trading_date` 포함 여부(현재 미포함, 요청이 단일 trading_date 라 불요).