"""Durable LLM usage/cost events.""" from __future__ import annotations from datetime import datetime, timezone from uuid import uuid4 from sqlalchemy import DateTime, Float, ForeignKey, Index, Integer, String, func, text from sqlalchemy.orm import Mapped, mapped_column from ..db import Base def _utc_now() -> datetime: return datetime.now(timezone.utc) class UsageEvent(Base): """One LLM usage record. Never stores prompt content or secrets.""" __tablename__ = "usage_events" __table_args__ = ( Index("ix_usage_org_created", "organization_id", "created_at"), Index("ix_usage_org_user", "organization_id", "user_id"), ) id: Mapped[str] = mapped_column( String(64), primary_key=True, default=lambda: f"usage_{uuid4().hex}" ) organization_id: Mapped[str] = mapped_column( ForeignKey("organizations.id", ondelete="CASCADE"), nullable=False, index=True ) user_id: Mapped[str | None] = mapped_column( ForeignKey("users.id", ondelete="SET NULL"), nullable=True, index=True ) operation: Mapped[str] = mapped_column(String(160), nullable=False) model: Mapped[str | None] = mapped_column(String(120), nullable=True) input_tokens: Mapped[int] = mapped_column(Integer, nullable=False, default=0, server_default=text("0")) output_tokens: Mapped[int] = mapped_column(Integer, nullable=False, default=0, server_default=text("0")) estimated_cost: Mapped[float] = mapped_column( Float, nullable=False, default=0.0, server_default=text("0") ) created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, default=_utc_now, server_default=func.now() )