[STK2-07] 캐시 + /signals API

작업 내용 (설계 의도)

변경 사항

  • cache.py TtlCache(in-memory, key별 value·timestamp).
  • GET /signals/{symbol}에 종목별 TTL(SIGNAL_CACHE_TTL 기본 600초) 적용.
  • 콜드 ~6s → hit ~1s.

의존

  • 선행: STK2-06
  • 후행: 없음

다이어그램

처리 흐름

sequenceDiagram
    participant Client as FE / 호출자
    participant API as main.py
    participant CA as TtlCache
    participant SVC as signal_service
    Client->>API: GET /signals/{symbol}
    API->>CA: get(symbol)
    alt 캐시 hit (TTL 이내)
        CA-->>API: Signal (캐시됨)
    else 캐시 miss 또는 만료
        API->>SVC: build_signal(symbol)
        SVC-->>API: Signal
        API->>CA: set(symbol, Signal)
    end
    API-->>Client: Signal JSON

클래스 의존

flowchart LR
    subgraph Presentation["Presentation"]
        main["main.py (GET /signals/{symbol})"]
    end
    subgraph Infra["Infrastructure"]
        cache["cache.py (TtlCache)"]
    end
    subgraph Application["Application"]
        signal_service["signal_service.py"]
    end
    subgraph Config["Config"]
        config["config.py (SIGNAL_CACHE_TTL)"]
    end
    main --> cache
    main --> signal_service
    cache --> config

테스트 케이스

  • TTL 이내 재조회 시 build_signal을 호출하지 않고 캐시된 값을 반환한다.
  • TTL 만료 후 재조회 시 build_signal을 새로 호출한다.
  • 서로 다른 종목의 캐시는 독립적으로 관리된다.
  • SIGNAL_CACHE_TTL=0 으로 설정하면 매 요청마다 재계산한다.
  • 미등록 symbol 요청 시 404를 반환한다.