"""Durable delivery queue for alert notifications.""" import enum from datetime import datetime from sqlalchemy import BigInteger, Column, DateTime, Enum, Index, Integer, String, Text from .device import Base PRIMARY_KEY_TYPE = BigInteger().with_variant(Integer, "sqlite") class NotificationStatus(str, enum.Enum): """Lifecycle states for a notification delivery attempt.""" pending = "pending" sending = "sending" sent = "sent" failed = "failed" class NotificationOutbox(Base): """A notification retained until a dispatcher records its final outcome.""" __tablename__ = "notification_outbox" id = Column(PRIMARY_KEY_TYPE, primary_key=True, autoincrement=True) alert_event_id = Column(BigInteger, nullable=False, index=True, comment="关联告警事件 ID") message_content = Column(Text, nullable=False, comment="待发送的脱敏消息摘要") delivery_scope = Column(String(256), nullable=True, comment="受控投递范围摘要") status = Column( Enum(NotificationStatus), nullable=False, default=NotificationStatus.pending, server_default=NotificationStatus.pending.value, comment="投递状态", ) attempt_count = Column(Integer, nullable=False, default=0, comment="投递尝试次数") next_attempt_at = Column(DateTime, nullable=True, comment="下次允许投递时间") locked_at = Column(DateTime, nullable=True, comment="投递器领取时间") sent_at = Column(DateTime, nullable=True, comment="成功投递时间") last_error = Column(String(512), nullable=True, comment="最近一次投递错误摘要") created_at = Column(DateTime, default=datetime.now, nullable=False, comment="创建时间") updated_at = Column( DateTime, default=datetime.now, onupdate=datetime.now, nullable=False, comment="更新时间", ) __table_args__ = ( Index("idx_notification_outbox_status_next_attempt", "status", "next_attempt_at"), )