"""SQLAlchemy models for knowledge graph storage.""" from sqlalchemy import Column, String, Text, Float, DateTime, ARRAY, ForeignKey, UniqueConstraint from sqlalchemy.dialects.postgresql import UUID, VECTOR from sqlalchemy.orm import declarative_base from sqlalchemy.sql import func import uuid from datetime import datetime Base = declarative_base() class Entity(Base): """Knowledge graph entity.""" __tablename__ = "entities" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) domain = Column(String(100), nullable=False, index=True) name = Column(String(500), nullable=False) description = Column(Text) entity_type = Column(String(100), nullable=False) # transceiver, standard, vendor, etc embedding = Column(VECTOR(384)) # bge-m3 384-dim confidence = Column(Float, default=1.0) metadata = Column(String) # JSON metadata created_at = Column(DateTime, default=datetime.utcnow) updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) __table_args__ = ( UniqueConstraint('domain', 'entity_type', 'name', name='unique_entity'), ) class Relation(Base): """Knowledge graph relation between entities.""" __tablename__ = "relations" source_id = Column(UUID(as_uuid=True), ForeignKey("entities.id"), primary_key=True) relation_type = Column(String(100), primary_key=True) # supported_by, manufactured_by, etc target_id = Column(UUID(as_uuid=True), ForeignKey("entities.id"), primary_key=True) strength = Column(Float, default=1.0) # confidence in relation metadata = Column(String) # JSON metadata created_at = Column(DateTime, default=datetime.utcnow) class Document(Base): """Ingested document for knowledge graph.""" __tablename__ = "documents" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) domain = Column(String(100), nullable=False, index=True) source = Column(String(100), nullable=False) # blog, datasheet, standard, etc title = Column(String(500), nullable=False) content = Column(Text, nullable=False) entity_ids = Column(ARRAY(UUID(as_uuid=True))) # linked entity IDs embedding = Column(VECTOR(384)) # Document-level embedding token_count = Column(Float) created_at = Column(DateTime, default=datetime.utcnow) class QueryLog(Base): """Query execution audit trail for evaluation.""" __tablename__ = "query_logs" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) domain = Column(String(100), nullable=False, index=True) query_text = Column(Text, nullable=False) retrieved_doc_ids = Column(ARRAY(UUID(as_uuid=True))) ground_truth_doc_ids = Column(ARRAY(UUID(as_uuid=True))) relevance_scores = Column(ARRAY(Float)) latency_ms = Column(Float) entity_count = Column(Float) created_at = Column(DateTime, default=datetime.utcnow) class EvaluationResult(Base): """Evaluation metrics snapshot.""" __tablename__ = "evaluation_results" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) domain = Column(String(100), nullable=False, index=True) eval_set_name = Column(String(100), nullable=False) metric_name = Column(String(100), nullable=False) metric_value = Column(Float, nullable=False) baseline_value = Column(Float) # FTS baseline for comparison improvement_pct = Column(Float) sample_count = Column(Float) created_at = Column(DateTime, default=datetime.utcnow)