yml2213
8f231e6edf
fix(binding): 角色绑定只看 is_bound_role —— 「是否开通」与「是否绑定角色」是两件事
用户明确指出:**精英/电竞是否开通,和是否绑定角色没关系**。
## 我确实混了(虽然这次没触发)
`derive_from_bind_info` 里有个兜底:
if bound_role is True or bound_act is True: return BOUND
`role_bind_status` 这一列问的是「**角色**绑没绑」,而 `is_bound_act` 是
「**活动**维度」的标志 —— 拿它兜底就是把两件事混起来。
一旦有账号 `is_bound_act=True` 而角色未绑,就会报出"角色已绑定"的**错结论**。
## 生产数据证实了用户的说法
查已查询的 196 个账号:
电竞 opened=False 且 bind=bound → **187 个**
也就是**187 个账号绑了角色、但电竞手册压根没开通** —— 两者完全独立。
同时数据也证明 `is_bound_role` 本身就够用(不需要那个兜底):
判为 bound 的里面:精英 183 个全都有角色名(0 个没有)
电竞 187 个全都有角色名(0 个没有)
## 改法
去掉 `is_bound_act` 的参与,**只看 `is_bound_role`**:
is_bound_role 真 → bound
is_bound_role 假 → unbound
缺失 → None(保持 unknown,别把"没查到"写成"没绑定")
语义上不再有"把活动当角色"的路径。
## 测试
把两条**编码了旧行为**的用例改掉,并补一条钉住领域事实:
- 只有 `is_bound_act` 没有 `is_bound_role` → **None**(推不出角色结论)
- `{"is_bound_role": True, "manual_type": 0, "expire_time": "0"}` → **bound**
(绑了角色+没开通,两者独立,不该因为"没开通"而变成别的)
## 验证(本地)
TZ=Asia/Shanghai **620 passed / 6 skipped**;ruff 全绿。