[BE-17] paper 격리 보장 + E2E 시나리오

작업 내용 (설계 의도)

변경 사항

토스에 sandbox가 없어 paper 안전성은 우리 코드가 유일한 방어선이다. 그 방어선이 실제로 서 있는지를 상시 검증하는 테스트와, 핵심 실패 경로 E2E 시나리오를 만든다.

격리 보장 테스트 2종 (PRD FR-35 / ADR-003):

  1. PaperTradeExecutor 생성자에 OrderGateway·ConditionalOrderGateway 타입이 없음을 리플렉션으로 검증한다. 누군가 나중에 주입하면 이 테스트가 깨진다.
  2. paper 모드로 전체 사이클을 돌렸을 때 MockWebServer에 도착한 토스 요청 수가 0건임을 검증한다.

E2E 시나리오 — 해피 패스보다 실패 경로를 우선한다. 이 시스템의 목적이 “손실이 한도를 넘지 않는 것”이기 때문이다.

의존

  • BE-16 (통합 배선)

다이어그램

처리 흐름

sequenceDiagram
    participant Test as E2E 시나리오
    participant Cycle as 사이클
    participant Pos as 포지션
    participant Day as 거래일
    Test->>Cycle: 신호 투입
    Cycle->>Pos: 자동 매수 체결
    Test->>Pos: 손절가 도달
    Pos->>Day: 실현손실 기록
    Day-->>Test: 일일 한도 도달 → 당일 중단

클래스 의존

flowchart LR
    Isolation[격리 보장 테스트] --> Paper[PaperTradeExecutor]
    Isolation --> Mock[MockWebServer 요청수 0]
    E2E[E2E 시나리오] --> Ctl[AutoTradingApiController]
    E2E --> Sch[스케줄러]

테스트 케이스

  • PaperTradeExecutor 생성자에 Gateway 타입 파라미터가 존재하지 않는다(리플렉션).
  • paper 사이클 전체에서 토스 요청이 0건이다(MockWebServer 카운트).
  • 신호 → 제안 → 자동 집행 → 손절 발동 → 실현손익 기록이 순서대로 완료된다.
  • 일일 손실 한도 도달 → 당일 신규 매수 중단 → 익일 개장 시 자동 해제된다.
  • 킬 스위치 작동 → 미체결 취소 + 제안 무효화 + 신규 주문 0건.
  • OCO 등록 실패 → 즉시 청산되어 손절 없는 포지션이 남지 않는다.
  • 프로세스 재기동 후 포지션·한도 소진량이 복구된다.