Files
site11/services/notifications/backend/models.py
2025-09-28 20:41:57 +09:00

201 lines
7.4 KiB
Python

"""
Data models for Notification Service
"""
from pydantic import BaseModel, Field
from datetime import datetime
from typing import Optional, List, Dict, Any, Literal
from enum import Enum
class NotificationChannel(str, Enum):
"""Notification delivery channels"""
EMAIL = "email"
SMS = "sms"
PUSH = "push"
IN_APP = "in_app"
class NotificationStatus(str, Enum):
"""Notification status"""
PENDING = "pending"
SENT = "sent"
DELIVERED = "delivered"
READ = "read"
FAILED = "failed"
CANCELLED = "cancelled"
class NotificationPriority(str, Enum):
"""Notification priority levels"""
LOW = "low"
NORMAL = "normal"
HIGH = "high"
URGENT = "urgent"
class NotificationCategory(str, Enum):
"""Notification categories"""
SYSTEM = "system"
MARKETING = "marketing"
TRANSACTION = "transaction"
SOCIAL = "social"
SECURITY = "security"
UPDATE = "update"
class Notification(BaseModel):
"""Notification model"""
id: Optional[str] = Field(None, description="Unique notification ID")
user_id: str = Field(..., description="Target user ID")
title: str = Field(..., description="Notification title")
message: str = Field(..., description="Notification message")
channel: NotificationChannel = Field(..., description="Delivery channel")
status: NotificationStatus = Field(default=NotificationStatus.PENDING)
priority: NotificationPriority = Field(default=NotificationPriority.NORMAL)
category: NotificationCategory = Field(default=NotificationCategory.SYSTEM)
data: Optional[Dict[str, Any]] = Field(default=None, description="Additional data")
template_id: Optional[str] = Field(None, description="Template ID if using template")
scheduled_at: Optional[datetime] = Field(None, description="Scheduled delivery time")
sent_at: Optional[datetime] = Field(None, description="Actual sent time")
delivered_at: Optional[datetime] = Field(None, description="Delivery confirmation time")
read_at: Optional[datetime] = Field(None, description="Read time")
retry_count: int = Field(default=0, description="Number of retry attempts")
error_message: Optional[str] = Field(None, description="Error message if failed")
created_at: datetime = Field(default_factory=datetime.now)
updated_at: datetime = Field(default_factory=datetime.now)
class Config:
json_encoders = {
datetime: lambda v: v.isoformat()
}
class NotificationTemplate(BaseModel):
"""Notification template model"""
id: Optional[str] = Field(None, description="Template ID")
name: str = Field(..., description="Template name")
channel: NotificationChannel = Field(..., description="Target channel")
category: NotificationCategory = Field(..., description="Template category")
subject_template: Optional[str] = Field(None, description="Subject template (for email)")
body_template: str = Field(..., description="Body template with variables")
variables: List[str] = Field(default_factory=list, description="List of required variables")
metadata: Dict[str, Any] = Field(default_factory=dict, description="Template metadata")
is_active: bool = Field(default=True, description="Template active status")
created_at: datetime = Field(default_factory=datetime.now)
updated_at: datetime = Field(default_factory=datetime.now)
class Config:
json_encoders = {
datetime: lambda v: v.isoformat()
}
class NotificationPreference(BaseModel):
"""User notification preferences"""
user_id: str = Field(..., description="User ID")
channels: Dict[NotificationChannel, bool] = Field(
default_factory=lambda: {
NotificationChannel.EMAIL: True,
NotificationChannel.SMS: False,
NotificationChannel.PUSH: True,
NotificationChannel.IN_APP: True
}
)
categories: Dict[NotificationCategory, bool] = Field(
default_factory=lambda: {
NotificationCategory.SYSTEM: True,
NotificationCategory.MARKETING: False,
NotificationCategory.TRANSACTION: True,
NotificationCategory.SOCIAL: True,
NotificationCategory.SECURITY: True,
NotificationCategory.UPDATE: True
}
)
quiet_hours: Optional[Dict[str, str]] = Field(
default=None,
description="Quiet hours configuration {start: 'HH:MM', end: 'HH:MM'}"
)
timezone: str = Field(default="UTC", description="User timezone")
language: str = Field(default="en", description="Preferred language")
email_frequency: Literal["immediate", "daily", "weekly"] = Field(default="immediate")
updated_at: datetime = Field(default_factory=datetime.now)
class Config:
json_encoders = {
datetime: lambda v: v.isoformat()
}
class NotificationHistory(BaseModel):
"""Notification history entry"""
notification_id: str
user_id: str
channel: NotificationChannel
status: NotificationStatus
title: str
message: str
sent_at: Optional[datetime]
delivered_at: Optional[datetime]
read_at: Optional[datetime]
error_message: Optional[str]
metadata: Dict[str, Any] = Field(default_factory=dict)
class Config:
json_encoders = {
datetime: lambda v: v.isoformat()
}
class CreateNotificationRequest(BaseModel):
"""Request model for creating notification"""
user_id: str
title: str
message: str
channels: List[NotificationChannel] = Field(default=[NotificationChannel.IN_APP])
priority: NotificationPriority = Field(default=NotificationPriority.NORMAL)
category: NotificationCategory = Field(default=NotificationCategory.SYSTEM)
data: Optional[Dict[str, Any]] = None
template_id: Optional[str] = None
schedule_at: Optional[datetime] = None
class BulkNotificationRequest(BaseModel):
"""Request model for bulk notifications"""
user_ids: List[str]
title: str
message: str
channels: List[NotificationChannel] = Field(default=[NotificationChannel.IN_APP])
priority: NotificationPriority = Field(default=NotificationPriority.NORMAL)
category: NotificationCategory = Field(default=NotificationCategory.SYSTEM)
data: Optional[Dict[str, Any]] = None
template_id: Optional[str] = None
class DeviceToken(BaseModel):
"""Device token for push notifications"""
user_id: str
token: str
device_type: Literal["ios", "android", "web"]
app_version: Optional[str] = None
created_at: datetime = Field(default_factory=datetime.now)
updated_at: datetime = Field(default_factory=datetime.now)
class Config:
json_encoders = {
datetime: lambda v: v.isoformat()
}
class NotificationStats(BaseModel):
"""Notification statistics"""
total_sent: int
total_delivered: int
total_read: int
total_failed: int
delivery_rate: float
read_rate: float
channel_stats: Dict[str, Dict[str, int]]
category_stats: Dict[str, Dict[str, int]]
period: str
class NotificationEvent(BaseModel):
"""Notification event for tracking"""
event_type: Literal["sent", "delivered", "read", "failed", "clicked"]
notification_id: str
user_id: str
channel: NotificationChannel
timestamp: datetime = Field(default_factory=datetime.now)
metadata: Dict[str, Any] = Field(default_factory=dict)
class Config:
json_encoders = {
datetime: lambda v: v.isoformat()
}