"""Organization member ORM model.""" from __future__ import annotations from datetime import datetime from enum import StrEnum from pydantic import BaseModel, ConfigDict from sqlalchemy import DateTime, ForeignKey, Integer, UniqueConstraint, func from sqlalchemy import Enum as SqlEnum from sqlalchemy.orm import Mapped, mapped_column, relationship from app.models.base import Base, enum_values class OrganizationRole(StrEnum): OWNER = "owner" ADMIN = "admin" MANAGER = "manager" MEMBER = "member" class OrganizationMember(Base): """Links users to organizations with role-based access.""" __tablename__ = "organization_members" __table_args__ = ( UniqueConstraint("organization_id", "user_id", name="uq_organization_member"), ) id: Mapped[int] = mapped_column(Integer, primary_key=True) organization_id: Mapped[int] = mapped_column(ForeignKey("organizations.id", ondelete="CASCADE")) user_id: Mapped[int] = mapped_column(ForeignKey("users.id", ondelete="CASCADE")) role: Mapped[OrganizationRole] = mapped_column( SqlEnum( OrganizationRole, name="organization_role", values_callable=enum_values, ), nullable=False, default=OrganizationRole.MEMBER, ) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), server_default=func.now(), nullable=False, ) organization = relationship("Organization", back_populates="members") user = relationship("User", back_populates="memberships") class OrganizationMemberBase(BaseModel): organization_id: int user_id: int role: OrganizationRole class OrganizationMemberCreate(OrganizationMemberBase): pass class OrganizationMemberRead(OrganizationMemberBase): id: int created_at: datetime model_config = ConfigDict(from_attributes=True)