Skip to main content

개요

Subscription Service는 VPMS 클러스터의 실시간 데이터 구독 및 알림 시스템을 담당하는 서비스입니다. GraphQL Subscription을 통해 숙박시설 관련 이벤트를 실시간으로 전달하며, 키오스크 및 대시보드 간의 실시간 통신을 지원합니다.

주요 기능

실시간 알림

숙박시설 이벤트 실시간 구독 및 알림

키오스크 통신

키오스크 시스템 상태 및 명령 실시간 전달

이벤트 발행

숙박시설 및 키오스크 알림 발행

데이터 스트림

객실 상태, 인증 요청 등 실시간 데이터 스트림

API 도메인

알림 관리 (Notification)

실시간 알림 구독 및 발행 기능을 제공합니다.
  • 알림 API: 숙박시설 알림, 키오스크 시스템 알림, 데이터 구독

기술 스택

  • API 타입: GraphQL (Apollo Federation) + WebSocket
  • 프레임워크: Fastify + TypeScript
  • 데이터베이스: PostgreSQL + Prisma ORM
  • 실시간 통신: GraphQL Subscription (PubSub)
  • 이벤트 소싱: EventStore

GraphQL Endpoint

HTTP Endpoint

POST https://development.vpms.io/graphql

WebSocket Endpoint (Subscription)

WS wss://development.vpms.io/graphql
GraphQL 공통 설정 및 인증 방법은 GraphQL 설정 가이드를 참고하세요.
Subscription Service는 Apollo Federation의 서브그래프로 동작하며, API Gateway를 통해 통합된 스키마로 접근할 수 있습니다.

실시간 구독 흐름

1

WebSocket 연결

GraphQL Subscription을 위한 WebSocket 연결 수립
2

구독 시작

accommodationSubscription 또는 dataSubscription으로 실시간 구독 시작
3

이벤트 수신

서버에서 발생하는 이벤트를 실시간으로 수신
4

알림 처리

수신된 알림을 UI에 표시하거나 후속 처리 수행

예제: 실시간 알림 구독

import { ApolloClient, InMemoryCache, split, HttpLink } from '@apollo/client';
import { GraphQLWsLink } from '@apollo/client/link/subscriptions';
import { createClient } from 'graphql-ws';
import { getMainDefinition } from '@apollo/client/utilities';
import { gql } from '@apollo/client';

// HTTP 링크 설정
const httpLink = new HttpLink({
  uri: 'https://development.vpms.io/graphql',
  headers: {
    authorization: `Bearer ${accessToken}`,
  },
});

// WebSocket 링크 설정
const wsLink = new GraphQLWsLink(
  createClient({
    url: 'wss://development.vpms.io/graphql',
    connectionParams: {
      authorization: `Bearer ${accessToken}`,
    },
  })
);

// HTTP와 WebSocket 링크 분기
const splitLink = split(
  ({ query }) => {
    const definition = getMainDefinition(query);
    return (
      definition.kind === 'OperationDefinition' &&
      definition.operation === 'subscription'
    );
  },
  wsLink,
  httpLink
);

const client = new ApolloClient({
  link: splitLink,
  cache: new InMemoryCache(),
});

// 숙박시설 알림 구독
const ACCOMMODATION_SUBSCRIPTION = gql`
  subscription OnAccommodationNotification($accommodationId: ID!) {
    accommodationSubscription(accommodationId: $accommodationId) {
      id
      type
      priority
      dotType
      description
      template
      objective
      relative
      roomTypeId
      createdAt
      data
    }
  }
`;

// 구독 시작
const subscription = client.subscribe({
  query: ACCOMMODATION_SUBSCRIPTION,
  variables: {
    accommodationId: '01HQKS9V8X',
  },
}).subscribe({
  next: ({ data }) => {
    console.log('새 알림:', data.accommodationSubscription);

    // 우선순위에 따른 처리
    const notification = data.accommodationSubscription;
    if (notification.priority >= 3) {
      // 긴급 알림 (빨강)
      showUrgentAlert(notification);
    } else if (notification.priority === 2) {
      // 경고 알림 (노랑)
      showWarning(notification);
    } else {
      // 일반 알림 (초록)
      showInfo(notification);
    }
  },
  error: (error) => {
    console.error('구독 에러:', error);
  },
});

// 데이터 구독 (객실 상태, 인증 요청 등)
const DATA_SUBSCRIPTION = gql`
  subscription OnDataEvent($accommodationId: ID!) {
    dataSubscription(accommodationId: $accommodationId) {
      type
      data
    }
  }
`;

client.subscribe({
  query: DATA_SUBSCRIPTION,
  variables: {
    accommodationId: '01HQKS9V8X',
  },
}).subscribe({
  next: ({ data }) => {
    const event = data.dataSubscription;
    const eventData = JSON.parse(event.data);

    switch (event.type) {
      case 'RoomState':
        updateRoomState(eventData.id, eventData.stateUpdatedAt);
        break;
      case 'AuthRequest':
        handleAuthRequest(eventData);
        break;
      default:
        console.log('알 수 없는 이벤트:', event.type);
    }
  },
});

알림 타입

Subscription Service는 다양한 유형의 알림을 지원합니다:

숙박시설 알림 (AccommodationNotification)

  • 체크인 알림: 고객 체크인 완료 시
  • 긴급 알림: 예약 누락, 시스템 오류 등
  • 인증 요청: 키오스크 인증 요청
  • 객실 상태 변경: 청소 완료, 정비 필요 등

키오스크 시스템 알림 (KioskSystemNotification)

  • 시스템 명령: 키오스크 제어 명령
  • 상태 업데이트: 연결 상태, 동작 상태

데이터 이벤트 (DataEvent)

  • 객실 상태: 실시간 객실 상태 변경
  • 인증 이벤트: 인증 요청 및 처리 상태

우선순위 시스템

알림은 우선순위(priority)에 따라 분류됩니다:
우선순위dotType설명용도
1success일반정보성 알림, 정상 처리 완료
2warning경고주의가 필요한 상황
3+error긴급즉각적인 조치가 필요한 상황
nulldisabled비활성처리 완료된 알림

알림 템플릿

자주 사용되는 알림 템플릿:
  • ROOM_CHECKED_IN: 객실 체크인 완료
  • RESERVATION_MISSED_HANDLED: 예약 누락 처리 완료
  • AUTH_REQUESTED: 키오스크 인증 요청
  • AUTH_REQUEST_CHECKIN: 체크인 인증 요청
  • AUTH_REQUEST_CHECKOUT: 체크아웃 인증 요청

보안 및 권한

숙박시설 알림 구독

  • 권한: MAID 이상 (청소 담당자 권한)
  • 해당 숙박시설에 대한 관리 권한 필요

키오스크 시스템 구독

  • 권한: 키오스크 자체 인증 필요
  • 해당 키오스크 ID와 토큰 일치 확인

데이터 구독

  • 권한: MAID 이상
  • 해당 숙박시설에 대한 관리 권한 필요

연결 상태 관리

Subscription Service는 키오스크의 연결 상태를 자동으로 관리합니다:
  • 연결 시: 키오스크 연결 상태 connected로 업데이트
  • 구독 활성화: WebSocket 연결 유지 중 실시간 알림 수신
  • 연결 해제 시: 자동으로 연결 상태 업데이트
WebSocket 연결이 끊어지면 자동으로 재연결하는 로직을 클라이언트에 구현해야 합니다.

관련 서비스

지원

문의사항이 있으시면 [email protected]로 연락주세요.