Skip to content

feat(sync): 逐笔记 Sync Receipt(本地修订 / 云端 ACK / 冲突) - #821

Merged
cropflre merged 30 commits into
release/v1.5.2from
feat/note-sync-receipts-v1
Oct 10, 2026
Merged

cropflre merged 30 commits into
release/v1.5.2from
feat/note-sync-receipts-v1

Conversation

@cropflre

@cropflre cropflre commented Oct 10, 2026 •

Copy link
Copy Markdown
Owner

目的

给普通笔记编辑器引入逐笔记同步收据,不再以全局 lastSyncAt、全局待同步数量为零暗示当前笔记已经云端确认。

主要改动

  • Web:按服务器和用户保存逐笔记逻辑修订。仅 Web Remote-first 且包含笔记正文的有效 HTTP 版本推进,才能确认本次修改;CRDT 元数据 REST 成功不足以证明正文同步。队列与冲突优先。Electron 内嵌后端 REST 仅表示本地 SQLite 写入,不当作云端 ACK。
  • Web 离线队列:在途请求的旧 ACK 不再移除已经更新的队列 payload;返回服务端版本时才确认对应笔记。
  • Android:在处理 Sync V2 applied/duplicate 结果的同一 SQLite 事务中持久化 mutationId ACK,并按 Profile + noteId 查询 Outbox、冲突和 ACK。
  • UI:普通笔记编辑器按当前 noteId 呈现「待核验、正在保存、等待云端、云端已确认、版本冲突、同步异常」,提供中英文文案。
  • 新增 DCC-011 契约、测试和 CI 路径。

数据保护边界

  • 云端已确认仅代表这篇笔记的修改被对应服务端确认;不承诺附件已经上传或第二设备已接收。
  • 浏览器持久化可能因配额/隐私模式失败;未知状态显式显示「待核验」而非虚构成功。
  • Android 无 ACK 记录的旧笔记、以及尚未建立远端逐笔记 ACK 查询的 Electron,保守显示「待核验」,避免将本机保存误称云端成功。
  • 后续继续支持轻量表格等其余内容编辑入口和真机强杀/离线验收。

2026-10-10 Android PJZ110 验收反馈与修复

精确提交 d8bacc6 的 Android 真机验收未通过。正文本地保留、断网重启、重连、A/B 隔离已获得设备测试证据,但有两种独立的错误云端确认以及连续编辑自身回声假冲突。不能用旧提交的 CI 通过替代真机验收。

后续修复已追加到此 PR:

  • P1:Native notes.create/update/remove/emptyTrash 在 SQLite 事务成功提交之后广播收据失效;真实 Outbox 的 pending 优先于旧 mutation ACK。新增 Markdown、富文本和 SyncStatusBadge 事件接线测试。
  • P2:applied/duplicate ACK 读取校验 result.version,在原来的出队事务中存储 serverVersion;VERSION_CONFLICT 继续读取 result.serverVersion,不得混用。
  • P2:Pull 遇到新本地待发送写入时,只有同 Profile/笔记、远端版本等于已记录的本设备 mutation ACK 且本地已领先的情况视为自身回声;不清空冲突、不覆盖本地;远端不同版本仍产生冲突。

回归:增加真实 SQLite 本地 Outbox 事务后通知测试、实际编辑器徽标事件测试、applied/duplicate/conflict 协议测试、真实并发冲突反例,并加入 DCC-011 数据一致性契约门禁。

最新自动化结果:Data Consistency Contract 3 个 job 全通过;Frontend Release Gate 通过(契约 CI,前端构建 CI)。其他非本 PR 的工作流仍有既有基线失败,不能宣称所有 CI 全绿。

仍待人工验收:在独立包名的 Android 15 真机复测 ACK 延迟 5s/7s、富文本 12s、在途切账号;先确认新 APK 的源码提交与构建资产一致。既有测试制造的 unresolved 冲突不会被新逻辑擅自清空,需单独核实后决定处理。PR 继续保留 Draft。

验收

  • Data Consistency Contract CI 全部 3 个 job 通过(HEAD 2e953f4)
  • 前端生产构建与同步队列、逐笔记收据、编辑器状态回归通过(HEAD 2e953f4)
  • Android 真机断网编辑、重连、切账号验证(需人工设备测试)

已知与本次无关的 CI 基线问题:部分前端 i18n 工作流在 AIChatPanel.tsx 的中文硬编码检查失败;需单独处理,不应误认为 Sync Receipt 功能回归失败。

