"""Notification channel configuration per account. Each account can have multiple notification configs (email, Slack webhook, Teams webhook). Each config specifies which events it receives. """ import uuid from datetime import datetime, timezone from typing import Optional, Any, TYPE_CHECKING from sqlalchemy import String, Boolean, DateTime, ForeignKey, CheckConstraint from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.dialects.postgresql import UUID, JSONB from app.core.database import Base if TYPE_CHECKING: from app.models.account import Account class NotificationConfig(Base): __tablename__ = "notification_configs" __table_args__ = ( CheckConstraint( "channel IN ('email', 'slack_webhook', 'teams_webhook')", name="ck_notification_configs_channel", ), ) id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4 ) account_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("accounts.id", ondelete="CASCADE"), nullable=False, index=True, ) channel: Mapped[str] = mapped_column(String(20), nullable=False) webhook_url: Mapped[Optional[str]] = mapped_column(String(500), nullable=True) email_addresses: Mapped[Optional[list]] = mapped_column(JSONB, nullable=True) is_active: Mapped[bool] = mapped_column(Boolean, default=True) events_enabled: Mapped[dict[str, Any]] = mapped_column( JSONB, default=lambda: { "session.escalated": True, "session.high_priority": True, "proposal.pending": True, "proposal.approved": True, "knowledge_gap.detected": True, } ) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), default=lambda: datetime.now(timezone.utc) ) updated_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc), ) account: Mapped[Optional["Account"]] = relationship("Account", foreign_keys=[account_id])