refactor(chain): 处理链功能域 mixin 化,清理未使用导入并根治兼容层循环导入

- ChainBase 拆分为 RecognitionMixin/MessageProcessingMixin/NotificationMixin
- TransferChain 拆分为 7 个功能 mixin(_mixins.py),SubscribeChain 音乐订阅域拆出 _music.py
- 斜杠命令交互四件套收敛为 InteractionChainMixin 委托,会话管理器移至 application 层,chain 层不再 re-export
- 模块基础类收敛到 app/modules/_base(notification/mediaserver 语义重命名)
- 清理 app/chain/__init__.py 24 个未使用导入,修正 49 处测试 patch 目标到实际命名空间
- 兼容层 legacy 符号不再并入 __all__,根治 schemas 初始化反向拉起 application.transfer 的循环导入
- 修复 bangumi 集数为字符串时 set_bangumi_info 抛 TypeError
- 新增重复代码等架构门禁测试;capability 清单校验排除下划线内部目录
This commit is contained in:
jxxghp
2026-08-16 16:30:16 +08:00
parent 24671f8f18
commit 7e851dbfa7
102 changed files with 6041 additions and 5888 deletions
+13
View File
@@ -19,6 +19,11 @@ def _load_subscribe_chain_class():
module = sys.modules[module_name]
return module, module.SubscribeChain
# 交互处理器模块须在打桩上下文之外预先真实加载:其模块级会话管理器单例
# 由 SlashInteractionManager 构造,若在桩内导入会绑定桩类并残留 sys.modules
# 污染依赖真实会话管理器的后续测试
import app.application.messaging.subscribe # noqa: F401
stub_deps = {}
def ensure_module(name: str, module: types.ModuleType):
@@ -43,6 +48,12 @@ def _load_subscribe_chain_class():
chain_module.ChainBase = _ChainBase
# 链内功能域 mixin:交互四件套委托与音乐订阅域,隔离加载以空 mixin 注入
interaction_mixin_module = ensure_module("app.chain._interaction", types.ModuleType("app.chain._interaction"))
interaction_mixin_module.InteractionChainMixin = type("InteractionChainMixin", (), {})
music_mixin_module = ensure_module("app.chain._music", types.ModuleType("app.chain._music"))
music_mixin_module.MusicSubscribeMixin = type("MusicSubscribeMixin", (), {})
class _MediaChain:
"""提供订阅链隔离测试所需的统一媒体识别接口。"""
@@ -77,6 +88,8 @@ def _load_subscribe_chain_class():
def remove(self, *args, **kwargs):
return None
# 真实导入 app.application.messaging.subscribe 需要 MessageGateway 类型符号
interaction_module.MessageGateway = type("MessageGateway", (), {})
interaction_module.SlashInteractionManager = _SlashInteractionManager
interaction_module.build_navigation_buttons = lambda *args, **kwargs: []
interaction_module.format_markdown_table = lambda *args, **kwargs: ""