""" Modello MailboxPermission – matrice permessi utente × casella (Fase 1-A). ADR permessi granulari: admin ha accesso implicito a tutto. Gli operator/readonly/supervisor devono avere un record esplicito. """ import uuid from datetime import datetime from sqlalchemy import ( Boolean, DateTime, ForeignKey, Index, UniqueConstraint, func, ) from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import Mapped, mapped_column, relationship from app.database import Base class MailboxPermission(Base): __tablename__ = "mailbox_permissions" id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), primary_key=True, default=uuid.uuid4 ) tenant_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False ) user_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("users.id", ondelete="CASCADE"), nullable=False ) mailbox_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("mailboxes.id", ondelete="CASCADE"), nullable=False ) can_read: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True) can_send: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False) can_manage: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False) can_conserve: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False) granted_by: Mapped[uuid.UUID | None] = mapped_column( UUID(as_uuid=True), ForeignKey("users.id"), nullable=True ) granted_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, server_default=func.now() ) # Relazioni user: Mapped["User"] = relationship( # noqa: F821 "User", back_populates="mailbox_permissions", foreign_keys=[user_id] ) mailbox: Mapped["Mailbox"] = relationship( # noqa: F821 "Mailbox", back_populates="permissions" ) __table_args__ = ( UniqueConstraint("user_id", "mailbox_id", name="uq_perm_user_mailbox"), Index("idx_mbperm_user", "user_id"), Index("idx_mbperm_mailbox", "mailbox_id"), Index("idx_mbperm_tenant", "tenant_id"), ) def __repr__(self) -> str: return ( f"" )