"""baseline_20260305

Revision ID: 33eff537939b
Revises:
Create Date: 2026-03-05 22:45:46.911018

"""

from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision: str = "33eff537939b"
down_revision: Union[str, Sequence[str], None] = None
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
    """Upgrade schema."""
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table(
        "file_directory",
        sa.Column(
            "id",
            sa.String(length=36),
            nullable=False,
            comment="Directory record identifier",
        ),
        sa.Column(
            "title", sa.String(length=255), nullable=False, comment="Directory title"
        ),
        sa.Column(
            "parent_id",
            sa.String(length=36),
            nullable=True,
            comment="Parent directory ID; NULL means root directory",
        ),
        sa.Column(
            "user_id", sa.String(length=36), nullable=False, comment="Owning user ID"
        ),
        sa.Column("create_time", sa.DateTime(), nullable=True, comment="Created time"),
        sa.Column("update_time", sa.DateTime(), nullable=True, comment="Updated time"),
        sa.ForeignKeyConstraint(
            ["parent_id"],
            ["file_directory.id"],
        ),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index(
        op.f("ix_file_directory_id"), "file_directory", ["id"], unique=False
    )
    op.create_table(
        "knowledge_base",
        sa.Column(
            "id", sa.String(length=36), nullable=False, comment="Content row identifier"
        ),
        sa.Column("content", sa.Text(), nullable=True, comment="Raw content text"),
        sa.Column("path", sa.Text(), nullable=True, comment="File path or source"),
        sa.Column(
            "type",
            sa.String(length=2000),
            nullable=True,
            comment="Content type, for example PTXT or SUMMARY",
        ),
        sa.Column(
            "length", sa.Integer(), nullable=True, comment="Content length or size"
        ),
        sa.Column(
            "keywords", sa.String(length=511), nullable=True, comment="Content keywords"
        ),
        sa.Column("summary", sa.Text(), nullable=True, comment="Content summary"),
        sa.Column(
            "know_id",
            sa.String(length=128),
            nullable=True,
            comment="Knowledge record ID that may refer to an external knowledge base",
        ),
        sa.Column("tokens", sa.Text(), nullable=True, comment="Tokenized content"),
        sa.Column(
            "embedding",
            sa.Text(),
            nullable=True,
            comment="Semantic vector used for similarity search",
        ),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index(
        op.f("ix_knowledge_base_id"), "knowledge_base", ["id"], unique=False
    )
    op.create_table(
        "path_base",
        sa.Column(
            "id", sa.String(length=36), nullable=False, comment="Path row identifier"
        ),
        sa.Column("path", sa.Text(), nullable=True, comment="File path or source"),
        sa.Column(
            "embedding",
            sa.Text(),
            nullable=True,
            comment="Semantic vector used for similarity search",
        ),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index(op.f("ix_path_base_id"), "path_base", ["id"], unique=False)
    op.create_table(
        "stripe_price_configs",
        sa.Column("id", sa.String(length=36), nullable=False),
        sa.Column("price_id", sa.String(length=255), nullable=False),
        sa.Column("product_type", sa.String(length=50), nullable=False),
        sa.Column("plan_id", sa.String(length=50), nullable=False),
        sa.Column(
            "credits_amount", sa.BigInteger(), server_default="0", nullable=False
        ),
        sa.Column("amount_cents", sa.Integer(), server_default="0", nullable=False),
        sa.Column("currency", sa.String(length=10), nullable=False),
        sa.Column("is_active", sa.Boolean(), nullable=False),
        sa.Column("metadata", sa.JSON(), nullable=True),
        sa.Column("created_at", sa.DateTime(), nullable=False),
        sa.Column("updated_at", sa.DateTime(), nullable=False),
        sa.CheckConstraint(
            "(product_type = 'credits_package' AND credits_amount > 0) OR (product_type = 'subscription')",
            name="chk_credits_package_has_amount",
        ),
        sa.CheckConstraint("amount_cents >= 0", name="chk_amount_cents_non_negative"),
        sa.PrimaryKeyConstraint("id"),
        sa.UniqueConstraint("price_id", name="uq_stripe_price_config_price_id"),
    )
    op.create_index(
        op.f("ix_stripe_price_configs_price_id"),
        "stripe_price_configs",
        ["price_id"],
        unique=True,
    )
    op.create_table(
        "system_limits",
        sa.Column("method", sa.String(length=10), nullable=False),
        sa.Column("api_pattern", sa.String(length=200), nullable=False),
        sa.Column("priority", sa.Integer(), nullable=False),
        sa.Column("rpm", sa.Integer(), nullable=False),
        sa.Column("description", sa.String(length=200), nullable=True),
        sa.PrimaryKeyConstraint("method", "api_pattern"),
    )
    op.create_table(
        "tier_limits",
        sa.Column("tier_name", sa.String(length=20), nullable=False),
        sa.Column("min_lifetime_amount_micro", sa.BigInteger(), nullable=False),
        sa.Column("max_concurrent_jobs", sa.Integer(), nullable=False),
        sa.Column("rpm_limit", sa.Integer(), nullable=False),
        sa.Column("daily_quota", sa.Integer(), nullable=False),
        sa.Column("display_name", sa.String(length=50), nullable=False),
        sa.PrimaryKeyConstraint("tier_name"),
    )
    op.execute(
        """
        INSERT INTO tier_limits (tier_name, min_lifetime_amount_micro, max_concurrent_jobs, rpm_limit, daily_quota, display_name)
        VALUES
            ('free',   0,            2,  2,   20, 'Free'),
            ('tier_1', 10000000,     5,  15,  -1, 'Tier 1'),
            ('tier_2', 50000000,     10, 20,  -1, 'Tier 2'),
            ('tier_3', 100000000,    20, 50,  -1, 'Tier 3'),
            ('tier_4', 500000000,    50, 100, -1, 'Tier 4'),
            ('tier_5', 2000000000,   -1, -1,  -1, 'Tier 5')
        ON CONFLICT (tier_name) DO NOTHING
        """
    )
    op.execute(
        """
        INSERT INTO system_limits (method, api_pattern, priority, rpm, description)
        VALUES
            ('GET',  '/v1/jobs/*',              200,  200,  'Job queries - prevent polling'),
            ('*',    '*',                       9999, 1000, 'Default for all unmatched endpoints')
        ON CONFLICT (method, api_pattern) DO NOTHING
        """
    )
    op.create_table(
        "api_keys",
        sa.Column("id", sa.String(length=36), nullable=False),
        sa.Column("user_id", sa.Text(), nullable=False),
        sa.Column("key_hash", sa.String(length=255), nullable=False),
        sa.Column("key_mask", sa.String(length=50), nullable=False),
        sa.Column("name", sa.String(length=255), nullable=False),
        sa.Column("enabled_modules", sa.JSON(), nullable=True),
        sa.Column("expires_at", sa.DateTime(), nullable=True),
        sa.Column("is_active", sa.Boolean(), nullable=False),
        sa.Column("created_at", sa.DateTime(), nullable=False),
        sa.Column("last_used_at", sa.DateTime(), nullable=True),
        sa.ForeignKeyConstraint(["user_id"], ["user.id"], ondelete="RESTRICT"),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index(
        op.f("ix_api_keys_key_hash"), "api_keys", ["key_hash"], unique=False
    )
    op.create_index(op.f("ix_api_keys_user_id"), "api_keys", ["user_id"], unique=False)
    op.create_table(
        "credits_transactions",
        sa.Column("id", sa.String(length=36), nullable=False),
        sa.Column("user_id", sa.Text(), nullable=False),
        sa.Column("credits_amount", sa.BigInteger(), nullable=False),
        sa.Column("transaction_type", sa.String(length=50), nullable=False),
        sa.Column("stripe_payment_id", sa.String(length=255), nullable=True),
        sa.Column("description", sa.String(length=500), nullable=True),
        sa.Column("transaction_metadata", sa.JSON(), nullable=True),
        sa.Column("created_at", sa.DateTime(), nullable=False),
        sa.ForeignKeyConstraint(["user_id"], ["user.id"], ondelete="RESTRICT"),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index(
        op.f("ix_credits_transactions_created_at"),
        "credits_transactions",
        ["created_at"],
        unique=False,
    )
    op.create_index(
        op.f("ix_credits_transactions_stripe_payment_id"),
        "credits_transactions",
        ["stripe_payment_id"],
        unique=False,
    )
    op.create_index(
        op.f("ix_credits_transactions_user_id"),
        "credits_transactions",
        ["user_id"],
        unique=False,
    )
    op.create_table(
        "jobs",
        sa.Column("job_id", sa.String(length=36), nullable=False),
        sa.Column("user_id", sa.Text(), nullable=False),
        sa.Column("job_type", sa.String(length=50), nullable=False),
        sa.Column("status", sa.String(length=50), nullable=False),
        sa.Column("source_type", sa.String(length=20), nullable=False),
        sa.Column("file_path", sa.String(length=512), nullable=True),
        sa.Column("s3_key", sa.String(length=512), nullable=True),
        sa.Column("webhook_url", sa.String(length=512), nullable=True),
        sa.Column("webhook_enabled", sa.Boolean(), nullable=False),
        sa.Column("job_metadata", sa.JSON(), nullable=True),
        sa.Column("error_message", sa.Text(), nullable=True),
        sa.Column("error_code", sa.String(length=50), nullable=True),
        sa.Column("version", sa.Integer(), nullable=False),
        sa.Column("created_at", sa.DateTime(), nullable=False),
        sa.Column("updated_at", sa.DateTime(), nullable=False),
        sa.Column(
            "page_count",
            sa.Integer(),
            nullable=True,
            comment="Calculated page count for billing",
        ),
        sa.Column(
            "credits_charged",
            sa.BigInteger(),
            nullable=False,
            comment="In micro-dollars: $1.00 = 1,000,000",
        ),
        sa.Column(
            "billing_status",
            sa.String(length=50),
            nullable=False,
            comment="pending, charged, billing_failed, refunded",
        ),
        sa.ForeignKeyConstraint(["user_id"], ["user.id"], ondelete="RESTRICT"),
        sa.PrimaryKeyConstraint("job_id"),
    )
    op.create_index("idx_job_created_at", "jobs", ["created_at"], unique=False)
    op.create_index("idx_job_status", "jobs", ["status"], unique=False)
    op.create_index("idx_job_type", "jobs", ["job_type"], unique=False)
    op.create_index(
        "idx_job_user_active_states",
        "jobs",
        ["user_id", "status"],
        unique=False,
        postgresql_where=sa.text(
            "status IN ('waiting-file', 'pending', 'running', 'converting')"
        ),
    )
    op.create_index("idx_job_user_status", "jobs", ["user_id", "status"], unique=False)
    op.create_index(op.f("ix_jobs_user_id"), "jobs", ["user_id"], unique=False)
    op.create_table(
        "payment_records",
        sa.Column("id", sa.String(length=36), nullable=False),
        sa.Column("payment_intent_id", sa.String(length=255), nullable=True),
        sa.Column("checkout_session_id", sa.String(length=255), nullable=True),
        sa.Column("user_id", sa.Text(), nullable=False),
        sa.Column("payment_type", sa.String(length=50), nullable=False),
        sa.Column("amount_cents", sa.Integer(), nullable=False),
        sa.Column("currency", sa.String(length=10), nullable=False),
        sa.Column("status", sa.String(length=50), nullable=False),
        sa.Column("credits_amount", sa.BigInteger(), nullable=True),
        sa.Column("plan_id", sa.String(length=50), nullable=True),
        sa.Column("stripe_subscription_id", sa.String(length=255), nullable=True),
        sa.Column("processed_at", sa.DateTime(), nullable=True),
        sa.Column("metadata", sa.JSON(), nullable=True),
        sa.Column("created_at", sa.DateTime(), nullable=False),
        sa.Column("updated_at", sa.DateTime(), nullable=False),
        sa.ForeignKeyConstraint(["user_id"], ["user.id"], ondelete="RESTRICT"),
        sa.PrimaryKeyConstraint("id"),
        sa.UniqueConstraint(
            "checkout_session_id", name="uq_payment_record_checkout_session_id"
        ),
    )
    op.create_index(
        op.f("ix_payment_records_checkout_session_id"),
        "payment_records",
        ["checkout_session_id"],
        unique=True,
    )
    op.create_index(
        op.f("ix_payment_records_payment_intent_id"),
        "payment_records",
        ["payment_intent_id"],
        unique=True,
    )
    op.create_index(
        op.f("ix_payment_records_stripe_subscription_id"),
        "payment_records",
        ["stripe_subscription_id"],
        unique=False,
    )
    op.create_index(
        op.f("ix_payment_records_user_id"), "payment_records", ["user_id"], unique=False
    )
    op.create_table(
        "user_balances",
        sa.Column("user_id", sa.Text(), nullable=False),
        sa.Column("credits_balance", sa.BigInteger(), nullable=False),
        sa.Column("user_tier", sa.String(length=20), nullable=False),
        sa.Column("stripe_customer_id", sa.String(length=255), nullable=True),
        sa.Column("created_at", sa.DateTime(), nullable=False),
        sa.Column("updated_at", sa.DateTime(), nullable=False),
        sa.ForeignKeyConstraint(["user_id"], ["user.id"], ondelete="RESTRICT"),
        sa.PrimaryKeyConstraint("user_id"),
    )
    op.create_table(
        "webhook_secrets",
        sa.Column("id", sa.String(length=36), nullable=False),
        sa.Column("user_id", sa.Text(), nullable=False),
        sa.Column("endpoint", sa.String(length=2048), nullable=True),
        sa.Column("secret_encrypted", sa.Text(), nullable=False),
        sa.Column("status", sa.String(length=20), nullable=False),
        sa.Column("last_used_at", sa.DateTime(), nullable=True),
        sa.Column("description", sa.String(length=255), nullable=True),
        sa.Column("created_at", sa.DateTime(), nullable=False),
        sa.ForeignKeyConstraint(["user_id"], ["user.id"], ondelete="RESTRICT"),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index(
        "idx_webhook_secrets_status", "webhook_secrets", ["status"], unique=False
    )
    op.create_index(
        "idx_webhook_secrets_user_endpoint",
        "webhook_secrets",
        ["user_id", "endpoint"],
        unique=False,
    )
    op.create_index(
        "idx_webhook_secrets_user_id", "webhook_secrets", ["user_id"], unique=False
    )
    op.create_table(
        "job_results",
        sa.Column("id", sa.String(length=36), nullable=False),
        sa.Column("job_id", sa.String(length=36), nullable=False),
        sa.Column("delivery_mode", sa.String(length=20), nullable=False),
        sa.Column("document_metadata", sa.JSON(), nullable=True),
        sa.Column("inline_payload", sa.JSON(), nullable=True),
        sa.Column("result_s3_key", sa.String(length=512), nullable=True),
        sa.Column("result_size", sa.Integer(), nullable=True),
        sa.Column("created_at", sa.DateTime(), nullable=False),
        sa.Column("updated_at", sa.DateTime(), nullable=False),
        sa.ForeignKeyConstraint(["job_id"], ["jobs.job_id"], ondelete="CASCADE"),
        sa.PrimaryKeyConstraint("id"),
        sa.UniqueConstraint("job_id"),
    )
    op.create_table(
        "job_state_audit_logs",
        sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
        sa.Column("job_id", sa.String(length=36), nullable=False),
        sa.Column("from_state", sa.String(length=50), nullable=True),
        sa.Column("to_state", sa.String(length=50), nullable=False),
        sa.Column("transition_reason", sa.String(length=100), nullable=False),
        sa.Column("operator_id", sa.String(length=36), nullable=True),
        sa.Column("operator_type", sa.String(length=20), nullable=False),
        sa.Column("transition_metadata", sa.JSON(), nullable=True),
        sa.Column("created_at", sa.DateTime(), nullable=False),
        sa.ForeignKeyConstraint(["job_id"], ["jobs.job_id"], ondelete="CASCADE"),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index(
        "idx_audit_log_created_at", "job_state_audit_logs", ["created_at"], unique=False
    )
    op.create_index(
        "idx_audit_log_job_created",
        "job_state_audit_logs",
        ["job_id", "created_at"],
        unique=False,
    )
    op.create_index(
        "idx_audit_log_job_id", "job_state_audit_logs", ["job_id"], unique=False
    )
    op.create_table(
        "job_state_history",
        sa.Column("id", sa.String(length=36), nullable=False),
        sa.Column("job_id", sa.String(length=36), nullable=False),
        sa.Column("from_state", sa.String(length=50), nullable=False),
        sa.Column("to_state", sa.String(length=50), nullable=False),
        sa.Column("transition_metadata", sa.JSON(), nullable=True),
        sa.Column("created_at", sa.DateTime(), nullable=False),
        sa.ForeignKeyConstraint(["job_id"], ["jobs.job_id"], ondelete="CASCADE"),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index(
        "idx_job_state_history_created_at",
        "job_state_history",
        ["created_at"],
        unique=False,
    )
    op.create_index(
        "idx_job_state_history_job_id", "job_state_history", ["job_id"], unique=False
    )
    op.create_table(
        "webhook_events",
        sa.Column("id", sa.String(length=36), nullable=False),
        sa.Column("job_id", sa.String(length=36), nullable=False),
        sa.Column("target_url", sa.String(length=2048), nullable=False),
        sa.Column("payload", postgresql.JSON(astext_type=sa.Text()), nullable=False),
        sa.Column("status", sa.String(length=50), nullable=False),
        sa.Column("attempts", sa.Integer(), nullable=False),
        sa.Column("next_retry_at", sa.DateTime(), nullable=True),
        sa.Column("created_at", sa.DateTime(), nullable=False),
        sa.Column("updated_at", sa.DateTime(), nullable=False),
        sa.ForeignKeyConstraint(["job_id"], ["jobs.job_id"], ondelete="CASCADE"),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index(
        "idx_webhook_events_created_at", "webhook_events", ["created_at"], unique=False
    )
    op.create_index(
        "idx_webhook_events_job_id", "webhook_events", ["job_id"], unique=False
    )
    op.create_index(
        "idx_webhook_events_next_retry",
        "webhook_events",
        ["next_retry_at"],
        unique=False,
    )
    op.create_index(
        "idx_webhook_events_status", "webhook_events", ["status"], unique=False
    )
    op.create_index(
        op.f("ix_webhook_events_status"), "webhook_events", ["status"], unique=False
    )
    op.create_table(
        "job_chunks",
        sa.Column("id", sa.String(length=36), nullable=False),
        sa.Column("job_result_id", sa.String(length=36), nullable=False),
        sa.Column("chunk_id", sa.String(length=64), nullable=False),
        sa.Column("chunk_type", sa.String(length=2000), nullable=False),
        sa.Column("text", sa.Text(), nullable=True),
        sa.Column("path", sa.String(length=1024), nullable=True),
        sa.Column("chunk_metadata", sa.JSON(), nullable=True),
        sa.Column("sort_order", sa.Integer(), nullable=False),
        sa.Column("created_at", sa.DateTime(), nullable=False),
        sa.ForeignKeyConstraint(
            ["job_result_id"], ["job_results.id"], ondelete="CASCADE"
        ),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index("idx_job_chunks_chunk_id", "job_chunks", ["chunk_id"], unique=False)
    op.create_index(
        "idx_job_chunks_result", "job_chunks", ["job_result_id"], unique=False
    )
    op.create_table(
        "webhook_logs",
        sa.Column("id", sa.String(length=36), nullable=False),
        sa.Column("job_id", sa.String(length=36), nullable=False),
        sa.Column("event_id", sa.String(length=36), nullable=True),
        sa.Column("webhook_url", sa.String(length=512), nullable=False),
        sa.Column("attempt_number", sa.Integer(), nullable=False),
        sa.Column("request_payload", sa.JSON(), nullable=True),
        sa.Column("signature", sa.String(length=128), nullable=False),
        sa.Column("idempotency_key", sa.String(length=36), nullable=False),
        sa.Column("response_status_code", sa.Integer(), nullable=True),
        sa.Column("response_body", sa.Text(), nullable=True),
        sa.Column("error_message", sa.Text(), nullable=True),
        sa.Column("duration_ms", sa.Integer(), nullable=False),
        sa.Column("created_at", sa.DateTime(), nullable=False),
        sa.ForeignKeyConstraint(
            ["event_id"], ["webhook_events.id"], ondelete="CASCADE"
        ),
        sa.ForeignKeyConstraint(["job_id"], ["jobs.job_id"], ondelete="CASCADE"),
        sa.PrimaryKeyConstraint("id"),
    )
    op.create_index(
        "idx_webhook_logs_attempt",
        "webhook_logs",
        ["job_id", "attempt_number"],
        unique=False,
    )
    op.create_index(
        "idx_webhook_logs_created_at", "webhook_logs", ["created_at"], unique=False
    )
    op.create_index(
        "idx_webhook_logs_event_id", "webhook_logs", ["event_id"], unique=False
    )
    op.create_index("idx_webhook_logs_job_id", "webhook_logs", ["job_id"], unique=False)
    # ### end Alembic commands ###


def downgrade() -> None:
    """Downgrade schema."""
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index("idx_webhook_logs_job_id", table_name="webhook_logs")
    op.drop_index("idx_webhook_logs_event_id", table_name="webhook_logs")
    op.drop_index("idx_webhook_logs_created_at", table_name="webhook_logs")
    op.drop_index("idx_webhook_logs_attempt", table_name="webhook_logs")
    op.drop_table("webhook_logs")
    op.drop_index("idx_job_chunks_result", table_name="job_chunks")
    op.drop_index("idx_job_chunks_chunk_id", table_name="job_chunks")
    op.drop_table("job_chunks")
    op.drop_index(op.f("ix_webhook_events_status"), table_name="webhook_events")
    op.drop_index("idx_webhook_events_status", table_name="webhook_events")
    op.drop_index("idx_webhook_events_next_retry", table_name="webhook_events")
    op.drop_index("idx_webhook_events_job_id", table_name="webhook_events")
    op.drop_index("idx_webhook_events_created_at", table_name="webhook_events")
    op.drop_table("webhook_events")
    op.drop_index("idx_job_state_history_job_id", table_name="job_state_history")
    op.drop_index("idx_job_state_history_created_at", table_name="job_state_history")
    op.drop_table("job_state_history")
    op.drop_index("idx_audit_log_job_id", table_name="job_state_audit_logs")
    op.drop_index("idx_audit_log_job_created", table_name="job_state_audit_logs")
    op.drop_index("idx_audit_log_created_at", table_name="job_state_audit_logs")
    op.drop_table("job_state_audit_logs")
    op.drop_table("job_results")
    op.drop_index("idx_webhook_secrets_user_id", table_name="webhook_secrets")
    op.drop_index("idx_webhook_secrets_user_endpoint", table_name="webhook_secrets")
    op.drop_index("idx_webhook_secrets_status", table_name="webhook_secrets")
    op.drop_table("webhook_secrets")
    op.drop_table("user_balances")
    op.drop_index(op.f("ix_payment_records_user_id"), table_name="payment_records")
    op.drop_index(
        op.f("ix_payment_records_stripe_subscription_id"), table_name="payment_records"
    )
    op.drop_index(
        op.f("ix_payment_records_payment_intent_id"), table_name="payment_records"
    )
    op.drop_index(
        op.f("ix_payment_records_checkout_session_id"), table_name="payment_records"
    )
    op.drop_table("payment_records")
    op.drop_index(op.f("ix_jobs_user_id"), table_name="jobs")
    op.drop_index("idx_job_user_status", table_name="jobs")
    op.drop_index(
        "idx_job_user_active_states",
        table_name="jobs",
        postgresql_where=sa.text(
            "status IN ('waiting-file', 'pending', 'running', 'converting')"
        ),
    )
    op.drop_index("idx_job_type", table_name="jobs")
    op.drop_index("idx_job_status", table_name="jobs")
    op.drop_index("idx_job_created_at", table_name="jobs")
    op.drop_table("jobs")
    op.drop_index(
        op.f("ix_credits_transactions_user_id"), table_name="credits_transactions"
    )
    op.drop_index(
        op.f("ix_credits_transactions_stripe_payment_id"),
        table_name="credits_transactions",
    )
    op.drop_index(
        op.f("ix_credits_transactions_created_at"), table_name="credits_transactions"
    )
    op.drop_table("credits_transactions")
    op.drop_index(op.f("ix_api_keys_user_id"), table_name="api_keys")
    op.drop_index(op.f("ix_api_keys_key_hash"), table_name="api_keys")
    op.drop_table("api_keys")
    op.drop_table("tier_limits")
    op.drop_table("system_limits")
    op.drop_index(
        op.f("ix_stripe_price_configs_price_id"), table_name="stripe_price_configs"
    )
    op.drop_table("stripe_price_configs")
    op.drop_index(op.f("ix_path_base_id"), table_name="path_base")
    op.drop_table("path_base")
    op.drop_index(op.f("ix_knowledge_base_id"), table_name="knowledge_base")
    op.drop_table("knowledge_base")
    op.drop_index(op.f("ix_file_directory_id"), table_name="file_directory")
    op.drop_table("file_directory")
    # ### end Alembic commands ###
