"""Make users.email the unique login identifier (NOT NULL + unique index). Backfills any missing/blank email from username first, so existing rows (e.g. the seeded admin, which historically had no email) never violate the new constraint. Revision ID: b067 Revises: b066 Create Date: 2026-07-23 """ from alembic import op import sqlalchemy as sa revision = "b067" down_revision = "b066" branch_labels = None depends_on = None def upgrade() -> None: op.execute( "UPDATE users SET email = username WHERE email IS NULL OR email = ''" ) op.alter_column("users", "email", existing_type=sa.String(), nullable=False) op.create_unique_constraint("uq_users_email", "users", ["email"]) op.create_index("ix_users_email", "users", ["email"]) def downgrade() -> None: op.drop_index("ix_users_email", table_name="users") op.drop_constraint("uq_users_email", "users", type_="unique") op.alter_column("users", "email", existing_type=sa.String(), nullable=True)