from __future__ import annotations import uuid from datetime import datetime from sqlalchemy import DateTime, ForeignKey, Text, UniqueConstraint, func from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import Mapped, mapped_column from . import Base class Group(Base): """A named set of users. Sharing a resource with a group grants it to every member (see thoughtsync.acl.visible_to_user).""" __tablename__ = "groups" id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) name: Mapped[str] = mapped_column(Text(), nullable=False) owner_id: Mapped[uuid.UUID | None] = mapped_column( UUID(as_uuid=True), ForeignKey("users.id", ondelete="SET NULL"), nullable=True ) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now()) class GroupMember(Base): __tablename__ = "group_members" __table_args__ = (UniqueConstraint("group_id", "user_id", name="uq_group_members_group_user"),) id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) group_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("groups.id", ondelete="CASCADE"), nullable=False ) user_id: Mapped[uuid.UUID] = mapped_column( UUID(as_uuid=True), ForeignKey("users.id", ondelete="CASCADE"), nullable=False ) role: Mapped[str] = mapped_column(Text(), nullable=False, server_default="member") created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now())