notification.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. """Notification provider and log models for push notifications."""
  2. from datetime import datetime
  3. from sqlalchemy import Boolean, Column, DateTime, ForeignKey, Integer, String, Text, Time
  4. from sqlalchemy.orm import relationship
  5. from backend.app.core.database import Base
  6. class NotificationDigestQueue(Base):
  7. """Model for queuing notifications to be sent in daily digest."""
  8. __tablename__ = "notification_digest_queue"
  9. id = Column(Integer, primary_key=True, index=True)
  10. provider_id = Column(Integer, ForeignKey("notification_providers.id", ondelete="CASCADE"), nullable=False)
  11. event_type = Column(String(50), nullable=False) # print_start, print_complete, etc.
  12. title = Column(String(255), nullable=False)
  13. message = Column(Text, nullable=False)
  14. printer_id = Column(Integer, ForeignKey("printers.id", ondelete="SET NULL"), nullable=True)
  15. printer_name = Column(String(100), nullable=True)
  16. created_at = Column(DateTime, default=datetime.utcnow, index=True)
  17. # Relationships
  18. provider = relationship("NotificationProvider", back_populates="digest_queue")
  19. class NotificationLog(Base):
  20. """Model for logging sent notifications."""
  21. __tablename__ = "notification_logs"
  22. id = Column(Integer, primary_key=True, index=True)
  23. provider_id = Column(Integer, ForeignKey("notification_providers.id", ondelete="CASCADE"), nullable=False)
  24. event_type = Column(String(50), nullable=False) # print_start, print_complete, etc.
  25. title = Column(String(255), nullable=False)
  26. message = Column(Text, nullable=False)
  27. success = Column(Boolean, default=True)
  28. error_message = Column(Text, nullable=True)
  29. printer_id = Column(Integer, ForeignKey("printers.id", ondelete="SET NULL"), nullable=True)
  30. printer_name = Column(String(100), nullable=True) # Store name in case printer is deleted
  31. created_at = Column(DateTime, default=datetime.utcnow, index=True)
  32. # Relationships
  33. provider = relationship("NotificationProvider", back_populates="logs")
  34. class NotificationProvider(Base):
  35. """Model for notification providers (WhatsApp, ntfy, Pushover, etc.)."""
  36. __tablename__ = "notification_providers"
  37. id = Column(Integer, primary_key=True, index=True)
  38. name = Column(String(100), nullable=False) # User-defined name
  39. provider_type = Column(String(50), nullable=False) # callmebot, ntfy, pushover, telegram, email
  40. enabled = Column(Boolean, default=True)
  41. # Provider-specific configuration stored as JSON string
  42. config = Column(Text, nullable=False)
  43. # Event triggers - print lifecycle
  44. on_print_start = Column(Boolean, default=False)
  45. on_print_complete = Column(Boolean, default=True)
  46. on_print_failed = Column(Boolean, default=True)
  47. on_print_stopped = Column(Boolean, default=True) # User cancelled/stopped print
  48. on_print_progress = Column(Boolean, default=False) # 25%, 50%, 75% milestones
  49. # Event triggers - printer status
  50. on_printer_offline = Column(Boolean, default=False)
  51. on_printer_error = Column(Boolean, default=False) # AMS issues, etc.
  52. on_filament_low = Column(Boolean, default=False)
  53. on_maintenance_due = Column(Boolean, default=False) # Maintenance reminder
  54. # Quiet hours (do not disturb)
  55. quiet_hours_enabled = Column(Boolean, default=False)
  56. quiet_hours_start = Column(String(5), nullable=True) # HH:MM format, e.g., "22:00"
  57. quiet_hours_end = Column(String(5), nullable=True) # HH:MM format, e.g., "07:00"
  58. # Daily digest (batch notifications into a single daily summary)
  59. daily_digest_enabled = Column(Boolean, default=False)
  60. daily_digest_time = Column(String(5), nullable=True) # HH:MM format, e.g., "08:00"
  61. # Optional: Link to specific printer (NULL = all printers)
  62. printer_id = Column(Integer, ForeignKey("printers.id", ondelete="SET NULL"), nullable=True)
  63. # Status tracking
  64. last_success = Column(DateTime, nullable=True)
  65. last_error = Column(Text, nullable=True)
  66. last_error_at = Column(DateTime, nullable=True)
  67. # Timestamps
  68. created_at = Column(DateTime, default=datetime.utcnow)
  69. updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
  70. # Relationships
  71. printer = relationship("Printer", back_populates="notification_providers")
  72. logs = relationship("NotificationLog", back_populates="provider", cascade="all, delete-orphan")
  73. digest_queue = relationship("NotificationDigestQueue", back_populates="provider", cascade="all, delete-orphan")