"""Benachrichtigungsregeln und Versandprotokoll.""" from datetime import date, datetime from sqlalchemy import ( Boolean, Date, DateTime, ForeignKey, Index, Integer, String, Text, UniqueConstraint, ) from sqlalchemy.orm import Mapped, mapped_column, relationship from app.db.base import Base, CreatedAtMixin from app.models.enums import ( NotificationChannel, NotificationStatus, NotificationType, pg_enum, ) class NotificationRule(Base, CreatedAtMixin): """Eine Regel pro Ereignistyp und Kanal.""" __tablename__ = "notification_rule" id: Mapped[int] = mapped_column(Integer, primary_key=True) type: Mapped[NotificationType] = mapped_column( pg_enum(NotificationType, "notification_type"), nullable=False ) lead_days: Mapped[int] = mapped_column(Integer, nullable=False, default=7) channel: Mapped[NotificationChannel] = mapped_column( pg_enum(NotificationChannel, "notification_channel"), nullable=False ) target: Mapped[str | None] = mapped_column(Text, nullable=True) is_active: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True) logs: Mapped[list["NotificationLog"]] = relationship( back_populates="rule", cascade="all, delete-orphan" ) class NotificationLog(Base): """Versandprotokoll. `dedupe_day` verhindert Doppelversand am selben Tag.""" __tablename__ = "notification_log" id: Mapped[int] = mapped_column(Integer, primary_key=True) rule_id: Mapped[int] = mapped_column( ForeignKey("notification_rule.id", ondelete="CASCADE"), nullable=False ) ref_type: Mapped[str] = mapped_column(String(40), nullable=False) ref_id: Mapped[str] = mapped_column(String(80), nullable=False) dedupe_day: Mapped[date] = mapped_column(Date, nullable=False) sent_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False) status: Mapped[NotificationStatus] = mapped_column( pg_enum(NotificationStatus, "notification_status"), nullable=False ) error: Mapped[str | None] = mapped_column(Text, nullable=True) rule: Mapped[NotificationRule] = relationship(back_populates="logs") __table_args__ = ( UniqueConstraint( "rule_id", "ref_type", "ref_id", "dedupe_day", name="uq_notification_log_rule_id" ), Index("ix_notification_log_sent_at", "sent_at"), )