# ================================================================ # services/notification/app/models/notifications.py # ================================================================ """ Notification models for the notification service """ from sqlalchemy import Column, String, Text, Boolean, DateTime, JSON, Integer, Enum from sqlalchemy.dialects.postgresql import UUID from datetime import datetime import uuid import enum from shared.database.base import Base class NotificationType(enum.Enum): """Notification types supported by the service""" EMAIL = "email" WHATSAPP = "whatsapp" PUSH = "push" SMS = "sms" class NotificationStatus(enum.Enum): """Notification delivery status""" PENDING = "pending" SENT = "sent" DELIVERED = "delivered" FAILED = "failed" CANCELLED = "cancelled" class NotificationPriority(enum.Enum): """Notification priority levels""" LOW = "low" NORMAL = "normal" HIGH = "high" URGENT = "urgent" class Notification(Base): """Main notification record""" __tablename__ = "notifications" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True) sender_id = Column(UUID(as_uuid=True), nullable=False) recipient_id = Column(UUID(as_uuid=True), nullable=True) # Null for broadcast # Notification details type = Column(Enum(NotificationType), nullable=False) status = Column(Enum(NotificationStatus), default=NotificationStatus.PENDING, index=True) priority = Column(Enum(NotificationPriority), default=NotificationPriority.NORMAL) # Content subject = Column(String(255), nullable=True) message = Column(Text, nullable=False) html_content = Column(Text, nullable=True) template_id = Column(String(100), nullable=True) template_data = Column(JSON, nullable=True) # Delivery details recipient_email = Column(String(255), nullable=True) recipient_phone = Column(String(20), nullable=True) delivery_channel = Column(String(50), nullable=True) # Scheduling scheduled_at = Column(DateTime, nullable=True) sent_at = Column(DateTime, nullable=True) delivered_at = Column(DateTime, nullable=True) # Metadata log_metadata = Column(JSON, nullable=True) error_message = Column(Text, nullable=True) retry_count = Column(Integer, default=0) max_retries = Column(Integer, default=3) # Tracking broadcast = Column(Boolean, default=False) read = Column(Boolean, default=False) read_at = Column(DateTime, nullable=True) # Timestamps created_at = Column(DateTime, default=datetime.utcnow, index=True) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) class NotificationTemplate(Base): """Email and notification templates""" __tablename__ = "notification_templates" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) tenant_id = Column(UUID(as_uuid=True), nullable=True, index=True) # Null for system templates # Template identification template_key = Column(String(100), nullable=False, unique=True) name = Column(String(255), nullable=False) description = Column(Text, nullable=True) category = Column(String(50), nullable=False) # alert, marketing, transactional # Template content type = Column(Enum(NotificationType), nullable=False) subject_template = Column(String(255), nullable=True) body_template = Column(Text, nullable=False) html_template = Column(Text, nullable=True) # Configuration language = Column(String(2), default="es") is_active = Column(Boolean, default=True) is_system = Column(Boolean, default=False) # System templates can't be deleted # Metadata default_priority = Column(Enum(NotificationPriority), default=NotificationPriority.NORMAL) required_variables = Column(JSON, nullable=True) # List of required template variables # Timestamps created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) class NotificationPreference(Base): """User notification preferences""" __tablename__ = "notification_preferences" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) user_id = Column(UUID(as_uuid=True), nullable=False, unique=True, index=True) tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True) # Email preferences email_enabled = Column(Boolean, default=True) email_alerts = Column(Boolean, default=True) email_marketing = Column(Boolean, default=False) email_reports = Column(Boolean, default=True) # WhatsApp preferences whatsapp_enabled = Column(Boolean, default=False) whatsapp_alerts = Column(Boolean, default=False) whatsapp_reports = Column(Boolean, default=False) # Push notification preferences push_enabled = Column(Boolean, default=True) push_alerts = Column(Boolean, default=True) push_reports = Column(Boolean, default=False) # Timing preferences quiet_hours_start = Column(String(5), default="22:00") # HH:MM format quiet_hours_end = Column(String(5), default="08:00") timezone = Column(String(50), default="Europe/Madrid") # Frequency preferences digest_frequency = Column(String(20), default="daily") # none, daily, weekly max_emails_per_day = Column(Integer, default=10) # Language preference language = Column(String(2), default="es") # Timestamps created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) class NotificationLog(Base): """Detailed logging for notification delivery attempts""" __tablename__ = "notification_logs" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) notification_id = Column(UUID(as_uuid=True), nullable=False, index=True) # Attempt details attempt_number = Column(Integer, nullable=False) status = Column(Enum(NotificationStatus), nullable=False) # Provider details provider = Column(String(50), nullable=True) # e.g., "gmail", "twilio" provider_message_id = Column(String(255), nullable=True) provider_response = Column(JSON, nullable=True) # Timing attempted_at = Column(DateTime, default=datetime.utcnow) response_time_ms = Column(Integer, nullable=True) # Error details error_code = Column(String(50), nullable=True) error_message = Column(Text, nullable=True) # Additional metadata log_metadata = Column(JSON, nullable=True)