feat: add local autosave history prototype

This commit is contained in:
QiuSW
2026-08-04 23:00:05 +08:00
parent b62e9697a4
commit a82af6939f
31 changed files with 1730 additions and 73 deletions
+23 -10
View File
@@ -7,11 +7,11 @@
| 数据 | 来源 | 默认位置 | 敏感性 | 是否参与起卦 |
|---|---|---|---|---|
| 三轮币面/六爻结果 | 用户输入/本地计算 | 会话状态,可选 Room | 低至中 | 是 |
| 用户问题 | 用户输入 | 会话状态,可选 Room | 高 | 否 |
| 十八枚币面/六爻结果 | 用户输入/本地计算 | 会话状态;结果锁定后默认 Room | 低至中 | 是 |
| 用户问题 | 用户输入 | 会话状态;按默认开启的设置进入 Room | 高 | 否 |
| 64 卦与爻辞 | 经审核的内容包 | assets 或预置 Room | 低,关注版权 | 仅用于查表 |
| 本地解释 | 编辑内容 | assets | 低,关注版权 | 否 |
| AI 请求与回复 | 用户主动请求 | 内存,可选 Room | 高 | 否 |
| AI 请求与回复 | 用户主动请求 | 请求在内存;回复按默认开启的设置进入 Room | 高 | 否 |
| 偏好与同意版本 | 用户设置 | DataStore | 中 | 否 |
任何“否”的数据都不能成为 `CastEngine` 输入。
@@ -106,6 +106,7 @@ ExplanationEntity
- contractVersion: string
- content: validated structured JSON
- createdAt
- supersedesExplanationId: nullable foreign key
ActionNoteEntity
- sessionId: foreign key
@@ -118,6 +119,9 @@ ActionNoteEntity
- 数据库存储原始 18 枚币面和确定结果,读取时可重新计算并进行一致性检查。
- `questionText` 默认可为空;用户不保存问题时不能偷偷复制到其他表。
- 第六爻锁定时读取一次 `HistorySavePolicy` 快照;总开关开启时,在单个事务中创建 `CastingSessionEntity`,并按默认开启的内容开关写入 `questionText`。关闭总开关或选择“本次不保存”时不得产生长期记录。
- 同一流程随后生成的本地或 AI 解读按策略写入关联的 `ExplanationEntity`;重新解读新增实体并通过 `supersedesExplanationId` 保留版本关系,不得静默覆写旧正文。
- 行动记录按策略关联到同一 session;没有实际行动内容时不创建空 `ActionNoteEntity`。
- 删除 session 应级联删除解释和行动记录。
- enum 使用稳定字符串或显式转换,不依赖 Kotlin ordinal。
- 每次 schema 迁移必须有 migration test;禁止发布构建使用 destructive migration。
@@ -131,7 +135,12 @@ DataStore 仅保存少量偏好:
- 减少应用内非必要动画;
- AI 同意文本版本和同意时间;
- 默认解释方式;
- 是否允许保存问题原文。
- `autoSaveHistory`:默认 `true`;
- `saveQuestionText`:默认 `true`;
- `saveExplanationContent`:默认 `true`;
- `saveActionNote`:默认 `true`。
总开关关闭时,后三项不参与自动写入,但保留用户上次选择;再次开启后恢复。DataStore 中的本地保存偏好与 AI 同意版本是独立字段,不得相互推导。
不要把六爻历史、完整内容包或 AI 长文本塞入 DataStore。
@@ -143,22 +152,26 @@ DataStore 仅保存少量偏好:
- AI 请求前展示准确的数据清单和服务方类别。
- 日志、分析、崩溃报告、截图测试夹具不得使用真实用户问题。
- 调试日志使用固定脱敏样例;发布构建关闭网络 body logging。
- 历史导出、云备份和 Android Auto Backup 策略在实现前必须单独决策。
- `CastingSessionEntity`、`ExplanationEntity`、`ActionNoteEntity` 所在的 Room 数据库及其 `-wal`、`-shm` 等辅助文件必须通过 Android backup/data-extraction 规则排除,不参与 Auto Backup、设备到设备迁移或厂商云备份。
- MVP 不提供历史导出、账号或云同步。未来任何导出、备份或同步都必须新增决策、展示准确范围并取得单独的明确选择。
## 8. 数据生命周期
```text
草稿问题/未完成投币:SavedStateHandle + 内存
↓ 用户完成
↓ 第六爻确认并锁定
不可变 CastResult:结果页内存
↓ 用户明确保存
Room 历史快照
├─ autoSaveHistory=true → Room 会话快照 + 按设置保存问题
└─ autoSaveHistory=false → 不写 Room,可由用户选择“保存本次”
AI 请求:请求期间内存 → 服务端按已披露策略处理
AI 回复:结果页内存 → 用户保存后可进入 Room
本地/AI 回复:结果页内存 → 按设置关联到同一 Room 会话
└─ 会话不存在或解释保存关闭 → 不长期保存,可由用户选择保存本次
```
会话中止后是否保留草稿由产品设置决定;无论如何都不能把草稿作为遥测发送。
“最近一次”不是独立复制的数据,而是按 `createdAt` 从 Room 查询得到的最新已保存会话。首页不得缓存另一份问题或解释正文;删除该会话后,最近记录区域必须随查询结果一起更新为空态或下一条记录。
中止的未完成草稿只按 SavedState 恢复策略存在,不进入问卦簿;无论如何都不能把草稿作为遥测发送。用户选择“本次不保存/删除本次记录”后,应删除已经自动创建的 session 及其关联内容,但不改写全局设置。
## 9. 内容变更规则