Add models for EmailTemplate, ActivityLog, and NotificationLog

Introduced new database models to handle email templates, activity logs, and notification logs, including relevant enums and utilities. Updated ER diagram to reflect new relationships and attributes, enhancing event tracking and notification management capabilities.
This commit is contained in:
2025-02-27 19:54:26 +01:00
parent 7247190f5f
commit 9d71fc7fcd
5 changed files with 342 additions and 4 deletions

View File

@@ -0,0 +1,87 @@
from datetime import datetime, timezone
from enum import Enum
from sqlalchemy import Column, String, ForeignKey, Enum as SQLEnum, Text, DateTime
from sqlalchemy.dialects.postgresql import UUID, JSONB
from sqlalchemy.orm import relationship
from .base import Base, TimestampMixin, UUIDMixin
class NotificationType(str, Enum):
EMAIL = "email"
SMS = "sms"
PUSH = "push"
IN_APP = "in_app"
class NotificationStatus(str, Enum):
QUEUED = "queued"
SENT = "sent"
DELIVERED = "delivered"
FAILED = "failed"
OPENED = "opened"
CLICKED = "clicked"
class NotificationLog(Base, UUIDMixin, TimestampMixin):
__tablename__ = 'notification_logs'
# Notification Details
notification_type = Column(SQLEnum(NotificationType), nullable=False)
status = Column(SQLEnum(NotificationStatus), nullable=False, default=NotificationStatus.QUEUED)
# Content
subject = Column(String)
content_preview = Column(String(255)) # Short preview of content
template_id = Column(UUID(as_uuid=True), ForeignKey('email_templates.id'))
# Recipient Information
event_id = Column(UUID(as_uuid=True), ForeignKey('events.id'), nullable=False)
guest_id = Column(UUID(as_uuid=True), ForeignKey('guests.id')) # Optional, if sent to a specific guest
recipient = Column(String, nullable=False) # Email address or phone number
# Tracking
sent_at = Column(DateTime(timezone=True))
delivered_at = Column(DateTime(timezone=True))
opened_at = Column(DateTime(timezone=True))
error_message = Column(Text)
retry_count = Column(Integer, default=0)
external_id = Column(String) # ID from external provider (SendGrid, Twilio, etc.)
# Additional Data
metadata = Column(JSONB, default=dict)
# Relationships
event = relationship("Event")
guest = relationship("Guest")
template = relationship("EmailTemplate")
def __repr__(self):
return f"<NotificationLog {self.notification_type.value} to {self.recipient} status={self.status.value}>"
def mark_sent(self):
"""Mark notification as sent"""
self.status = NotificationStatus.SENT
self.sent_at = datetime.now(timezone.utc)
def mark_delivered(self):
"""Mark notification as delivered"""
self.status = NotificationStatus.DELIVERED
self.delivered_at = datetime.now(timezone.utc)
def mark_opened(self):
"""Mark notification as opened"""
self.status = NotificationStatus.OPENED
self.opened_at = datetime.now(timezone.utc)
def mark_failed(self, error: str):
"""Mark notification as failed with error message"""
self.status = NotificationStatus.FAILED
self.error_message = error
self.retry_count += 1
@property
def can_retry(self):
"""Check if notification can be retried (fewer than 3 attempts)"""
return self.status == NotificationStatus.FAILED and self.retry_count < 3