본문으로 건너뛰기

알림 서비스 (Notification)

개요

알림 서비스는 사용자에게 다양한 채널(푸시, 이메일, SMS)을 통해 알림을 발송합니다. 주문/결제/배송 이벤트를 구독하여 자동으로 알림을 생성하고, OpenSearch를 통해 알림 이력을 검색할 수 있습니다.

항목
언어Python 3.11
프레임워크FastAPI
데이터베이스DocumentDB (MongoDB 호환)
검색OpenSearch
네임스페이스mall-services
포트8000
헬스체크GET /health

아키텍처

API 엔드포인트

알림 API

메서드경로설명
GET/api/v1/notifications/{user_id}사용자 알림 목록
POST/api/v1/notifications/send알림 발송

요청/응답 예시

사용자 알림 목록

요청:

GET /api/v1/notifications/user_001?limit=50

응답:

{
"notifications": [
{
"id": "notif_001",
"user_id": "user_001",
"channel": "PUSH",
"subject": "주문이 완료되었습니다",
"message": "주문번호 ORD-2024-001의 주문이 정상적으로 완료되었습니다. 배송 준비 중입니다.",
"status": "SENT",
"created_at": "2024-01-15T10:00:00Z",
"sent_at": "2024-01-15T10:00:05Z",
"metadata": {
"order_id": "ORD-2024-001",
"event_type": "order.completed"
}
},
{
"id": "notif_002",
"user_id": "user_001",
"channel": "EMAIL",
"subject": "배송이 시작되었습니다",
"message": "주문하신 상품이 CJ대한통운을 통해 발송되었습니다. 송장번호: 1234567890123",
"status": "SENT",
"created_at": "2024-01-15T14:00:00Z",
"sent_at": "2024-01-15T14:00:03Z",
"metadata": {
"order_id": "ORD-2024-001",
"carrier": "CJ대한통운",
"tracking_number": "1234567890123"
}
},
{
"id": "notif_003",
"user_id": "user_001",
"channel": "PUSH",
"subject": "배송이 완료되었습니다",
"message": "주문하신 상품이 배송 완료되었습니다. 상품 리뷰를 작성해주세요!",
"status": "SENT",
"created_at": "2024-01-16T14:00:00Z",
"sent_at": "2024-01-16T14:00:02Z",
"metadata": {
"order_id": "ORD-2024-001",
"event_type": "shipping.delivered"
}
}
],
"total": 3
}

알림 발송

요청:

POST /api/v1/notifications/send
Content-Type: application/json

{
"user_id": "user_001",
"channel": "PUSH",
"subject": "특별 할인 이벤트",
"message": "관심 상품이 30% 할인 중입니다! 지금 확인하세요.",
"metadata": {
"campaign_id": "PROMO-2024-001",
"product_id": "prod_001"
}
}

응답:

{
"id": "notif_004",
"user_id": "user_001",
"channel": "PUSH",
"status": "SENT",
"created_at": "2024-01-15T11:00:00Z"
}

데이터 모델

NotificationChannel (Enum)

class NotificationChannel(str, Enum):
EMAIL = "EMAIL" # 이메일
SMS = "SMS" # 문자 메시지
PUSH = "PUSH" # 푸시 알림

NotificationStatus (Enum)

class NotificationStatus(str, Enum):
PENDING = "PENDING" # 대기 중
SENT = "SENT" # 발송 완료
FAILED = "FAILED" # 발송 실패

Notification

class Notification(BaseModel):
id: str
user_id: str
channel: NotificationChannel
subject: str
message: str
status: NotificationStatus = NotificationStatus.PENDING
created_at: datetime
sent_at: Optional[datetime] = None
metadata: Optional[dict] = None

NotificationRequest

class NotificationRequest(BaseModel):
user_id: str
channel: NotificationChannel
subject: str
message: str
metadata: Optional[dict] = None

NotificationResponse

class NotificationResponse(BaseModel):
id: str
user_id: str
channel: NotificationChannel
status: NotificationStatus
created_at: datetime

NotificationListResponse

class NotificationListResponse(BaseModel):
notifications: list[Notification]
total: int

이벤트 (Kafka)

구독 토픽

토픽이벤트알림 내용
orders.*주문 이벤트주문 접수/확정/취소 알림
payments.*결제 이벤트결제 완료/실패/환불 알림
shipping.*배송 이벤트배송 출발/도착/완료 알림

이벤트 컨슈머 설정

consumer_configs = [
("orders.*", "notification-orders-consumer", handle_order_event),
("payments.*", "notification-payments-consumer", handle_payment_event),
("shipping.*", "notification-shipping-consumer", handle_shipping_event),
]

이벤트별 알림 템플릿

이벤트제목메시지
order.created주문이 접수되었습니다주문번호 {order_id}가 접수되었습니다.
order.confirmed주문이 확정되었습니다주문번호 {order_id}가 확정되어 배송 준비 중입니다.
payment.completed결제가 완료되었습니다{amount}원 결제가 완료되었습니다.
payment.failed결제에 실패했습니다결제 처리 중 문제가 발생했습니다. 다시 시도해주세요.
shipping.picked_up상품이 발송되었습니다{carrier}를 통해 상품이 발송되었습니다. 송장번호: {tracking}
shipping.out_for_delivery배송이 시작되었습니다오늘 중 상품이 도착할 예정입니다.
shipping.delivered배송이 완료되었습니다상품이 배송 완료되었습니다. 리뷰를 작성해주세요!

환경 변수

변수명설명기본값
SERVICE_NAME서비스 이름notification
PORT서비스 포트8080
AWS_REGIONAWS 리전us-east-1
REGION_ROLE리전 역할 (PRIMARY/SECONDARY)PRIMARY
DB_HOSTDocumentDB 호스트localhost
DB_PORTDocumentDB 포트27017
DB_USER데이터베이스 사용자mall
DB_PASSWORD데이터베이스 비밀번호-
DOCUMENTDB_HOSTDocumentDB 호스트localhost
DOCUMENTDB_PORTDocumentDB 포트27017
KAFKA_BROKERSKafka 브로커 주소localhost:9092
OPENSEARCH_ENDPOINTOpenSearch 엔드포인트http://localhost:9200
LOG_LEVEL로그 레벨info

서비스 의존성

의존하는 서비스

  • DocumentDB: 알림 데이터 저장
  • OpenSearch: 알림 이력 검색
  • MSK Kafka: 이벤트 구독
  • User Profile Service: 사용자 알림 선호도 조회

의존받는 서비스

  • API Gateway: 사용자 알림 센터 표시

기능 상세

알림 채널별 특성

채널용도특성
PUSH즉시 알림앱 설치 필수, 실시간성 높음
EMAIL상세 정보주문 확인서, 영수증 첨부 가능
SMS중요 알림배송 완료, 인증번호 등

알림 우선순위

  1. 긴급 (Urgent): 결제 실패, 주문 취소 - 모든 채널 동시 발송
  2. 높음 (High): 배송 시작/완료 - PUSH + EMAIL
  3. 보통 (Normal): 주문 확정 - PUSH 또는 EMAIL
  4. 낮음 (Low): 프로모션 - 사용자 설정에 따름

사용자 알림 설정 연동

User Profile 서비스의 preferences 필드 참조:

{
"notification_email": true,
"notification_push": true,
"notification_sms": false
}

재시도 정책

  • 발송 실패 시 최대 3회 재시도
  • 지수 백오프: 1분 -> 5분 -> 30분
  • 3회 실패 후 FAILED 상태로 변경