"""app_user 支持邮箱注册:放开 phone 非空、记录邮箱已验证时间 手机验证码登录关掉以后,新用户是「邮箱 + 验证码」注册进来的,此时还没有手机号; `app_user.phone` 原来 NOT NULL,不放开就没法插这类账号。 `email_verified_at` 用来区分"填了个邮箱字符串"和"这个地址确实验证过": 注册流程发码成功后写入;账号页手工绑邮箱时同一套流程。 Revision ID: 0011 Revises: 0010 """ from __future__ import annotations from alembic import op from app.roles import APP_ROLE revision = "0011" down_revision = "0010" branch_labels = None depends_on = None def upgrade() -> None: # 邮箱注册的账号没有手机号:老账号都有值,放开非空不影响它们 op.execute("ALTER TABLE app_user ALTER COLUMN phone DROP NOT NULL") op.execute("ALTER TABLE app_user ADD COLUMN IF NOT EXISTS email_verified_at TIMESTAMPTZ") op.execute( "COMMENT ON COLUMN app_user.email_verified_at IS " "'邮箱验证通过的时间;为空表示还没验证过这个地址'" ) # 本表全局(不挂租户),只补列不新增表,权限照旧:应用角色要能读写这些列 op.execute(f"GRANT SELECT, UPDATE ON app_user TO {APP_ROLE}") def downgrade() -> None: # 回滚前先把没有手机号的账号补上占位值,否则加回 NOT NULL 会失败 op.execute("UPDATE app_user SET phone = 'redeem-' || replace(id::text, '-', '') WHERE phone IS NULL") op.execute("ALTER TABLE app_user DROP COLUMN IF EXISTS email_verified_at") op.execute("ALTER TABLE app_user ALTER COLUMN phone SET NOT NULL")