`status` 列从「空壳」变成可信状态:S1 建了列、S2 让账号独立,本提交让状态真正
反映账号处境,并把「哪些账号要人处理」变成可筛选的事实。
## 状态机(7 → 6 个状态)
`imported` / `active` / `invalid` / `manual` / `disabled` / `archived`
**砍掉 `relogin`**:它完全等价于 `invalid + relogin_next_at is not None`,
独立成状态就多出一个必须与 `relogin_next_at` 同步的字段 —— 正是要消灭的「双份真相」。
## 唯一推导入口(防「双份真相」)
新增 `services/account_lifecycle.py`:
- `derive_status(account)` —— **纯函数**,按 cookie / ck_check_status / relogin_*
推导状态;人工态(disabled/archived)优先级最高,不被覆盖;
- `sync_status(db, account)` —— 推导 + 变了才写,**幂等**(没变则不写库、不发事件,
否则巡检每轮都往时间线刷一条);
- `set_manual_state(db, account, state)` —— 停用/归档/`auto`(恢复自动推导);
- `on_login_success(db, account)` —— **「登录成功对账号意味着什么」只定义一次**:
作废本轮重登退避痕迹 + 重算状态。于是**「待人工」的账号被人工登录救回来时状态
会自动恢复**,而不是卡在 manual。
- `MANUAL_KINDS` 从 `jobs/ck_relogin.py` 挪到这里(service 不该反向依赖 job)。
**9 处底层判据写入点全部接线**:登录成功、CK 清除(单个/批量)、ck_health 巡检、
人工 CK 检测、工作台执行前检测、重登复检、重登结算(成功/失败退避)。
## 消费端:补上一个真缺口 + 删掉两处临时派生
- ⚠️ **缺口**:`ck_health` / `ck_relogin` / `count_pending_relogin` 此前只按底层判据
选行,**没排除 disabled/archived** —— S2 提交里已标注,状态一上线就会变成
「停用的账号照样被自动重登」。现已全部排除。
- `automation.manual_queue` 原本用 4 个条件自己拼「需要人工」,现在一句
`status == 'manual'`。同一判据从「3 处各写一遍」收敛成「1 处推导」。
## 接口与前端
- `PUT /api/accounts/{id}/lifecycle`(disabled/archived/auto + 原因,写审计)
- `PUT /api/accounts/{id}/automation`(**接上死开关**:`auto_managed` 此前没有任何
接口/前端能改,永远是默认 True)
- 新增权限点 `account:manage`(运营默认拥有)
- 列表支持 `?status=` 筛选;**归档默认不出现**(要看需显式筛选)
- `AccountOut` / 概览接口补 status / status_label / status_reason / auto_managed
- 前端:账号列表加「状态」列与状态筛选;详情页状态卡 + 停用/归档/恢复/自动化开关
## 两个自查出来的问题(都已修)
1. **幂等键反而丢事件**:状态事件一开始用 `status:{id}:{target}:{秒级时间戳}` 作
`source_ref`,结果同一账号在同一秒内两次切到同一状态就撞唯一键,`emit` 静默吞掉
—— **状态改了、时间线却少一条**,正是本模块要消灭的「悄悄不一致」。
改为不传 `source_ref`:`sync_status` 本身已幂等,不存在重复写入路径。已加用例。
2. **迁移与运行时规则分叉**:迁移 0042 的状态回填 CASE 原本会写出已被砍掉的
`relogin`,且判据与 `derive_status` 不一致(次数用尽的会回填成 invalid 而非 manual)。
已改成逐字对应,并加一条用例**真跑那段 SQL 与纯函数逐条比对**(已验证:
临时改回旧 CASE 该用例立刻红)。
## 验证
- `TZ=Asia/Shanghai`:**404 passed / 6 skipped**(S2 后 373 → 新增 31 条)
- 迁移链 3 passed;ruff check/format 全绿;前端 `tsc -b && vite build` 通过
- 真实开发库核对:落库状态分布 active 4 / imported 8,**与 derive_status 逐账号比对无漂移**
- 新增用例覆盖:derive 真值表(每状态入口 + 人工态优先)、sync 幂等、
人工态切换、**全生命周期走查**(导入→登录→失效→重登→转人工→人工救回→清 CK→停用)、
自动化排除 disabled/archived、列表状态筛选、接口
未做(后续阶段):S4 事件发射点补齐、S5 业务事实直发事件、S6 账号页重构。
项目文档索引
更新时间:2026-10-02
当前入口
- 自动化与资料收集规划:CK 自动管理、资料收集链接、皮肤台账与半自动工单的分期计划(规划中,未开工)。
- 皮肤准入映射分析:C 桶皮肤类到斗鱼商品目录的归一与覆盖分析(923 个快手名 → 78 个斗鱼商品,覆盖率 40.1%)。
- 虎牙 Cookie 路线状态:当前实现、字段状态、验证边界和后续工作。
- 虎牙网页设备字段溯源:浏览器证据、字段来源和生成算法。
- 虎牙 Cookie 合并审计与来源矩阵:字段来源约束和合并策略。
- 虎牙精英宝典联调指南:工作台联调顺序和只读验证方法。
虎牙业务与协议
- 虎牙精英宝典 9.1 全流程分析
- 虎牙精英宝典后端与抓包对照
- 虎牙精英宝典 8.31 Python 重分析
- 虎牙精英宝典联调指南
- 网页 Cookie 缺失字段历史方案
- 虎牙 App 登录总览
- 虎牙纯 Python 自动登录总结
虎牙设备与加密逆向
- HDID 算法生成
- HDID 研究记录
- 标识符命名规范
- 铸币机终局总结
- App 登录协议抓包实证
- App 登录 WUP 明文抓包
- App 登录加密算法动态验证
- App 登录 APK 静态分析
- App 登录逆向笔记
- 扫码登录闭环逆向
- hyCred 签发侦察笔记
设备注册与运行工具
鱼翅充值接口
文档约定
- 带日期的抓包和逆向笔记属于历史证据,结论以对应日期为准。
- 当前代码行为和未完成项以“虎牙 Cookie 路线状态”为准。
- Cookie、UID、订单号和设备标识进入文档时使用脱敏值;真实数据只保存在本地 evidence 目录。
- 兑换、下单和支付属于写操作,除非明确确认,不纳入自动回归测试。