"""retrieval_logs: per-call semantic-retrieval telemetry for KB-injection tuning Revision ID: 0068 Revises: 0067 Create Date: 2026-06-22 One row per semantic-retrieval call (MCP search tool, REST search route, and — once it lands — the title-first auto-inject path). Captures the effective query params and the score distribution of the results so the similarity threshold and top-k can be tuned from real usage. FK-free on user_id (mirrors app_logs): telemetry should outlive the row it describes. """ from alembic import op import sqlalchemy as sa from sqlalchemy.dialects.postgresql import JSONB revision = "0068" down_revision = "0067" branch_labels = None depends_on = None def upgrade() -> None: op.create_table( "retrieval_logs", sa.Column("id", sa.Integer(), primary_key=True), sa.Column( "created_at", sa.DateTime(timezone=True), nullable=False, server_default=sa.text("now()"), ), sa.Column("user_id", sa.Integer(), nullable=True), sa.Column("source", sa.Text(), nullable=False), sa.Column("query", sa.Text(), nullable=True), sa.Column("threshold", sa.Float(), nullable=True), sa.Column("limit_n", sa.Integer(), nullable=True), sa.Column("project_id", sa.Integer(), nullable=True), sa.Column("is_task", sa.Boolean(), nullable=True), sa.Column("result_count", sa.Integer(), nullable=False, server_default="0"), sa.Column("top_score", sa.Float(), nullable=True), sa.Column("min_score", sa.Float(), nullable=True), sa.Column("result_ids", JSONB(), nullable=False, server_default=sa.text("'[]'::jsonb")), sa.Column("duration_ms", sa.Float(), nullable=True), ) op.create_index("ix_retrieval_logs_created_at", "retrieval_logs", ["created_at"]) op.create_index("ix_retrieval_logs_user_id", "retrieval_logs", ["user_id"]) op.create_index("ix_retrieval_logs_source", "retrieval_logs", ["source"]) op.create_index( "ix_retrieval_logs_source_created_at", "retrieval_logs", ["source", sa.text("created_at DESC")], ) def downgrade() -> None: op.drop_index("ix_retrieval_logs_source_created_at", table_name="retrieval_logs") op.drop_index("ix_retrieval_logs_source", table_name="retrieval_logs") op.drop_index("ix_retrieval_logs_user_id", table_name="retrieval_logs") op.drop_index("ix_retrieval_logs_created_at", table_name="retrieval_logs") op.drop_table("retrieval_logs")