from __future__ import annotations import uuid from datetime import datetime from typing import Any from sqlalchemy import Boolean, JSON, MetaData, String, Text from sqlalchemy.types import DateTime from sqlalchemy.engine import Engine from sqlalchemy.orm import Mapped, mapped_column, registry from govoplan_core.db.base import NAMING_CONVENTION, utcnow scope_registry = registry(metadata=MetaData(naming_convention=NAMING_CONVENTION)) def new_uuid() -> str: return str(uuid.uuid4()) @scope_registry.mapped class Tenant: """Core-owned scope row used when the tenancy module is not installed. The table was historically named ``tenancy_tenants``. It is now owned by core as ``core_scopes`` so access, auth and policy code can use a stable scope identifier without importing or requiring the tenancy module. """ __tablename__ = "core_scopes" id: Mapped[str] = mapped_column(String(36), primary_key=True, default=new_uuid) slug: Mapped[str] = mapped_column(String(100), unique=True, nullable=False, index=True) name: Mapped[str] = mapped_column(String(255), nullable=False) description: Mapped[str | None] = mapped_column(Text) default_locale: Mapped[str] = mapped_column(String(20), default="de", nullable=False) settings: Mapped[dict[str, Any]] = mapped_column(JSON, default=dict, nullable=False) allow_custom_groups: Mapped[bool | None] = mapped_column(Boolean, nullable=True) allow_custom_roles: Mapped[bool | None] = mapped_column(Boolean, nullable=True) allow_api_keys: Mapped[bool | None] = mapped_column(Boolean, nullable=True) is_active: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utcnow, nullable=False) updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utcnow, onupdate=utcnow, nullable=False) def create_scope_tables(engine: Engine) -> None: scope_registry.metadata.create_all(bind=engine, checkfirst=True) __all__ = ["Tenant", "create_scope_tables", "new_uuid", "scope_registry"]