68 lines
1.8 KiB
Python
68 lines
1.8 KiB
Python
|
|
"""Tenant model for multi-tenancy support."""
|
||
|
|
|
||
|
|
from typing import TYPE_CHECKING
|
||
|
|
|
||
|
|
from sqlalchemy import String
|
||
|
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||
|
|
|
||
|
|
from app.models.base import Base, TimestampMixin, UUIDMixin
|
||
|
|
|
||
|
|
if TYPE_CHECKING:
|
||
|
|
from app.models.agent import Agent
|
||
|
|
from app.models.event import Event
|
||
|
|
from app.models.registration_token import RegistrationToken
|
||
|
|
from app.models.server import Server
|
||
|
|
from app.models.task import Task
|
||
|
|
|
||
|
|
|
||
|
|
class Tenant(UUIDMixin, TimestampMixin, Base):
|
||
|
|
"""
|
||
|
|
Tenant model representing a customer organization.
|
||
|
|
|
||
|
|
Each tenant has isolated servers, tasks, agents, and events.
|
||
|
|
"""
|
||
|
|
|
||
|
|
__tablename__ = "tenants"
|
||
|
|
|
||
|
|
name: Mapped[str] = mapped_column(
|
||
|
|
String(255),
|
||
|
|
unique=True,
|
||
|
|
nullable=False,
|
||
|
|
index=True,
|
||
|
|
)
|
||
|
|
domain: Mapped[str | None] = mapped_column(
|
||
|
|
String(255),
|
||
|
|
unique=True,
|
||
|
|
nullable=True,
|
||
|
|
)
|
||
|
|
dashboard_token_hash: Mapped[str | None] = mapped_column(
|
||
|
|
String(64), # SHA-256 hex = 64 characters
|
||
|
|
nullable=True,
|
||
|
|
comment="SHA-256 hash of dashboard authentication token",
|
||
|
|
)
|
||
|
|
|
||
|
|
# Relationships
|
||
|
|
servers: Mapped[list["Server"]] = relationship(
|
||
|
|
back_populates="tenant",
|
||
|
|
lazy="selectin",
|
||
|
|
)
|
||
|
|
tasks: Mapped[list["Task"]] = relationship(
|
||
|
|
back_populates="tenant",
|
||
|
|
lazy="selectin",
|
||
|
|
)
|
||
|
|
agents: Mapped[list["Agent"]] = relationship(
|
||
|
|
back_populates="tenant",
|
||
|
|
lazy="selectin",
|
||
|
|
)
|
||
|
|
events: Mapped[list["Event"]] = relationship(
|
||
|
|
back_populates="tenant",
|
||
|
|
lazy="selectin",
|
||
|
|
)
|
||
|
|
registration_tokens: Mapped[list["RegistrationToken"]] = relationship(
|
||
|
|
back_populates="tenant",
|
||
|
|
lazy="selectin",
|
||
|
|
)
|
||
|
|
|
||
|
|
def __repr__(self) -> str:
|
||
|
|
return f"<Tenant(id={self.id}, name={self.name})>"
|