import uuid from enum import Enum from sqlalchemy import String, Boolean, ForeignKey, Enum as SQLEnum, UniqueConstraint from sqlalchemy.orm import Mapped, mapped_column, relationship from typing import TYPE_CHECKING if TYPE_CHECKING: from domains.users.models import User from db.base import Base class GroupType(str, Enum): PUBLIC = "public" PRIVATE = "private" class GroupMemberRole(str, Enum): MANAGER = "manager" MEMBER = "member" class Group(Base): __tablename__ = "groups" # type: ignore name: Mapped[str] = mapped_column( String(100), nullable=False, index=True ) type: Mapped[GroupType] = mapped_column( SQLEnum(GroupType, name="group_type"), default=GroupType.PUBLIC, nullable=False ) is_active: Mapped[bool] = mapped_column( Boolean, default=True, index=True ) owner_id: Mapped[uuid.UUID] = mapped_column( ForeignKey("users.id", ondelete="CASCADE"), nullable=False, index=True ) # Relationship to members members: Mapped[list["GroupMember"]] = relationship(back_populates="group", cascade="all, delete-orphan") class GroupMember(Base): __tablename__ = "group_members" # type: ignore __table_args__ = ( UniqueConstraint("user_id", "group_id", name="uq_group_member"), ) user_id: Mapped[uuid.UUID] = mapped_column( ForeignKey("users.id", ondelete="CASCADE"), index=True ) group_id: Mapped[uuid.UUID] = mapped_column( ForeignKey("groups.id", ondelete="CASCADE"), index=True ) role: Mapped[GroupMemberRole] = mapped_column( SQLEnum(GroupMemberRole, name="group_member_role"), default=GroupMemberRole.MEMBER, nullable=False ) # Relationships group: Mapped["Group"] = relationship(back_populates="members") user: Mapped["User"] = relationship()