refactor(architecture): 修复模块依赖违规并强化架构守护

- 字幕编排上移 DownloadChain.download_site_subtitles,SubtitleModule 仅保留站点链接解析
- TransferChain.recommend_name 上移 TV episodes_info 获取,filemanager 模块不再导入 TmdbChain
- endpoint 穿透修复:WXBizMsgCrypt3 迁至 adapters/external/wechat_crypt.py;
  music/tmdb 缓存管理、listenbrainz 常量、TMDbException、WechatClawBot 辅助统一经 chain 包装
- RuleParser 与 builtin_rules 合并为 application/filter_rules.py;
  fsproxy/fsworker 迁至 adapters/system/
- chain/__init__.py 删除 qbittorrentapi/transmission_rpc 导入,消除后端协议类型泄漏
- 架构守护测试新增三项检查:模块间隔离、入口层穿透、下载器 SDK 泄漏
- 文档同步:05-architecture.md 记录 DB/Oper 聚合例外与迁移文件位置,AGENTS.md 更新所有权表
This commit is contained in:
jxxghp
2026-08-16 04:59:17 +08:00
parent f7e39a47c6
commit 02f0dd0b9a
37 changed files with 630 additions and 450 deletions
+9 -3
View File
@@ -314,7 +314,9 @@ def test_music_cache_endpoint_returns_management_statistics(monkeypatch):
"recognized": {"media_id": "rec-1", "title": "晴天"},
"unrecognized": {"media_id": "", "title": "未知曲目"},
})
monkeypatch.setattr(music_endpoint, "MusicBrainzCache", lambda: cache)
monkeypatch.setattr(
music_endpoint.MusicBrainzChain, "cache_items", staticmethod(cache.list_items)
)
response = asyncio.run(music_endpoint.music_recognition_cache(None))
@@ -328,7 +330,9 @@ def test_music_cache_endpoint_returns_management_statistics(monkeypatch):
def test_music_cache_delete_endpoint_reports_missing_item(monkeypatch):
"""删除接口应区分成功删除与缓存不存在。"""
cache = _build_music_cache({"existing": {"media_id": "rec-1"}})
monkeypatch.setattr(music_endpoint, "MusicBrainzCache", lambda: cache)
monkeypatch.setattr(
music_endpoint.MusicBrainzChain, "delete_cache", staticmethod(cache.delete)
)
deleted_response = asyncio.run(
music_endpoint.delete_music_recognition_cache("existing", None)
@@ -344,7 +348,9 @@ def test_music_cache_delete_endpoint_reports_missing_item(monkeypatch):
def test_music_cache_clear_endpoint_removes_all_items(monkeypatch):
"""清空接口应删除全部音乐识别缓存。"""
cache = _build_music_cache({"existing": {"media_id": "rec-1"}})
monkeypatch.setattr(music_endpoint, "MusicBrainzCache", lambda: cache)
monkeypatch.setattr(
music_endpoint.MusicBrainzChain, "clear_cache", staticmethod(cache.clear)
)
response = asyncio.run(music_endpoint.clear_music_recognition_cache(None))