# Obsidian Backlink Config Gap Report ## Scope 本报告基于当前仓库真实代码审查,聚焦这五条链路与计划差距: - settings 默认值、校验、持久化与旧 data.json 兼容 - 普通 QA / Cloze / 语义 QA 的回链渲染入口 - Cloze title/body 合并影响面 - QA Group 12 模板生成与 model drift 更新链路 - renderConfigHash 对已同步卡片的失效机制 ## Confirmed Gaps ### 1. 普通卡回链仍硬编码在 ManualCardRenderer `src/domain/manual-sync/services/ManualCardRenderer.ts` 当前只在一个分支里决定回链行为: - `addObsidianBacklink = true` 时始终向 `renderedFields.body` 末尾追加 `

Open in Obsidian

` - 没有 label 配置入口 - 没有 placement 配置入口 这意味着普通 QA、Cloze、语义 QA 目前共享同一个“答案末尾 + 固定文案”硬编码。 ### 2. Cloze 兼容点不在 renderer,而在现有字段映射合并逻辑 当前仓库结构里,Cloze 仍然由 renderer 先产出 `title` / `body`,再由 note field mapping 把它们合并进主字段。 因此实现时不需要改 Cloze 的字段结构;只要保证 `question-last-line` 改的是 `title`,`answer-first-line` / `answer-last-line` 改的是 `body`,现有 `title

body` 合并形状就会自然继承新位置。 ### 3. QA Group 12 也仍然硬编码默认回链 `src/application/services/QaGroupModelDefinition.ts` 当前在模板生成里写死: - back 模板固定把 `Open in Obsidian` 放在答案容器后 - `buildQaGroupModelDefinition()` 没有接收 settings 或其他配置参数 `src/application/services/QaGroupModelService.ts` 的 `ensureModel()` 也始终调用无参 `buildQaGroupModelDefinition()`,所以模板漂移更新机制存在,但暂时无法感知用户配置。 ### 4. QA Group note 字段链路已经独立,不需要改字段结构 `src/application/services/QaGroupSyncService.ts` 当前行为已符合计划的结构约束: - `Src` 仍由 `buildGroupBacklink()` 生成并写入 note fields - `buildQaGroupNoteFields()` 仍固定写 `Stem / GroupId / Src / S01..S12` - 没有通过普通 note field mapping 去映射 QA Group 字段 因此本轮不需要新增字段,也不需要改变 `Src` 含义,只需让 model template 生成使用当前 settings。 ### 5. settings 持久化只做默认值合并,没有空 label 归一 `src/infrastructure/persistence/DataJsonPluginConfigRepository.ts` 当前对 settings 的处理是: - load 时直接用 `DEFAULT_SETTINGS` 合并旧 snapshot - save 时直接校验后原样写回 这能处理“缺字段”,但不能处理: - 旧 / 异常 data.json 中 `obsidianBacklinkLabel` 为空字符串或全空格 - UI 保存时把全空格文案写进 settings 计划要求的空 label 归一,需要引入一个显式 normalize 层。 ### 6. renderConfigHash 目前还不感知新配置 `src/application/services/RenderConfigService.ts` 当前 hash 只包含: - note model / mapping - `addObsidianBacklink` - `convertHighlightsToCloze` - `keepPureTagLinesInCardBody` 如果只修改 label 或 placement,当前 diff planner 不会把已同步卡片判定为需要更新。 ### 7. settings UI 与 i18n 尚未暴露新配置 `src/presentation/settings/PluginSettingTab.ts` 当前只在 sync options 区域渲染了 `addObsidianBacklink` toggle,没有: - label 文本输入 - placement 下拉 中英文消息文件里也尚未存在这两组设置文案与 placement 校验错误文案。 ### 8. 现有测试覆盖还缺四个关键面 当前仓库已有: - `PluginSettings.test.ts` - `PluginSettingTab.test.ts` - `ManualCardRenderer.test.ts` - `QaGroupModelService.test.ts` - `QaGroupSyncService.test.ts` 但还缺或不足: - settings 归一化与 placement 校验 - label / placement 改变引起的 renderConfigHash 变化 - 普通卡三种 placement 的断言 - QA Group 模板三种 placement 与 drift 更新断言 ## Repository-Compatible Fix Direction 最安全的仓库兼容方案是: 1. 在 settings 层新增集中 normalize 函数,供 load/save/UI 共用。 2. 把普通卡回链渲染收口成共享 helper,并在 `ManualCardRenderer` 内按 placement 分流到 `title` 或 `body`。 3. 让 `buildQaGroupModelDefinition()` 接收 label/placement,并让 `QaGroupModelService.ensureModel()` 按 settings 生成模板。 4. 把 label/placement 纳入 `RenderConfigService` hash。 5. 只扩展现有测试锚点,不改 note 字段结构、不改 `Src` 语义、不做无关重构。 ## Out Of Scope 本轮不扩张到: - 新增 note 字段 - 改写 QA Group field contract - 修改 Cloze 合并结构 - 新增独立的 QA Group settings 面板 - 调整现有 Obsidian backlink 开关语义