from sqlalchemy import ( CheckConstraint, DateTime, Integer, ForeignKey, Index, String, UniqueConstraint, func, ) from sqlalchemy.orm import Mapped, mapped_column, relationship from datetime import datetime from typing import Optional from app.database import Base class EventInvitation(Base): __tablename__ = "event_invitations" __table_args__ = ( UniqueConstraint("event_id", "user_id", name="uq_event_invitations_event_user"), CheckConstraint( "status IN ('pending', 'accepted', 'tentative', 'declined')", name="ck_event_invitations_status", ), Index("ix_event_invitations_user_status", "user_id", "status"), Index("ix_event_invitations_event_id", "event_id"), ) id: Mapped[int] = mapped_column(primary_key=True) event_id: Mapped[int] = mapped_column( Integer, ForeignKey("calendar_events.id", ondelete="CASCADE"), nullable=False ) user_id: Mapped[int] = mapped_column( Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False ) invited_by: Mapped[Optional[int]] = mapped_column( Integer, ForeignKey("users.id", ondelete="SET NULL"), nullable=True ) status: Mapped[str] = mapped_column(String(20), default="pending") invited_at: Mapped[datetime] = mapped_column( DateTime, default=func.now(), server_default=func.now() ) responded_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True) event: Mapped["CalendarEvent"] = relationship(lazy="raise") user: Mapped["User"] = relationship(foreign_keys=[user_id], lazy="raise") inviter: Mapped[Optional["User"]] = relationship( foreign_keys=[invited_by], lazy="raise" ) overrides: Mapped[list["EventInvitationOverride"]] = relationship( lazy="raise", cascade="all, delete-orphan" ) class EventInvitationOverride(Base): __tablename__ = "event_invitation_overrides" __table_args__ = ( UniqueConstraint("invitation_id", "occurrence_id", name="uq_invitation_override"), CheckConstraint( "status IN ('accepted', 'tentative', 'declined')", name="ck_invitation_override_status", ), Index("ix_invitation_overrides_lookup", "invitation_id", "occurrence_id"), ) id: Mapped[int] = mapped_column(primary_key=True) invitation_id: Mapped[int] = mapped_column( Integer, ForeignKey("event_invitations.id", ondelete="CASCADE"), nullable=False ) occurrence_id: Mapped[int] = mapped_column( Integer, ForeignKey("calendar_events.id", ondelete="CASCADE"), nullable=False ) status: Mapped[str] = mapped_column(String(20), nullable=False) responded_at: Mapped[datetime] = mapped_column( DateTime, default=func.now(), server_default=func.now() )