Files
trex-core/docs/srs/Interface/req-036_auto-sell-internal-path.md
T
genichinandClaude Opus 4.8 a30efa8f3b feat(safety-sell): dcy-007 core 자율 안전 매도 — BAT-010 기반 + BAT-011 트리거
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>
2026-06-07 08:32:30 +09:00

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()을 통해 제출된 매도는 기존 execution worker의 transit_slot(holding→pending_sell) + broker dispatch + ledger 기록 경로를 재사용해야 한다.

Acceptance Criteria

  1. Given holding 상태의 슬롯 S가 있을 때, When SlotService.sell(S, actor="safety-sell", reason="stop_loss") 를 호출하면, Then S의 상태가 pending_sell로 전이된다.
  2. Given pending_sell 상태의 슬롯 S가 있을 때, When sell(S, ...) 를 다시 호출하면, Then 슬롯 상태가 변경되지 않고 중복 매도 intent가 제출되지 않는다.
  3. Given idle 상태의 슬롯 S가 있을 때, When sell(S, ...) 를 호출하면, Then 오류(예외 또는 rejected 응답)가 반환되고 슬롯 상태는 변경되지 않는다.
  4. Given sell() 호출 성공 시, When execution worker가 이후 처리하면, Then 매도 주문이 broker에 제출되고 outbox 및 ledger 경로가 기존 intent RPC 경로와 동일하게 작동한다.
  5. 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 배정