af615a9853
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
32 lines
1.4 KiB
Python
32 lines
1.4 KiB
Python
"""手机号换绑台账。
|
|
|
|
记录"手机号从老账号被夺走、重建为新账号(X 注销 → Y)"这一破坏性事件,支撑"一个手机号
|
|
30 天内最多换绑一次"的限制。手机号级、渠道无关(source 标来源);普通微信绑定不写此表。
|
|
见 M2 spec §4.1。
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from datetime import datetime
|
|
|
|
from sqlalchemy import DateTime, Integer, String, func
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from app.db.base import Base
|
|
|
|
|
|
class PhoneRebindLog(Base):
|
|
__tablename__ = "phone_rebind_log"
|
|
|
|
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
|
# 被换绑的真实手机号(注意:存真实号,不是老账号被腾号后的 deleted_<id>)
|
|
phone: Mapped[str] = mapped_column(String(20), index=True, nullable=False)
|
|
# 被注销的老账号 X;P 换绑时已被腾空(极边界)则为空
|
|
old_user_id: Mapped[int | None] = mapped_column(Integer, nullable=True)
|
|
# 换绑后新建的账号 Y
|
|
new_user_id: Mapped[int] = mapped_column(Integer, nullable=False)
|
|
# 换绑来源。手机号级配额、渠道无关,留字段给未来其他换绑路径共用同一份 30 天限制。
|
|
source: Mapped[str] = mapped_column(String(32), nullable=False, default="wechat_conflict")
|
|
rebound_at: Mapped[datetime] = mapped_column(
|
|
DateTime(timezone=True), server_default=func.now(), index=True, nullable=False
|
|
)
|