mirror of
https://github.com/panatgithub/AnkiHeadingSync.git
synced 2026-07-22 06:51:43 +00:00
6.7 KiB
6.7 KiB
QA Group 用户模板化实现决策
本文锁定本轮“QA Group 改为用户模板 + 自动字段映射”的仓库兼容实现方案。
1. 作用域决策
- 只重构
qa-group路径。 basic/cloze/semantic-qa的现有同步主线保持不变。- 不借机重做普通卡片字段映射体系。
2. 默认模型决策
- 三类可见卡片默认模板都改为空:
basicqa-groupcloze
semantic-qa继续保持当前隐藏状态,不纳入本轮产品行为变更。- 设置层允许空模板保存;真正的“必须选择模型”约束放到同步时执行。
3. 映射类型决策
-
NoteModelFieldMapping升级为联合类型:- basic-like mapping
- cloze mapping
- qa-group mapping
-
新增:
QaGroupSlotMapping = { index; questionField; answerField }QaGroupFieldMapping = { cardType: "qa-group"; modelName; loadedFieldNames; titleField; slots; warnings; acceptedWarnings?; loadedAt }
-
qa-group不再使用bodyField或mainField。
4. QA Group 自动识别服务决策
- 新增独立服务:
QaGroupFieldMappingService。 - 它负责:
- 按优先级识别 title 字段
- 识别连续完整的 question/answer slot
- 输出 warnings
- 校验已保存 mapping 是否仍然有效
NoteFieldMappingService不再负责 qa-group 的 suggest/map 逻辑。
5. title 字段优先级决策
- 按以下顺序做不区分大小写的精确优先匹配:
题目标题正面StemTitle
- 若均不存在,则识别失败。
6. slot 识别规则决策
- 问题字段支持:
问题01问题1Q01Q1S01_Q
- 答案字段支持:
答案01答案1A01A1S01_A
- 只启用从 1 开始连续且完整配对的 slot。
- 识别到不完整配对时:
- 记录 warning
- 只保留前面的完整连续 slot
- 如果最小索引不是 1,则直接识别失败。
- 旧模型
Stem + S01_Q/S01_A作为普通用户模板兼容支持。
7. warnings 与确认决策
warnings保存当前识别结果。acceptedWarnings保存用户已确认忽略的 warning 文本列表。- 当字段列表变化导致 warning 文本变化时:
- 重新计算
warnings - 清空
acceptedWarnings
- 重新计算
- 同步前的放行条件是:
warnings.length === 0- 或
acceptedWarnings与当前warnings完全一致
8. 设置页行为决策
- QA Group 行不再渲染 question/body 下拉框。
- QA Group 行显示:
- note type 下拉
- 自动识别出的 title 字段
- 已识别 slot 数量
- warning 文案
- warning 确认控件
- 如果 qa-group 模型已选且缓存字段可用:
- 自动生成 mapping
- 自动保存到
noteFieldMappings
- 如果识别失败:
- 不保存无效 mapping
- 在设置页显示清晰错误
- basic/cloze 仍沿用当前字段下拉行为。
9. 刷新按钮决策
- 保持当前优化后的按钮流程:
listNoteModels()一次getModelFieldNamesByModelNames()一次
- 刷新后:
- 普通卡片继续只水合 draft mapping
- QA Group 如果当前模型有缓存字段,则立即重算并持久化 qa-group mapping
10. 同步时模型选择与报错决策
- 普通卡片:在
RenderConfigService里对空模型抛出PluginUserError。 - QA Group:在
QaGroupSyncService中对空模型抛出PluginUserError。 - 这样可以满足“空模型在同步时清晰报错”,又不阻止设置页保存。
11. QA Group 主同步决策
QaGroupSyncService不再依赖:QaGroupModelService.ensureModel()QA_GROUP_MODEL_NAMEQA_GROUP_SLOT_COUNTbuildQaGroupNoteFields(...)
- 同步输入改为:
settings.cardTypeConfigs["qa-group"].noteTypesettings.noteFieldMappings["qa-group:<modelName>"]
- 同步前校验:
- 已选择模型
- mapping 存在且类型为
qa-group - title 字段存在
- 至少 1 个 slot
- warnings 已确认或不存在
- slot 字段仍存在于当前 Anki 模型
12. 写字段决策
- 只写:
mapping.titleField- 每个
slot.questionField - 每个
slot.answerField
- 未使用但已映射的 slot 字段统一写空字符串,避免旧内容残留。
- 不再写:
GroupIdSrcSxx_Id
13. 回链决策
- QA Group 不再把回链写入
Src字段。 - 改为同步时直接把回链字符串拼入用户字段内容:
question-last-line-> 追加到 title 字段answer-first-line-> 追加到每个已用 answer 字段开头answer-last-line-> 追加到每个已用 answer 字段末尾
addObsidianBacklink = false时不写回链。
14. 恢复策略决策
- 继续保留本地 state 和 GI marker 作为主要身份恢复来源。
- 删除按
GroupId/Src查询 Anki 的恢复分支。 - 若只有
noteId可用,可从 Anki note 内容按保存的 qa-group mapping 恢复 question/answer 展示内容。 - 这种场景下恢复出的
itemId使用临时格式:recovered-slot-01recovered-slot-02
15. slot 上限与 GI marker 决策
- QA Group 容量来自
mapping.slots.length。 GroupMarkerService不再把 slot 范围上限硬编码为 12。freeSlots的范围改为依据当前 mapping 可用 slot 集合生成。
16. 兼容保留决策
ManagedNoteModels.QA_GROUP_MODEL_NAME可以保留为兼容常量,但不能再被 QA Group 主同步流程使用。QaGroupModelDefinition/QaGroupModelService可以保留为兼容或测试工具,但不能再由 Manual Sync 主流程调用。- 若这些文件保留,其测试也只表示“兼容工具仍可工作”,不再代表主流程行为。
17. 测试决策
- 新增
QaGroupFieldMappingService单测,覆盖 title/slot 识别与 warning。 - 调整
PluginSettingTab.test.ts,覆盖 QA Group 新 UI、自动识别、warning 确认与确认重置。 - 重写
QaGroupSyncService.test.ts,覆盖:- 用户模板字段写入
- 容量校验
- 回链拼接
- 不写内部字段
- 本地 state / GI marker 仍保留 groupId、itemId、slot
- 调整
ManualSyncService.test.ts和PluginSettings.test.ts,去掉对托管模型默认值与 ensureModel 主流程的断言。
18. 与草案的受控偏离
- 草案写到“如果 warning 存在,允许保存草稿”。当前仓库没有单独的 qa-group draft 持久层,最兼容实现是:直接把带 warnings 的 qa-group mapping 保存进
noteFieldMappings,并用acceptedWarnings控制同步放行。这样既满足“可保存草稿”,也复用现有 data.json 结构。 - 草案没有显式提 GI marker 的
1..12限制,但仓库真实实现里这会直接限制用户模板容量,因此本轮会一并解除该硬编码;这是为满足“N 不固定”所必须的仓库兼容修正。