Spaces:
Runtime error
Runtime error
refactor(notification-ms): migrate templates to company-level and integrate merchant context
f773f54 | """ | |
| Notification models and Pydantic schemas. | |
| """ | |
| import uuid | |
| from datetime import datetime | |
| from typing import Optional, List, Dict, Any | |
| from enum import Enum | |
| from pydantic import BaseModel, Field | |
| class NotificationChannel(str, Enum): | |
| WHATSAPP = "whatsapp" | |
| EMAIL = "email" | |
| SMS = "sms" | |
| PUSH = "push" | |
| class NotificationStatus(str, Enum): | |
| PENDING = "pending" | |
| QUEUED = "queued" | |
| SENDING = "sending" | |
| SENT = "sent" | |
| DELIVERED = "delivered" | |
| FAILED = "failed" | |
| class NotificationPriority(str, Enum): | |
| LOW = "low" | |
| NORMAL = "normal" | |
| HIGH = "high" | |
| CRITICAL = "critical" | |
| # --- Request Schemas --- | |
| class SendNotificationRequest(BaseModel): | |
| """Send a notification via one or more channels.""" | |
| recipient: str = Field(..., description="Phone number (with country code) or email") | |
| channels: List[NotificationChannel] = Field( | |
| default=[NotificationChannel.WHATSAPP], | |
| description="Delivery channels" | |
| ) | |
| template_name: str = Field(..., description="Template identifier") | |
| template_data: Dict[str, Any] = Field(default_factory=dict) | |
| priority: NotificationPriority = Field(default=NotificationPriority.NORMAL) | |
| source: Optional[str] = Field(None, description="Originating microservice") | |
| merchant_id: str = Field(..., description="Merchant ID (required for credential lookup)") | |
| merchant_name: Optional[str] = Field("", description="Merchant name (injected into template variables at dispatch)") | |
| metadata: Optional[Dict[str, Any]] = None | |
| class SendBatchRequest(BaseModel): | |
| """Send notifications to multiple recipients.""" | |
| notifications: List[SendNotificationRequest] = Field( | |
| ..., min_length=1, max_length=100 | |
| ) | |
| class ListNotificationsRequest(BaseModel): | |
| """List notifications with filters and projection support.""" | |
| filters: Optional[Dict[str, Any]] = Field(default_factory=dict) | |
| skip: int = Field(default=0, ge=0) | |
| limit: int = Field(default=50, ge=1, le=200) | |
| projection_list: Optional[List[str]] = Field( | |
| None, description="List of fields to include in response" | |
| ) | |
| # --- Response Schemas --- | |
| class SendNotificationResponse(BaseModel): | |
| success: bool | |
| notification_id: str | |
| message: str | |
| channels: List[str] | |
| class SendBatchResponse(BaseModel): | |
| success: bool | |
| total: int | |
| queued: int | |
| failed: int | |
| results: List[SendNotificationResponse] | |
| class NotificationDetail(BaseModel): | |
| notification_id: str | |
| recipient: str | |
| channels: List[str] | |
| template_name: str | |
| template_data: Dict[str, Any] = {} | |
| status: str | |
| priority: str = "normal" | |
| source: Optional[str] = None | |
| merchant_id: Optional[str] = None | |
| merchant_name: Optional[str] = None | |
| channel_results: Dict[str, Any] = {} | |
| retry_count: int = 0 | |
| created_at: Optional[datetime] = None | |
| updated_at: Optional[datetime] = None | |
| sent_at: Optional[datetime] = None | |
| class ListNotificationsResponse(BaseModel): | |
| success: bool = True | |
| total: int | |
| skip: int | |
| limit: int | |
| data: List[Any] | |
| # --- MongoDB Document Shape --- | |
| def new_notification_doc(req: SendNotificationRequest) -> Dict[str, Any]: | |
| now = datetime.utcnow() | |
| return { | |
| "notification_id": str(uuid.uuid4()), | |
| "recipient": req.recipient, | |
| "channels": [ch.value for ch in req.channels], | |
| "template_name": req.template_name, | |
| "template_data": req.template_data, | |
| "priority": req.priority.value, | |
| "status": NotificationStatus.QUEUED.value, | |
| "source": req.source, | |
| "merchant_id": req.merchant_id, | |
| "merchant_name": req.merchant_name or "", | |
| "metadata": req.metadata or {}, | |
| "channel_results": {}, | |
| "retry_count": 0, | |
| "created_at": now, | |
| "updated_at": now, | |
| "sent_at": None, | |
| } | |