Initial commit - cleaned repository

This commit is contained in:
jungwoo choi
2025-09-28 20:41:57 +09:00
commit e3c28f796a
188 changed files with 28102 additions and 0 deletions

View File

@ -0,0 +1,201 @@
"""
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()
}