From af2bfe7c420d800ae1477753585c23ebad1a431a Mon Sep 17 00:00:00 2001 From: wangdl Date: Thu, 11 Jun 2026 21:20:28 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20V1=E2=86=92V2=20compatibility=20layer?= =?UTF-8?q?=20(DOC-FULL-034)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.7 --- docs/v1-v2-compatibility.md | 83 +++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 docs/v1-v2-compatibility.md diff --git a/docs/v1-v2-compatibility.md b/docs/v1-v2-compatibility.md new file mode 100644 index 0000000..b038f75 --- /dev/null +++ b/docs/v1-v2-compatibility.md @@ -0,0 +1,83 @@ +# V1 → V2 兼容层 + +## 策略 + +V1 不删除,V2 新增独立模块。iOS 可逐步迁移。 + +## V1 模块(保留 deprecated) + +| 文件 | 状态 | 说明 | +|------|------|------| +| `events.rs` | `#[deprecated]` | 旧 ReadingEvent 类型 + push/export/clear | +| `reading_material.rs` | `#[deprecated]` | 旧 ReadingMaterialRef(仅 material_id) | + +所有 V1 `#[uniffi::export]` 方法保留,确保现有 iOS V1 接入不中断。 + +## V2 模块(新增) + +| 文件 | 内容 | +|------|------| +| `reading_material.rs` | ReadingMaterialRefV2(camelCase, 8 fields) | +| `session_v2.rs` | ReadingSessionV2 + 5 statuses + lifecycle methods | +| `events_v2.rs` | ReadingEventV2 + EventBuffer (ack/failed/reload/state) | +| `time_tracker.rs` | ActiveTimeTracker(iOS 控制 tick) | +| `progress.rs` | ReadingPosition(camelCase + clamp) | + +## V1 vs V2 差异 + +| 维度 | V1 | V2 | +|------|----|----| +| material ref | `ReadingMaterialRef { material_id }` | `ReadingMaterialRefV2 { 8 fields }` | +| session | 无独立模型 | `ReadingSessionV2` + lifecycle | +| event_id | 无 | UUID v4, 36 char | +| session_id | 无 | UUID v4 | +| sequence | 无 | u64 递增 | +| active_seconds | 累计/语义模糊 | `activeSecondsDelta` 增量 | +| position | snake_case | camelCase + clamp 0~1 | +| buffer 管理 | 无 ack/failed | export→ack/failed/reload 完整生命周期 | +| time tracker | 无 | ActiveTimeTracker(iOS tick / pause / resume) | +| session recovery | 无 | reload_stale_events_v2 + interrupted/failed | + +## iOS 迁移路径 + +``` +Phase 1 (当前): + iOS 继续使用 V1 接入(V1 方法仍可用) + +Phase 2: + iOS 实现 V2ReadingRuntimeAdapter(使用 V2 方法) + 同时保留 V1ReadingRuntimeAdapter 作为 fallback + +Phase 3: + 全量切换到 V2 + V1 接口留在代码中保持编译兼容 + +Phase 4 (未来): + 确认所有端都切换到 V2 后,可移除 V1 +``` + +## active_seconds vs activeSecondsDelta + +| V1 | V2 | +|----|----| +| `active_seconds` 语义模糊,可能是累计值 | `active_seconds_delta` 每次 heartbeat 增量 | +| iOS 侧自己算 | ActiveTimeTracker 计算,基于 timestamp 差值 | +| 无 clamp / 校验 | maxDeltaSeconds=60,超出 clamp + warning | + +## FFI 接口对比 + +| V1 (deprecated) | V2 | +|-----------------|-----| +| `push_reading_event(ReadingEvent)` | `push_material_opened_v2 / push_heartbeat_v2 / ...` | +| `export_pending_events() → Vec` | `export_pending_events_v2(limit, ts) → Vec` | +| `clear_exported_events(count)` | `ack_events_v2(eventIds)` + `mark_events_failed_v2(eventIds)` | +| — | `reload_stale_events_v2()` | +| — | `get_event_buffer_state_v2()` | + +## 验收 + +- [x] V1 仍可编译(所有 V1 tests pass) +- [x] V2 新接口可用(169 tests pass) +- [x] V1 deprecated 信息清楚(`#[deprecated]` annotations) +- [x] active_seconds 与 activeSecondsDelta 差异说明 +- [x] iOS 迁移路径说明