from sqlalchemy import Column, Integer, String, DateTime, Text, JSON, Boolean, ForeignKey, Float from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import relationship from datetime import datetime Base = declarative_base() class Tool(Base): __tablename__ = "tools" id = Column(Integer, primary_key=True) tool_id = Column(String(64), unique=True, nullable=False) name = Column(String(128), nullable=False) description = Column(Text, nullable=True) category = Column(String(64), nullable=True) enabled = Column(Boolean, default=True) created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) versions = relationship("ToolVersion", back_populates="tool") permissions = relationship("ToolPermission", back_populates="tool") health_checks = relationship("ToolHealth", back_populates="tool") class ToolVersion(Base): __tablename__ = "tool_versions" id = Column(Integer, primary_key=True) tool_id = Column(Integer, ForeignKey("tools.id")) version = Column(String(32), nullable=False) code_path = Column(String(256), nullable=False) # module path or file path entry_point = Column(String(128), nullable=False) # function name config_schema = Column(JSON, nullable=True) # JSON schema for input created_at = Column(DateTime, default=datetime.utcnow) is_active = Column(Boolean, default=True) tool = relationship("Tool", back_populates="versions") class ToolPermission(Base): __tablename__ = "tool_permissions" id = Column(Integer, primary_key=True) tool_id = Column(Integer, ForeignKey("tools.id")) role = Column(String(64), nullable=False) # e.g. "admin", "user", "service" allowed = Column(Boolean, default=True) tool = relationship("Tool", back_populates="permissions") class ToolHealth(Base): __tablename__ = "tool_health" id = Column(Integer, primary_key=True) tool_id = Column(Integer, ForeignKey("tools.id")) status = Column(String(32), default="healthy") # healthy, degraded, unhealthy last_check = Column(DateTime, default=datetime.utcnow) response_time = Column(Float, nullable=True) # in ms error_message = Column(Text, nullable=True) tool = relationship("Tool", back_populates="health_checks")