[STK1-04] 알림 채널 (Discord·Mac·Composite)

작업 내용 (설계 의도)

변경 사항

  • NotificationGateway interface + Discord·Mac 구현 + CompositeNotificationGateway(@Primary).
  • Discord: webhook {"content":...} POST. Mac: osascript -e 'display notification...'.
  • Composite가 활성화된 채널을 모두 호출 — 채널 추가 시 구현체만 등록.
  • 한 채널 실패가 다른 채널 전송을 막지 않도록 예외를 채널 단위로 처리.

의존

  • 선행: STK1-02
  • 후행: STK1-05

롤백

  • DISCORD_ENABLED/MAC_NOTIFICATION_ENABLED 환경변수 OFF로 채널 비활성.

다이어그램

처리 흐름

sequenceDiagram
    participant DS as PriceAlertDomainService
    participant CMP as CompositeNotificationGateway
    participant DIS as DiscordNotificationGateway
    participant MAC as MacNotificationGateway

    DS->>CMP: notify(message)
    par Discord 전송
        CMP->>DIS: notify(message)
        DIS->>DIS: POST webhook
    and Mac 전송
        CMP->>MAC: notify(message)
        MAC->>MAC: osascript
    end
    Note over CMP: 채널 실패 시 로그 후 계속 진행
    CMP-->>DS: 완료

클래스 의존

flowchart LR
    subgraph Domain["domain"]
        NGW[NotificationGateway]
    end
    subgraph Infra["infrastructure"]
        CMP["CompositeNotificationGateway (@Primary)"]
        DIS[DiscordNotificationGateway]
        MAC[MacNotificationGateway]
    end
    CMP -.->|implements| NGW
    DIS -.->|implements| NGW
    MAC -.->|implements| NGW
    CMP --> DIS
    CMP --> MAC

테스트 케이스

  • Composite는 Discord·Mac 양쪽 채널에 메시지를 모두 전송한다.
  • DISCORD_ENABLED=false이면 Discord를 건너뛰고 Mac만 전송한다.
  • Discord webhook 호출이 실패해도 Mac 채널 전송은 계속 진행된다.
  • 모든 채널이 비활성이면 예외 없이 정상 종료된다.
  • Discord 채널은 webhook URL에 {"content": "메시지"} JSON을 POST한다.