# req-035: 슬롯 가격 임계값 도메인 필드 + DB 마이그레이션 - Status: Implemented - Type: Data - Priority: High - Owner: project maintainers ## Intent stop-loss(손절)·take-profit(익절) 가격 트리거를 지원하기 위해 슬롯 도메인 모델에 `stop_loss_price: Optional[Decimal]`과 `take_profit_price: Optional[Decimal]` 필드를 추가하고, PostgreSQL 스키마에 해당 컬럼을 additive 마이그레이션으로 추가한다(dcy-007 코드 영향 — 필드 추가 + DB 마이그레이션). ## Requirement - 슬롯 도메인 모델(`SlotModel` / `Slot`)에 `stop_loss_price: Optional[Decimal]`과 `take_profit_price: Optional[Decimal]` 필드를 추가해야 한다. 기본값은 `None`이다. - PostgreSQL `slots` 테이블에 `stop_loss_price NUMERIC` 및 `take_profit_price NUMERIC` 컬럼을 NULL 허용으로 추가하는 마이그레이션을 제공해야 한다. 기존 슬롯 행은 `NULL`로 유지된다. - 매수 intent(`BuyIntent` / `IntentIn`) payload에 `stop_loss_price`와 `take_profit_price` 필드를 선택 항목으로 추가해야 한다. 미설정 시 `None`으로 처리한다. - persistence 레이어(PostgreSQL 어댑터)는 두 필드를 읽기·쓰기 대상에 포함해야 한다. ## Acceptance Criteria 1. Given `SlotModel` 인스턴스를 생성할 때 `stop_loss_price`와 `take_profit_price`를 지정하지 않으면, When 필드를 조회하면, Then 두 필드 모두 `None`이다. 2. Given `stop_loss_price=Decimal("50000")`으로 슬롯을 생성해 Postgres에 저장하면, When 같은 슬롯을 다시 조회하면, Then `stop_loss_price`가 `Decimal("50000")`으로 복원된다. 3. Given 기존 슬롯 row가 마이그레이션 전에 존재하면, When 마이그레이션을 실행하면, Then 기존 row의 `stop_loss_price`와 `take_profit_price`가 `NULL`이고 마이그레이션이 멱등하게 완료된다. 4. Given 매수 intent payload에 `stop_loss_price`와 `take_profit_price`를 포함하면, When `IntentService.submit_buy`를 호출하면, Then 해당 슬롯의 두 필드가 저장된다. 5. Given 매수 intent payload에 두 필드가 없으면, When `submit_buy`를 호출하면, Then 두 필드는 `None`으로 저장되고 오류가 발생하지 않는다. ## Impacted Area - Docs: - `docs/interface-contract.md` — intent RPC payload에 `stop_loss_price`, `take_profit_price` 선택 필드 추가 (REQ-042 참조) - Modules: - `trex_core/domain/slot/models.py` — `stop_loss_price`, `take_profit_price` 필드 추가 - `trex_core/adapters/persistence/postgresql.py` — 두 필드 read/write 포함 - `trex_core/adapters/persistence/sql/` — 마이그레이션 스크립트 추가 - `trex_core/application/intents.py` — `IntentIn`(또는 `BuyIntent`)에 두 필드 추가 - `trex_core/application/messaging_handlers.py` — intent RPC payload 파싱에 두 필드 추가 - Tests: - 슬롯 도메인 모델 단위 테스트 — 필드 기본값 및 직렬화 확인 - persistence 통합 테스트 — 저장·조회 라운드트립 확인 - 마이그레이션 멱등성 테스트 ## Notes - `Decimal` 타입을 사용해 부동소수점 오차 없이 가격을 표현한다. - `take_profit_price`와 `stop_loss_price` 값의 논리적 유효성(예: take_profit > stop_loss)은 이번 REQ 범위 밖이다. REQ 단계에서 추가 필요 시 change-req로 처리한다. - 기존 `forced_close_at` 필드는 이미 존재하며 이 REQ에서 다루지 않는다. ## Change Log ### CHG-20260607-01 - Date: 2026-06-07 - Author: Justin Ko #### Change Summary - dcy-007 confirmed → REQ-035 초안 생성 #### Intent - 가격 임계값 필드 추가 + DB 마이그레이션을 독립 Data REQ로 정규화 #### Acceptance Criteria Delta - Added: AC-1~5 전체 #### Impacted Area Delta - Docs: interface-contract.md (REQ-042에서 처리) - Modules: models.py, postgresql.py, sql 마이그레이션, intents.py, messaging_handlers.py - Tests: 도메인 단위 + persistence 통합 + 마이그레이션 멱등성 #### 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 후 batch 배정 ### CHG-20260607-02 - Date: 2026-06-07 - Author: Justin Ko #### Change Summary - Proposed → Approved (confirm-req) #### Intent - 승인 게이트 통과: 필수 필드·AC·Impacted Area·Change Log 완비 확인. dcy-007(confirmed) 범위 및 결정 사항과 모순 없음. #### Acceptance Criteria Delta - (변경 없음) #### 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 후 batch 배정