Copy link
Copy Markdown
Owner Author

Android PJZ110 真机验收反馈已接收,修复已提交(2026-10-10)

确认旧 HEAD d8bacc6 的真机验收未通过,重点 P1 是“已有 ACK 时新修改在 Outbox 但 UI 仍显示云端已确认”,该问题会误导用户判断数据安全。感谢报告提供精确 mutationId、延迟 ACK 时间线及本地 SQLite 对照。

已直接更新本 PR 源分支 feat/note-sync-receipts-v1,最新提交 2e953f4:

  1. P1 已修:Android NativeLocalRepository 的笔记 CRUD 在 SQLite 事务提交后触发收据刷新,组件重新读取当前 Profile/笔记的 Outbox。增加真实 SQLite 提交通知与 SyncStatusBadge 状态刷新测试(含 Markdown、富文本及旧请求回包竞态)。
  2. P2 已修:applied/duplicate ACK 用实际协议的 result.version 校验并持久化;冲突 serverVersion 保持独立。新增三种真实响应形状测试。
  3. P2 已修(保守规则):Pull 只有在新本地编辑仍 pending、远端版本精确等于本 Profile/笔记记录的 mutation ACK 版本时,才跳过自身回声;远端新版本仍进冲突中心。不会清空历史冲突或覆盖待同步正文。

以上变更已加入 DCC-011 数据一致性回归。最新 HEAD 的 Contract coverage mapping、Client offline and Native safety、Backend durability and recovery 均通过;生产构建在本评论发布时仍处于运行中,不提前宣布全部通过。

保持 Draft,未合并。 仍需要以新 HEAD 重建的独立 Android Release 验收 APK重复 5s/7s Markdown ACK 延迟、12s 富文本 ACK 延迟、断网重启及在途 A→B→A 切换,重点检查 UI 不再错误确认且不生成新的假冲突。旧测试留下的 unresolved 冲突不做自动清理。此前提到的启动时桥接顺序异常另行跟踪;报告不构成真实 Wi‑Fi、附件及第二物理设备验收。

Copy link
Copy Markdown
Owner Author

I18n Release CI 失败项已从基础分支独立修复

原失败 Job: https://github.com/cropflre/nowen-note/actions/runs/38058357986/job/114231347386
根因是 AIChatPanel.tsx 中内嵌中文任务命令与提示文案,基础分支 release/v1.5.2 已存在;与本 PR Sync Receipt 逻辑无关。

现已通过独立 PR #825 修复并 squash 合并进 release/v1.5.2(040c428)。中文命令移至独立解析器、UI/回复文案国际化,保留 /待办、创建、完成与今日任务解析规则。新代码未放宽 i18n 扫描。

**注意:**上述老 Job 记录绑定的是旧提交/旧 PR 合并上下文,历史运行不会自动改成绿色;更新本 PR 与基础分支的合并上下文并触发新 CI 后,才能将这项门禁认定为本 PR 最新状态。#821 的 Android 延迟 ACK 真机复验仍待完成,继续保持 Draft。

Non-code commit to request a fresh pull_request CI merge context following base fix 040c428 (#825). No source or test changes.

Copy link
Copy Markdown
Owner Author

Shared lint baseline fix applied

已将 #826 合并后的 release/v1.5.2 更新到本 PR(合并提交 d964fff)。

  • 已修复本 PR 测试文件中新引入的 no-explicit-any、未使用参数等 ESLint 错误,并保留 SQL mock 的类型签名。
  • Issue 612 Data Protection CI 的 Frontend lint 现已通过。
  • I18n 修复 #825 亦已纳入本 PR 基础代码。
  • 仍为 Draft,Android 真机 ACK / 重试 / 冲突验收未完成;不得将 CI 绿灯视为真机验收完成。

Copy link
Copy Markdown
Owner Author

Crypto CI 回归追踪

更新到 release/v1.5.2 后,#821 上一轮 Encrypted Notes CI 曾有 3 个 autoLockEditors 断言失败。定位结果为 PR 分支合入基础代码时误保留了旧 coverageTranslations.ts 的最低密码提示 12 字符,而发布分支 passphrasePolicy.ts 和 coverageTranslations.ts 都以 6 字符为当前有效策略。

已提交 7e474807 精确恢复中英文密码提示及改密说明(4 项文案),未修改加解密和密码验证规则。正在重新运行整套 CI。Android 真机验收仍待完成,继续保留 Draft。

@cropflre
cropflre merged commit c40ca7a into release/v1.5.2 Oct 10, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant