# AI有声书 v2 - 系统不变量

> 不可违反的系统边界。违反其中任何一条 = CRITICAL Bug。
> 每条不变量应注明：能否自动化？当前状态（已有测试 / 无测试 / 人工检查）

## 安全边界

- INV-1: 用户只能操作自己的书籍（权限校验）— 状态：人工检查
- INV-2: 反馈内容需经过滤敏感词 — 状态：无测试

## 数据隔离

- INV-3: 播放进度只能被对应用户读取/修改 — 状态：人工检查
- INV-4: 书籍发布状态变更需记录操作人 — 状态：无测试

## 接口契约

- INV-5: 前后端 API 字段名必须与 api-contracts.md 一致 — 状态：人工检查
- INV-6: WebSocket 事件数据格式必须与 api-contracts.md 一致 — 状态：无测试

## 生成流程

- INV-7: 音频未完成时不显示视频相关按钮 — 状态：前端逻辑，人工检查
- INV-8: 批量生成中断后已完成的步骤保留 — 状态：无测试

## 书籍规模配置

- **基数**：13万字
- **黄金数 φ**：1.618033988749895
- **规模档位**：上2(34万)、上1(21万)、标准(13万)、下1~下10
- **浮动规则**：AI 生成时理解"约X字"为 ±20%，即 13万 → 10.4万~15.6万
- **字数校验上限**：`scaleWords × (1 + FLOAT_RATIO)`，超限停止生成
- **章节数浮动**：允许 ±20%（由 `FLOAT_RATIO` 控制），超出才截断/补充（差距小不处理）
- **每章字数浮动**：每章基准 1.2万字，浮动 ±50%（6000~18000字/章）
- **配置位置**：`server/src/modules/book-generator/book-type-config.ts`
  - `FLOAT_RATIO = 0.2`：总字数浮动比例（20%）
  - `WORDS_PER_CHAPTER = 2000`：每章基准字数（2千字）
  - `CHAPTER_WORDS_FLOAT_RATIO = 0.5`：每章字数浮动比例（50%）
  - `WORDS_PER_MINUTE = 200`：每分钟音频对应文本字数
  - `getWordUpperLimit()`：字数上限计算函数
  - `getChapterRange()`：章节数浮动范围计算函数
  - `getChapterWordsRange()`：每章字数浮动范围计算函数
  - `calcChapters()`：根据总字数计算章节数（每章约 1.2万 字）
  - `calcAudioMinutes()`：根据总字数计算音频时长（分钟）

---

当识别到反复出现的 Bug 模式，考虑将其添加为正式不变量。
