dcy-007(core 자율 안전 매도) 전체 delivery. BAT-010 기반 인프라가 미커밋 상태였고 BAT-011 트리거 레이어와 공유 파일에서 섞여 있어 한 커밋으로 묶음. BAT-010 (REQ-034/035/036/041, release-candidate): - WatchdogStore(application/watchdog.py) + snapshot RPC 워치독 갱신 - Slot stop_loss_price/take_profit_price 필드 + 004_add_price_thresholds.sql - SlotService.sell() 자율 매도 내부 경로 + idempotency - SafetySellConfig env 5종 파싱 BAT-011 (REQ-037/038/039/040/042, release-candidate): - SafetySellService(application/safety_sell.py): forced_close 만기 / stop-loss· take-profit KIS polling / 장 마감 강제 청산 + trex-safety-sell 7번째 스레드 - BrokerPort.get_current_price + KIS inquire-price(TTTC8397R/VTTC8397R, stck_prpr) + paper stub - SlotService.update_thresholds() + intent RPC update_thresholds 액션 (부분 갱신/null 해제, 워치독 last_seen_at 리셋) - baseline 3문서 정합(interface-contract/runtime-flows/project-structure) 거버넌스: REQ-034~042 Implemented 동기화, BAT-010/011 release-candidate, dcy-007 discovery 포함. 검증: 신규 38 테스트 green, 단위 236 passed/23 skipped, 인프라 게이트(PG+RabbitMQ) 259 passed(마이그레이션 001~004 round-trip 포함), ruff clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
4.8 KiB
4.8 KiB
req-036: 자동 매도 내부 경로 — SlotService.sell + idempotency
- Status: Implemented
- Type: Interface
- Priority: High
- Owner: project maintainers
Intent
자율 안전 매도 트리거가 RabbitMQ intent RPC를 거치지 않고 직접 슬롯 매도를 제출할 수 있도록 SlotService.sell() 내부 메서드를 추가한다. RabbitMQ 장애와 독립적으로 동작해야 하는 transport-independent 매도 경로다. 이미 pending_sell 상태인 슬롯에 대한 중복 트리거를 방지하는 idempotency도 함께 보장한다(dcy-007 FR-3, FR-4, A-1).
Requirement
SlotService는sell(slot_id, actor, reason)메서드를 제공해야 한다. 이 메서드는holding슬롯을pending_sell로 전이시키고 기존 outbox 내구성·execution 루프 경로를 따른다.sell()은 내부 함수 직접 호출이며 RabbitMQ intent RPC를 거치지 않는다.- 대상 슬롯이 이미
pending_sell상태이면sell()은 추가 전이 없이 조용히 반환하거나 멱등 응답을 반환해야 한다(중복 트리거 방지). - 대상 슬롯이
holding이 아니고pending_sell도 아닌 상태이면 적절한 예외 또는 오류 응답을 반환한다. sell()을 통해 제출된 매도는 기존executionworker의transit_slot(holding→pending_sell)+ broker dispatch + ledger 기록 경로를 재사용해야 한다.
Acceptance Criteria
- Given
holding상태의 슬롯 S가 있을 때, WhenSlotService.sell(S, actor="safety-sell", reason="stop_loss")를 호출하면, Then S의 상태가pending_sell로 전이된다. - Given
pending_sell상태의 슬롯 S가 있을 때, Whensell(S, ...)를 다시 호출하면, Then 슬롯 상태가 변경되지 않고 중복 매도 intent가 제출되지 않는다. - Given
idle상태의 슬롯 S가 있을 때, Whensell(S, ...)를 호출하면, Then 오류(예외 또는 rejected 응답)가 반환되고 슬롯 상태는 변경되지 않는다. - Given
sell()호출 성공 시, When execution worker가 이후 처리하면, Then 매도 주문이 broker에 제출되고 outbox 및 ledger 경로가 기존 intent RPC 경로와 동일하게 작동한다. - Given RabbitMQ transport가 불가용 상태일 때, When
sell()을 호출하면, Then transport 상태와 무관하게holding→pending_sell전이가 성공한다.
Impacted Area
- Docs: 없음 (런타임 흐름 변경은 REQ-037~039에서 발생, baseline 문서 갱신은 REQ-042 참조)
- Modules:
trex_core/domain/slot/service.py—SlotService.sell(slot_id, actor, reason)메서드 추가
- Tests:
SlotService.sell()단위 테스트 —holding→pending_sell전이 확인- idempotency 테스트 —
pending_sell슬롯 중복 호출 시 무전이 확인 - 잘못된 상태(
idle) 슬롯 호출 시 오류 반환 확인
Notes
sell()은transit_slot(slot_id, from_state=HOLDING, to_state=PENDING_SELL, ...)패턴 위에 구현한다. 기존 advisory lock + Postgres commit 보장이 그대로 적용된다.- NFR-2(자동 매도 실패 시 outbox retry): broker 오류 발생 시 execution worker의 기존 retry 경로를 따른다. 별도 retry 로직 불필요.
actor값은 트리거 구분을 위해"safety-sell","forced-close","market-close"등으로 구체화하는 것을 권장한다. 정확한 값은 batch 설계에서 결정한다.- 이 메서드는 dcy-007 FR-3의 "내부 자동 매도 trigger 경로"를 표준화한다. 이후 kill-switch Discovery(trex-core#3)에서도 재사용 가능하도록 격리한다.
Change Log
CHG-20260607-01
- Date: 2026-06-07
- Author: Justin Ko
Change Summary
- dcy-007 confirmed → REQ-036 초안 생성
Intent
- 자동 매도 내부 경로(FR-3, FR-4)를 독립 Interface REQ로 정규화
Acceptance Criteria Delta
- Added: AC-1~5 전체
Impacted Area Delta
- Modules: service.py (
sell()메서드 추가) - Tests: 단위 테스트 3종
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 배정