This commit is contained in:
Iliyan Angelov
2025-11-23 18:59:18 +02:00
parent be07802066
commit 627959f52b
1840 changed files with 236564 additions and 3475 deletions

View File

@@ -0,0 +1,125 @@
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')