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>
6.6 KiB
6.6 KiB
req-040: update_thresholds intent RPC 액션
- Status: Implemented
- Type: Interface
- Priority: High
- Owner: project maintainers
Intent
전략 모듈이 매수 이후에도 손절·익절 임계값과 강제 만기 시각을 갱신할 수 있도록 trex.intent.req 채널에 action: "update_thresholds" 메시지 액션을 추가한다. 수신 시 해당 슬롯의 stop_loss_price·take_profit_price·forced_close_at를 DB에 갱신하고, 해당 슬롯의 워치독 last_seen_at을 현재 시각으로 리셋해 전략 모듈 활성 신호로 활용한다(dcy-007 FR-7).
Requirement
- 시스템은
trex.intent.req채널의action: "update_thresholds"메시지를 처리해야 한다. - 메시지 payload는
{action: "update_thresholds", slot_id, stop_loss_price?, take_profit_price?, forced_close_at?}형식이며, 세 필드는 각각 독립적으로 포함하거나 생략할 수 있다. 생략된 필드는 현재 값을 유지한다. - 처리 성공 시 요청한 필드를 DB에 갱신하고 해당 슬롯의 워치독
last_seen_at을 현재 시각으로 리셋해야 한다. - 대상 슬롯이
holding상태인 경우에만 갱신을 수행한다. - 대상 슬롯이
holding이 아닌 경우의 처리(무시 또는 에러 응답)는 구현 시 결정한다(OQ-6 Deferred — 선택 옵션:{status: ignored, reason: "not_holding"}응답 또는 silent discard). reply_to가 있으면 갱신 결과({status: updated|ignored, slot_id})를 응답으로 반환한다.
Acceptance Criteria
- Given
holding상태의 슬롯 S가 있을 때, When{action: "update_thresholds", slot_id: S, stop_loss_price: 50000}을trex.intent.req에 발행하면, Then S의stop_loss_price가50000으로 DB에 갱신된다. - Given
holding상태의 슬롯 S가 있을 때, When{action: "update_thresholds", slot_id: S, take_profit_price: 80000, forced_close_at: "2026-06-07T15:10:00+09:00"}를 발행하면, Then S의take_profit_price와forced_close_at가 DB에 갱신된다. - Given
holding상태의 슬롯 S가 있을 때, Whenupdate_thresholds를 수신하면, Then S의 워치독last_seen_at이 현재 시각으로 리셋된다. - Given
update_thresholds메시지에stop_loss_price만 포함되고take_profit_price와forced_close_at는 생략될 때, When 처리되면, Thenstop_loss_price만 갱신되고 나머지 두 필드는 기존 값을 유지한다. - Given
null값으로stop_loss_price: null을 명시할 때, When 처리되면, Thenstop_loss_price가NULL로 갱신된다(임계값 해제). - Given 대상 슬롯이
holding이 아닌 상태일 때, Whenupdate_thresholds를 수신하면, Then 슬롯 필드가 변경되지 않는다.reply_to가 있으면{status: ignored, reason: "not_holding"}응답을 반환한다(OQ-6 구현 결정). - Given
reply_to가 있는 요청에서 갱신이 성공하면, When 처리가 완료되면, Then{status: updated, slot_id}가reply_to로 반환된다.
Impacted Area
- Docs:
docs/interface-contract.md—update_thresholdsaction 계약 추가 (REQ-042 참조)
- Modules:
trex_core/application/messaging_handlers.py—make_intent_rpc_handler확장:update_thresholdsaction 라우팅 + DB 갱신 +last_seen_at리셋trex_core/domain/slot/service.py—SlotService.update_thresholds(slot_id, stop_loss_price, take_profit_price, forced_close_at)메서드 추가
- Tests:
update_thresholdshandler 단위 테스트 — holding 슬롯 갱신 확인, last_seen_at 리셋 확인- 필드 부분 갱신 테스트 (일부만 포함된 payload)
- null 값 처리 테스트
- non-holding 슬롯 무시 테스트
Notes
- OQ-6(Deferred → REQ AC):
holding이 아닌 슬롯 요청 처리 방식. 구현 시{status: ignored, reason: "not_holding"}응답 반환을 권장한다. silent discard도 허용되며 batch에서 결정한다. update_thresholds수신은 워치독last_seen_at리셋을 겸한다. 전략 모듈이 임계값을 갱신하면 활성 신호로 처리돼 그 시점부터TREX_WATCHDOG_TIMEOUT타이머가 재시작된다(REQ-034).- 기존 intent RPC dedup(
intent_log.try_insert) 적용 여부는 batch 설계에서 결정한다.update_thresholds는 상태 read-modify가 아닌 idempotent SET이므로 dedup 생략이 적절할 수 있다.
Change Log
CHG-20260607-01
- Date: 2026-06-07
- Author: Justin Ko
Change Summary
- dcy-007 confirmed → REQ-040 초안 생성
Intent
- update_thresholds intent RPC 액션(FR-7)을 독립 Interface REQ로 정규화. OQ-6 Deferred 처리 방식을 AC-6에 명시.
Acceptance Criteria Delta
- Added: AC-1~7 전체
Impacted Area Delta
- Docs: interface-contract.md (REQ-042에서 처리)
- Modules: messaging_handlers.py (handler 확장), service.py (
update_thresholds()추가) - Tests: handler 단위 테스트 4종
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 배정
CHG-20260607-03
- Date: 2026-06-07
- Author: Justin Ko
Change Summary
- Status Approved → Implemented (confirm-req-implemented, 근거 batch BAT-011 release-candidate).
Intent
- BAT-011 verification.md 의 AC↔evidence(
update_thresholds부분 갱신·null 해제·last_seen_at 리셋·non-holding ignored·미존재 slot_not_found·updated 응답)로 AC-1~7 충족 → 구현 완료 동기화. OQ-6 은 AC-6 의{ignored, not_holding}응답으로 확정 구현.
Acceptance Criteria Delta
- (변경 없음)
Impacted Area Delta
- (변경 없음)
Delivery Trace Delta
- Batches: BAT-011 (release-candidate)
- Releases: none
Revalidation Impact
- Reverification Needed: no
- Existing Implementation Invalidated: no
- Status Recommendation: keep-current (Implemented)
- Follow-up Action: draft-release 로 BAT-011 배포 편성.