docs: update V2 architecture to reflect DOC-FULL-001~006 changes

- ReadingMaterialRef → ReadingMaterialRefV2 (full fields, camelCase)
- ReadingSessionV2: add closed_at_ms, Interrupted/Failed statuses
- EventBuffer: add reload_stale_events_v2, buffer_size_v2
- V1/V2 diff table: add session status/recovery rows
- Verification chain: add startup recovery + V2 MaterialRef

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
wangdl 2026-06-11 21:10:58 +08:00
parent e64f96d43c
commit 6250dacd71

View File

@ -103,29 +103,43 @@ Rust exportPendingEventsV2 → iOS 写本地队列 → iOS ackEventsV2(eventIds)
## 3. 核心 V2 模型
### 3.1 ReadingMaterialRef
### 3.1 ReadingMaterialRefV2
```rust
pub struct ReadingMaterialRef {
pub material_id: String,
pub struct ReadingMaterialRefV2 {
pub material_id: String, // 业务 ID
pub file_path: String, // 本地文件路径
pub file_name: String, // 文件名
pub file_type: String, // markdown / pdf / epub / text / image / office
pub mime_type: Option<String>, // MIME 类型(可选)
pub file_size: Option<u64>, // 文件大小字节(可选)
pub content_hash: Option<String>,// 内容哈希(可选)
pub created_at_ms: Option<i64>, // 创建时间毫秒(可选)
}
```
不包含:`readingTargetType`, `userId`, `knowledgeBaseId`, `platform`, `appVersion`
V1 `ReadingMaterialRef`(仅 `material_id`)标记 `#[deprecated]`,保留不删除。
### 3.2 ReadingSessionV2
```rust
pub struct ReadingSessionV2 {
pub client_session_id: String, // UUID, Rust 生成
pub material: ReadingMaterialRef,
pub material: ReadingMaterialRefV2,
pub started_at_ms: i64,
pub closed_at_ms: Option<i64>, // 关闭时间(由 iOS 传入)
pub last_event_at_ms: i64,
pub next_sequence: u64, // 从 1 递增
pub total_active_seconds: u32,
pub last_position: Option<ReadingPosition>,
pub status: ReadingSessionStatus, // Active | Paused | Closed
pub status: ReadingSessionStatus, // Active | Paused | Closed | Interrupted | Failed
}
```
新增方法:`mark_session_interrupted_v2`, `mark_session_failed_v2`, `get_active_session_v2`, `set_session_closed_at_ms`
### 3.3 ReadingEventV2
```rust
@ -173,10 +187,12 @@ pub struct BufferedReadingEventV2 {
}
```
方法:`push_event_v2 / export_pending_events_v2 / ack_events_v2 / mark_events_failed_v2`
方法:`push_event_v2 / export_pending_events_v2 / ack_events_v2 / mark_events_failed_v2 / reload_stale_events_v2 / buffer_size_v2`
容量:最大 1000 条,超出时 Failed→Exported→Pending 顺序清理。
`reload_stale_events_v2`:启动时将 Exported 但未 ack 的事件重置为 Pending用于 App crash 后的恢复。iOS 启动时必须调用。
---
## 4. V1 → V2 迁移策略
@ -197,7 +213,9 @@ pub struct BufferedReadingEventV2 {
| client_session_id | 无 | UUID |
| active_seconds | 累计值/语义模糊 | active_seconds_delta 增量 |
| sequence | 无 | 递增 |
| target | material_id 裸字符串 | ReadingMaterialRef |
| target | material_id 裸字符串 | ReadingMaterialRefV2含 filePath/fileName/fileType 等) |
| session status | - | Active/Paused/Closed/Interrupted/Failed |
| session recovery | - | reload_stale_events_v2 / mark_session_interrupted_v2 |
---
@ -253,13 +271,20 @@ zhixi-document-runtime
## 7. 最终验收链路
```
iOS 创建 materialId
→ Rust startReadingSessionV2
→ Rust 生成 clientSessionId
→ push MaterialOpened / PositionChanged / Heartbeat / MaterialClosed
App 启动
→ reload_stale_events_v2重置未 ack 的 Exported 事件为 Pending
→ cleanup_stale_sessions_v2清理超时旧 session
iOS 创建 ReadingMaterialRefV2只传 materialId + 文件信息)
→ Rust startReadingSessionV2生成 clientSessionId
→ push MaterialOpeneddelta=0
→ heartbeat tick 每 15s → push Heartbeatdelta=增量秒数)
→ push PositionChangeddelta=0
→ push MarkedAsReaddelta=0
→ push MaterialCloseddelta=残余秒数)
→ exportPendingEventsV2
→ iOS 写入本地队列
→ ackEventsV2
→ iOS 写入本地 ReadingEventUploadQueue
→ ackEventsV2(按 eventId 精确删除)
→ iOS 补 readingTargetType / platform / appVersion / timezone
→ API batch upload
```