"""Telegram bot user hardening: rate-limit, profile guards, binding audit. Revision ID: 0005 Revises: 0004 Create Date: 2026-08-13 Adds optional audit columns to users for Telegram-bound accounts and a verification flag so the admin panel can review anonymous/suspicious accounts. """ from __future__ import annotations from collections.abc import Sequence import sqlalchemy as sa from alembic import op # revision identifiers, used by Alembic. revision: str = "0005" down_revision: str | None = "0004" branch_labels: str | Sequence[str] | None = None depends_on: str | Sequence[str] | None = None def upgrade() -> None: # Telegram profile snapshot captured on first /start (for admin review). op.add_column( "users", sa.Column( "telegram_profile_json", sa.Text(), nullable=True, comment="Snapshot of Telegram first_name/last_name/username/language_code", ), ) # True once the account is considered trusted. New auto-created Telegram # users may start as not_verified if their profile is empty. op.add_column( "users", sa.Column( "telegram_verified", sa.Boolean(), nullable=False, server_default=sa.text("true"), comment="Telegram user passed profile guard; false = admin review", ), ) # Audit timestamp for when a Telegram identity was first bound. op.add_column( "users", sa.Column( "telegram_bound_at", sa.DateTime(timezone=True), nullable=True, comment="When telegram_id was first set (auto-created or bound)", ), ) op.create_index("users_telegram_verified_idx", "users", ["telegram_verified"]) op.create_index("users_telegram_bound_idx", "users", ["telegram_bound_at"]) def downgrade() -> None: op.drop_index("users_telegram_bound_idx", table_name="users") op.drop_index("users_telegram_verified_idx", table_name="users") op.drop_column("users", "telegram_bound_at") op.drop_column("users", "telegram_verified") op.drop_column("users", "telegram_profile_json")