Files
MediaOrganizer/docs/adr/0020-search-chain-abstraction.md
Shuery c1ed1795c2
CI / lint + test + build (push) Canceled after 0s
docs: 重写 README、新增项目报告与开发工具配置
- README 现代化重写:徽章区、特性一览、统一 GitHub 提示块格式、修正版本号与 AI 默认值
- 新增 docs/PROJECT_REPORT.md 学术项目报告(含许可证合规分析与死链修复记录)
- 收录 23 份 ADR 架构决策记录与 CONTEXT.md 领域术语表
- 新增开发配置:.editorconfig / .shellcheckrc / .markdownlint-cli2.jsonc
- .gitignore 补充 mo_map/、检查报告、编辑器临时文件
- 新增 config.example.json 配置模板(不含真实密钥)
2026-08-14 22:41:40 +08:00

8 lines
1.8 KiB
Markdown

# 搜索链抽象(R1):统一尝试器消除逐层复制
识别搜索链(zh → en → 规则别名 → 目录 → MAL → 后缀二次剥离)经三轮功能叠加后,每层都是 `tmdb_api(_lang) + 结果选择 + 失败条件` 的复制粘贴变体——`pick_tv_show_id` 调用点达 9 处,新增一层兜底需要复制 ~10 行且容易漏掉失败语义。决定:抽象 `tv_search_once` / `movie_search_once` 统一尝试器——参数(query/季号/特典/语言/年份),返回码约定(0=命中 stdout=id;1=无结果;2=请求失败),电影版以两行协议(id + 单行响应 JSON)回传响应供调用方做年份校验/需甄别检测(bash 无多返回值,命令替换子 shell 会丢全局赋值,两行协议是零新依赖的惯用回传)。
**行为保持契约**(测试锁定):① 主搜索(zh)失败(rc=2)立即短路 return 2,后续层不执行;② 后续层失败(rc=2)忽略继续下一层;③ 别名层失败不试其 en 变体(`_ar -ne 2` 守卫);④ movie 的 result 只在 zh/en/别名/MAL 命中时更新(目录命中不更新——原行为);⑤ 后缀二次剥离修改 `search_name` 影响后续 MATCH emit 与季偏移查询——保持不变;⑥ 目录兜底(tv/movie_search_by_dir)保留对外签名,内部改用尝试器。
**Considered Options**: 保留逐层复制(原状)——每新增一层兜底维护成本线性增长,失败语义易漂移;全局变量回传响应(`LAST_SEARCH_RESPONSE`)——命令替换子 shell 赋值丢失,需调用方同 shell 调用,破坏现有模式;整链一次性编排(query 列表驱动)——六层的 query 生成逻辑(别名查表/MAL 网络/目录名清洗)各不相同,编排层反而更复杂,统一"单次尝试"粒度是抽象与简单的平衡点。