Files
Hotel-Booking/Backend/src/models/notification.py
Iliyan Angelov 627959f52b updates
2025-11-23 18:59:18 +02:00

126 lines
6.3 KiB
Python

from sqlalchemy import Column, Integer, String, DateTime, Boolean, Text, Enum, ForeignKey, JSON
from sqlalchemy.orm import relationship
from datetime import datetime
import enum
from ..config.database import Base
class NotificationChannel(str, enum.Enum):
email = 'email'
sms = 'sms'
push = 'push'
whatsapp = 'whatsapp'
in_app = 'in_app'
class NotificationStatus(str, enum.Enum):
pending = 'pending'
sent = 'sent'
delivered = 'delivered'
failed = 'failed'
read = 'read'
class NotificationType(str, enum.Enum):
booking_confirmation = 'booking_confirmation'
payment_receipt = 'payment_receipt'
pre_arrival_reminder = 'pre_arrival_reminder'
check_in_reminder = 'check_in_reminder'
check_out_reminder = 'check_out_reminder'
marketing_campaign = 'marketing_campaign'
loyalty_update = 'loyalty_update'
system_alert = 'system_alert'
custom = 'custom'
class Notification(Base):
__tablename__ = 'notifications'
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
user_id = Column(Integer, ForeignKey('users.id'), nullable=True) # Nullable for system-wide notifications
notification_type = Column(Enum(NotificationType), nullable=False)
channel = Column(Enum(NotificationChannel), nullable=False)
subject = Column(String(255), nullable=True) # For email/push
content = Column(Text, nullable=False)
template_id = Column(Integer, ForeignKey('notification_templates.id'), nullable=True)
status = Column(Enum(NotificationStatus), nullable=False, default=NotificationStatus.pending)
priority = Column(String(20), nullable=False, default='normal') # low, normal, high, urgent
scheduled_at = Column(DateTime, nullable=True) # For scheduled notifications
sent_at = Column(DateTime, nullable=True)
delivered_at = Column(DateTime, nullable=True)
read_at = Column(DateTime, nullable=True)
error_message = Column(Text, nullable=True)
external_id = Column(String(255), nullable=True) # ID from external service (e.g., Twilio, SendGrid)
meta_data = Column(JSON, nullable=True) # Additional data (recipient info, attachments, etc.)
booking_id = Column(Integer, ForeignKey('bookings.id'), nullable=True)
payment_id = Column(Integer, ForeignKey('payments.id'), nullable=True)
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
user = relationship('User')
template = relationship('NotificationTemplate')
booking = relationship('Booking')
payment = relationship('Payment')
delivery_logs = relationship('NotificationDeliveryLog', back_populates='notification', cascade='all, delete-orphan')
class NotificationTemplate(Base):
__tablename__ = 'notification_templates'
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
name = Column(String(255), nullable=False)
notification_type = Column(Enum(NotificationType), nullable=False)
channel = Column(Enum(NotificationChannel), nullable=False)
subject = Column(String(255), nullable=True)
content = Column(Text, nullable=False)
variables = Column(JSON, nullable=True) # Available template variables
is_active = Column(Boolean, nullable=False, default=True)
created_by = Column(Integer, ForeignKey('users.id'), nullable=False)
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
creator = relationship('User', foreign_keys=[created_by])
notifications = relationship('Notification', back_populates='template')
class NotificationPreference(Base):
__tablename__ = 'notification_preferences'
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
user_id = Column(Integer, ForeignKey('users.id'), nullable=False, unique=True)
email_enabled = Column(Boolean, nullable=False, default=True)
sms_enabled = Column(Boolean, nullable=False, default=True)
push_enabled = Column(Boolean, nullable=False, default=True)
whatsapp_enabled = Column(Boolean, nullable=False, default=False)
in_app_enabled = Column(Boolean, nullable=False, default=True)
# Per-type preferences
booking_confirmation_email = Column(Boolean, nullable=False, default=True)
booking_confirmation_sms = Column(Boolean, nullable=False, default=False)
payment_receipt_email = Column(Boolean, nullable=False, default=True)
payment_receipt_sms = Column(Boolean, nullable=False, default=False)
pre_arrival_reminder_email = Column(Boolean, nullable=False, default=True)
pre_arrival_reminder_sms = Column(Boolean, nullable=False, default=True)
check_in_reminder_email = Column(Boolean, nullable=False, default=True)
check_in_reminder_sms = Column(Boolean, nullable=False, default=True)
check_out_reminder_email = Column(Boolean, nullable=False, default=True)
check_out_reminder_sms = Column(Boolean, nullable=False, default=True)
marketing_campaign_email = Column(Boolean, nullable=False, default=True)
marketing_campaign_sms = Column(Boolean, nullable=False, default=False)
loyalty_update_email = Column(Boolean, nullable=False, default=True)
loyalty_update_sms = Column(Boolean, nullable=False, default=False)
system_alert_email = Column(Boolean, nullable=False, default=True)
system_alert_push = Column(Boolean, nullable=False, default=True)
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
user = relationship('User')
class NotificationDeliveryLog(Base):
__tablename__ = 'notification_delivery_logs'
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
notification_id = Column(Integer, ForeignKey('notifications.id'), nullable=False)
channel = Column(Enum(NotificationChannel), nullable=False)
status = Column(Enum(NotificationStatus), nullable=False)
external_id = Column(String(255), nullable=True)
error_message = Column(Text, nullable=True)
response_data = Column(JSON, nullable=True)
created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
notification = relationship('Notification', back_populates='delivery_logs')