panatgithub_AnkiHeadingSync/docs/empty-deck-cleanup-fix-decisions.md
Dusk a5056dd71c fix: prevent treating unknown deck stats as cleanup candidates | 修复:防止把未知 deck 统计当成空牌组 cleanup candidates
English: Ensure that decks with unknown statistics are not incorrectly treated as empty candidates for cleanup.
中文:确保统计信息未知的牌组不会被错误地视为待清理的空牌组。
2026-04-18 22:37:08 +08:00

1.5 KiB
Raw Permalink Blame History

Empty Deck Cleanup Fix Decisions

1. DeckStat 语义

DeckStat.noteCount 改为可选值。

语义固定为:

  1. 0 表示明确为空
  2. 正数表示明确非空
  3. undefined 表示未知或缺失统计

2. Gateway 解析策略

AnkiConnectGateway.getDeckStats 不再使用任何把缺失统计映射成 0 的 fallback。

解析规则:

  1. 只接受对象形态的 rawStats[deckName]
  2. 只接受数值型 total_in_deck
  3. 缺 key、字段缺失、字段类型不对、整体结构不对都返回 noteCount: undefined

这保证未知不会伪装成 empty。

3. Candidate 筛选策略

CleanupEmptyDecksUseCase.listCandidates() 只接受:

  1. stat.noteCount === 0

其他情况全部跳过:

  1. undefined
  2. 正数

4. 删除前再校验策略

CleanupEmptyDecksUseCase.execute() 在实际删除前继续重新读取 deck stats但只把满足以下条件的 deck 视为可删:

  1. deck 当前仍存在
  2. currentDeckStatsByName.get(deckName) === 0

不再使用 ?? 0

因此:

  1. missing stats -> skipped
  2. unknown stats -> skipped
  3. nonzero stats -> skipped

5. 测试策略

新增并锁定以下 fail-safe 测试:

  1. stats 缺 key 时不判空
  2. stats 空对象时候选为空
  3. 只返回部分 deck 时,只接受显式为 0 的 deck
  4. 返回结构缺少 total_in_deck 时,不把该 deck 视为空

6. 范围控制

本次只修空牌组候选误判,不扩展:

  1. deck cleanup UI
  2. deck cleanup 交互文案
  3. 普通 sync/rebuild 行为
  4. 其他 AnkiConnect payload 兼容逻辑