60 lines
1.7 KiB
Python
60 lines
1.7 KiB
Python
"""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, Enum as SqlEnum, ForeignKey, Integer, UniqueConstraint, func
|
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
|
|
from app.models.base import Base
|
|
|
|
|
|
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"),
|
|
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)
|