from datetime import datetime from typing import Optional from sqlalchemy import UniqueConstraint from sqlmodel import Field, SQLModel class SkillMarketItem(SQLModel, table=True): __tablename__ = "skill_market_item" __table_args__ = ( UniqueConstraint("skill_key", name="uq_skill_market_item_skill_key"), UniqueConstraint("zip_filename", name="uq_skill_market_item_zip_filename"), ) id: Optional[int] = Field(default=None, primary_key=True) skill_key: str = Field(index=True, max_length=120) display_name: str = Field(default="", max_length=255) description: str = Field(default="") zip_filename: str = Field(max_length=255) zip_size_bytes: int = Field(default=0) entry_names_json: str = Field(default="[]") created_at: datetime = Field(default_factory=datetime.utcnow, index=True) updated_at: datetime = Field(default_factory=datetime.utcnow, index=True) class BotSkillInstall(SQLModel, table=True): __tablename__ = "bot_skill_install" __table_args__ = ( UniqueConstraint("bot_id", "skill_market_item_id", name="uq_bot_skill_install_bot_market"), ) id: Optional[int] = Field(default=None, primary_key=True) bot_id: str = Field(foreign_key="bot_instance.id", index=True) skill_market_item_id: int = Field(foreign_key="skill_market_item.id", index=True) installed_entries_json: str = Field(default="[]") source_zip_filename: str = Field(default="", max_length=255) status: str = Field(default="INSTALLED", index=True, max_length=32) last_error: Optional[str] = Field(default=None) installed_at: datetime = Field(default_factory=datetime.utcnow, index=True) updated_at: datetime = Field(default_factory=datetime.utcnow, index=True)