REQ-056(영구 슬롯 스키마)+REQ-057(상태머신 재정의+인스턴스 lock) 토대 배치. - planning: delivery plan/Design Gate(R-cascade)/milestones/risks - design: R-cascade 실측(idle·closed/entry_count/전역 lock/trading_date 소비처) + 접근안 A/B/C → 안 B(점진/additive-first) 확정: * additive 스키마(instance_key·retired_at, entry_count/trading_date 유지→BAT-δ drop) * inactive 표준 + idle/closed 별칭(closed→idle 제거) * advisory lock 인스턴스 스코프화 * 부분 UNIQUE(instance_key, portfolio_id) WHERE portfolio_id NOT NULL * instance_key NOT NULL DEFAULT 'default' - batches/index BAT-027(standard, planning) 등록 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4.2 KiB
4.2 KiB
BAT-027 Planning
- Status: confirmed
- Batch: BAT-027
- Profile: standard
Included REQ
- REQ-056 (Data, Approved): 영구 슬롯 스키마 — portfolio_id 영구키·instance_key·retired_at·
UNIQUE(instance_key, portfolio_id), entry_count/슬롯 trading_date 제거 + 마이그레이션 009. - REQ-057 (Interface, Approved): 상태머신 재정의(inactive↔pending_buy↔holding↔pending_sell, closed→idle 제거) + holding 로컬 정본 + 인스턴스 스코프 advisory lock.
Delivery Plan
- REQ-056 도메인 모델:
models.pySlot재정의 —instance_key(str) 추가,retired_at: Optional[datetime]추가,entry_count제거,trading_date의미 재정의(슬롯 키 아님; 호환 위해 last_activity 성격으로 둘지 design 에서 확정).EXPECTED_SLOT_FIELDS정합. - REQ-056 persistence: 마이그레이션 009(
ALTER/신규 — instance_key NOT NULL·retired_at·UNIQUE(instance_key, portfolio_id), entry_count drop),postgresql.py_SLOT_COLUMNS/_row_to_slot/update_slot/insert 매핑 정합. 기존 행 전환은 본 배치 범위 밖(REQ-064). - REQ-057 상태머신:
state.py상태 집합{inactive, pending_buy, holding, pending_sell, error}+ 허용 전이 재정의(closed/idle→inactive,closed→idle제거).SLOT_ADVISORY_LOCK_ID→ 인스턴스 스코프 키(2-int advisory lock) 헬퍼. - REQ-057 서비스:
service.pyholding 로컬 set/clear, transit 인스턴스 스코프 lock 사용. 점유 필드 리셋 의미 재정의(종료=inactive 복귀). - 소비처 연쇄 정합(R-cascade): intents.py·safety_sell·snapshot_handlers·execution·reconciliation 등
idle/closed·entry_count·전역 lock 참조를 새 모델로 정합(컴파일·테스트 green 유지 범위). - 테스트: test_state(전이 집합)·test_contract(필드셋)·test_service 재작성 + 인스턴스 락 단위.
data-model.md슬롯 스키마/상태 부분 갱신(REQ-065 부분).- 단위 회귀 + ruff (+ test DSN 마이그레이션/드리프트).
Dependencies
- Internal: dcy-001/BAT-001 슬롯 도메인(재작성 대상), dcy-002/BAT-002 persistence(재작성 대상), dcy-019/BAT-025 entry_count(제거 대상).
- External: 없음(본 배치는 내부 도메인/스키마). 외부 전략 계약은 BAT-γ.
Design Gate
- Design Required Before Implementation: yes
- Reason: (a)
Slot모델·상태머신 변경이 intents/safety_sell/snapshot/execution/reconciliation 으로 연쇄(R-cascade) — 한 배치에서 어디까지 동시 수정해 green 을 유지할지 경계를 설계에서 확정해야 한다. (b)idle+closed→inactive합침과closed→idle제거가 기존 lifecycle(재진입·점유 리셋·daily_symbol_entries)과 교차 — 전이/리셋 의미를 못박아야 안전. (c) advisory lock 전역→인스턴스 스코프 전환은 단일 writer 불변식(REQ-002 NFR-1) 재정의라 락 키 설계 필요. (d)trading_date컬럼 drop vs 재의미·entry_count drop 의 스키마/계약 가드 영향. → design.md 를 채우고 구현 전 사용자 체크포인트.
Milestones
- M1 — REQ-056 모델+마이그레이션+persistence 매핑, 계약/드리프트 green
- M2 — REQ-057 상태머신+인스턴스 락, 전이/락 단위 green
- M3 — 소비처 연쇄 정합(전체 단위 green 회복)
- M4 — data-model.md 부분 갱신 + 회귀/ruff
Risks
- R-cascade (High): 모델/상태머신 변경의 소비처 연쇄로 광범위 회귀. 대응: design 에서 동시 수정 범위 확정, 단계별 단위 green 게이트, 기존 테스트 대량 갱신 인지.
- R-trading-date (Medium): trading_date 슬롯 키 제거가 일일 회계·kill-switch day-scope·transition_log 와 얽힘. 대응: design 에서 drop vs 재의미 결정, 회계 경로는 transition_log/ledger 로 이전.
- R-lock (Medium): 인스턴스 스코프 락 전환이 동시성 회귀. 대응: 2-int advisory lock + 경합 회귀 테스트.
Notes
- 라이브 데이터 불변(본 배치는 목표 스키마/모델 정의 + 신규 마이그레이션). 기존 행 cutover 는 BAT-δ(REQ-064).
- 본 배치 green 기준: 단위 전체 회귀(소비처 연쇄 정합 무누락). PG 마이그레이션/드리프트는 test DSN.