[STK7-04] BE — SSE 현재가·등락율 실시간 전송

작업 내용 (설계 의도)

변경 사항

현재 SSE는 "refresh" 문자열만 전송하여 FE가 별도로 GET /api/v1/stocks/prices REST API를 추가 호출해야 한다. SseEmitterRegistry.broadcastRefresh()broadcast(prices: List<StockPriceCache>)로 변경해 실제 가격 데이터를 JSON 배열로 직접 푸시한다.

StockPriceScheduler에서 sync 후 캐시된 전체 가격을 조회해 broadcast에 전달하도록 연동한다.

SSE event 형식:

  • event name: price-updated (기존 유지)
  • data: [{"symbol":"005930","lastPrice":"61500","changeRate":"-1.27","changeAmount":"-790"}, ...]

변경 파일:

  • stock/presentation/SseEmitterRegistry.ktbroadcastRefresh()broadcast(prices) 리팩토링
  • stock/domain/StockDomainService.ktsyncPrices() 반환값 추가 또는 getAllCachedPrices() 추가
  • stock/application/SyncStocksUseCase.kt — prices 반환하도록 수정
  • stock/presentation/StockPriceScheduler.kt — prices를 broadcast에 전달

다이어그램

처리 흐름

sequenceDiagram
    participant Sch as StockPriceScheduler
    participant UC as SyncStocksUseCase
    participant DS as StockDomainService
    participant Cache as StockPriceCacheRepository
    participant Sse as SseEmitterRegistry
    participant FE as FE (SSE Client)

    Sch->>UC: executeAndReturn()
    UC->>DS: syncPrices()
    DS->>Cache: upsertAll(prices)
    DS->>Cache: findAll()
    Cache-->>DS: List<StockPriceCache>
    DS-->>UC: List<StockPriceCache>
    UC-->>Sch: List<StockPriceCache>
    Sch->>Sse: broadcast(prices)
    Sse->>FE: SSE event(price-updated, JSON[])

클래스 의존

flowchart LR
    Scheduler["StockPriceScheduler"] --> SyncUC["SyncStocksUseCase"]
    Scheduler --> SseReg["SseEmitterRegistry"]
    SyncUC --> StockDS["StockDomainService"]
    StockDS --> PriceCacheRepo["StockPriceCacheRepository"]

테스트 케이스

  • broadcast(prices) 호출 시 연결된 emitter에 JSON 배열 포함 SSE event 전송된다
  • broadcast(emptyList()) 호출 시 [] data로 event 전송된다
  • 전송 중 예외 발생한 emitter는 emitters 목록에서 제거된다
  • 정상 emitter에게는 예외 발생 emitter와 무관하게 전송이 완료된다
  • SSE event name이 price-updated로 유지된다
  • StockPriceScheduler가 30초 주기로 syncAndBroadcast() 실행 후 prices가 SSE로 전송된다
  • SyncStocksUseCase.executeAndReturn()이 캐시 저장 후 전체 캐시 목록을 반환한다