""" LLM artifacts / cache. Stores strict-JSON outputs from our internal LLM gateway for: - Vision (business concept + buyer matchmaker) - Yield landing page configs Important: - Tier gating is enforced at the API layer; never expose artifacts to Scout users. """ from __future__ import annotations from datetime import datetime from typing import Optional from sqlalchemy import DateTime, Index, Integer, String, Text, ForeignKey from sqlalchemy.orm import Mapped, mapped_column from app.database import Base class LLMArtifact(Base): __tablename__ = "llm_artifacts" id: Mapped[int] = mapped_column(primary_key=True, index=True) # Optional: who generated it (for auditing). Not used for access control. user_id: Mapped[Optional[int]] = mapped_column(ForeignKey("users.id"), nullable=True, index=True) # What this artifact represents. # Examples: "vision_v1", "yield_landing_v1" kind: Mapped[str] = mapped_column(String(50), nullable=False, index=True) # Domain this artifact belongs to (lowercase). domain: Mapped[str] = mapped_column(String(255), nullable=False, index=True) # Prompt/versioning for safe cache invalidation prompt_version: Mapped[str] = mapped_column(String(50), nullable=False, index=True) model: Mapped[str] = mapped_column(String(100), nullable=False) # Strict JSON payload (string) payload_json: Mapped[str] = mapped_column(Text, nullable=False) created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, index=True) updated_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) expires_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True, index=True) __table_args__ = ( Index("ix_llm_artifacts_kind_domain_prompt", "kind", "domain", "prompt_version"), )