feat(db): S1 迁移 0042 —— 账号全生命周期落库(登录态 + 状态机 + 事件台账)
账号不再依赖登录记录的第一步:把「账号自己的东西」搬到账号上。本提交**只加列、 只读源表**,不改任何行为,单独部署安全。 accounts 新增 15 列: - 登录态:cookie / cookie_updated_at / cookie_source - CK 健康:ck_check_status / ck_check_result / ck_checked_at - 重登进度:relogin_attempts / relogin_next_at / relogin_last_error / relogin_failure_kind - 生命周期:status / status_reason / status_changed_at / disabled_at / archived_at - 索引:ck_checked_at、status、与 (status, relogin_next_at) account_events 新增 5 列(category / subject_type / subject_key / actor_type / actor_id) 与台账复合索引 (account_id, event_type, subject_key, occurred_at) —— 支撑 「365 天同皮肤」这类需要检索客体的规则,让事件表同时承担业务台账。 login_tasks 补 (account_id, attempt_status) 索引:CK 搬到账号后,「在途尝试」只能留在 登录记录上,巡检/重登每轮都要按它过滤。 回填做成生产级: - 只读 login_tasks、分块 200 账号、幂等(只在 accounts.cookie 为空时写); - 窗口函数取「最近一条持 CK 的行」,不用 GROUP_CONCAT(受 max_len 限制会静默截断); - 自校验 fail closed:回填不完整直接抛错让应用起不来,宁可起不来也不带半份 CK 上线; - 外加值级校验,防张冠李戴(条数相等仍可能 A 账号拿到 B 账号的 CK)。 踩坑留档:cookie 是 TEXT,**不能有 server_default**(MySQL 1101: BLOB/TEXT/GEOMETRY/JSON column can not have a default value),模型与迁移两侧都要去掉。 验证: - 空库整链 upgrade head + 模型对齐 + 索引存在 → 通过; - 本机开发库实跑 0041→0042:记录侧 4 个持 CK 账号 = 账号侧 4 个,值级不一致 0, CK 仍是密文(enc:v1: 前缀),状态分布 active 4 / imported 8; - downgrade 到 0041 再 upgrade:数据完整还原(这是 CK 丢失场景的安全网); - 全量 pytest 364 passed / 6 skipped。
This commit is contained in:
@@ -26,7 +26,7 @@ TESTS_DIR = Path(__file__).resolve().parent
|
||||
PROJECT_ROOT = TESTS_DIR.parent
|
||||
VERSIONS_DIR = PROJECT_ROOT / "web" / "backend" / "migrations" / "versions"
|
||||
|
||||
HEAD_REVISION = "20261003_0041"
|
||||
HEAD_REVISION = "20261003_0042"
|
||||
|
||||
# 迁移新增、但不声明在模型里的复合查询索引。
|
||||
EXTRA_INDEXES = (
|
||||
@@ -36,6 +36,9 @@ EXTRA_INDEXES = (
|
||||
"ix_login_tasks_status_finished_at_id",
|
||||
# 账号时间线按「账号 + 时间倒序」查,模型里不声明这个复合索引。
|
||||
"ix_account_events_account_occurred",
|
||||
# CK 搬到账号后,「在途尝试」只能留在登录记录上,巡检/重登每轮按
|
||||
# (account_id, attempt_status) 过滤 —— 模型里不声明这个索引。
|
||||
"ix_login_tasks_account_attempt_status",
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user