from __future__ import annotations from sqlalchemy import Boolean, ForeignKey, Integer, JSON, String, Text from sqlalchemy.orm import Mapped, mapped_column from sqlalchemy.types import TypeDecorator from admin_app.db.models.base import AdminTimestampedModel from shared.contracts import ToolLifecycleStatus class ToolLifecycleStatusType(TypeDecorator): impl = String(32) cache_ok = True @property def python_type(self): return ToolLifecycleStatus def process_bind_param(self, value, dialect): if value is None: return None if isinstance(value, ToolLifecycleStatus): return value.value return ToolLifecycleStatus(str(value).strip().lower()).value def process_result_value(self, value, dialect): if value is None: return None return ToolLifecycleStatus(str(value).strip().lower()) class ToolDraft(AdminTimestampedModel): __tablename__ = "tool_drafts" id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) draft_id: Mapped[str] = mapped_column(String(40), unique=True, index=True, nullable=False) tool_name: Mapped[str] = mapped_column(String(64), unique=True, index=True, nullable=False) display_name: Mapped[str] = mapped_column(String(120), nullable=False) domain: Mapped[str] = mapped_column(String(40), index=True, nullable=False) description: Mapped[str] = mapped_column(Text, nullable=False) business_goal: Mapped[str] = mapped_column(Text, nullable=False) status: Mapped[ToolLifecycleStatus] = mapped_column( ToolLifecycleStatusType(), nullable=False, default=ToolLifecycleStatus.DRAFT, index=True, ) summary: Mapped[str] = mapped_column(Text, nullable=False) parameters_json: Mapped[list[dict]] = mapped_column(JSON, nullable=False, default=list) required_parameter_count: Mapped[int] = mapped_column(Integer, nullable=False, default=0) current_version_number: Mapped[int] = mapped_column(Integer, nullable=False, default=1) version_count: Mapped[int] = mapped_column(Integer, nullable=False, default=1) requires_director_approval: Mapped[bool] = mapped_column( Boolean, nullable=False, default=True, ) owner_staff_account_id: Mapped[int] = mapped_column( Integer, ForeignKey("staff_accounts.id"), nullable=False, index=True, ) owner_display_name: Mapped[str] = mapped_column(String(150), nullable=False)