fix:后端同步时保留仓库本地元数据#147
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR introduces repository metadata preservation during backend synchronization. A new merge utility selectively preserves local metadata fields when updating repositories from the backend, replacing direct overwrite logic in the auto-sync service to prevent loss of local AI summaries, tags, custom descriptions, and related metadata. ChangesRepository Metadata Sync Preservation
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
AmintaCCCP
left a comment
There was a problem hiding this comment.
🔍 Code Review: fix: 后端同步时保留仓库本地元数据
审计人: Hermes Agent
审计模型: z-ai/glm-5.1
CI 状态: ✅ 全部通过 (macOS / Ubuntu / Windows)
TypeScript 编译: ✅ tsc --noEmit 无错误
✅ Looks Good
- 核心思路正确:后端是仓库列表的权威来源,本地仅保护「后端不存的本地专属字段」,语义清晰
- 新增文件职责单一:
repositoryMerge.ts只做一件事——merge local metadata,命名清晰 LOCAL_REPOSITORY_FIELDS用keyof Repository约束:TypeScript 编译器保证字段名与类型定义同步,未来加新字段时类型会帮忙localValue !== undefined的守卫:避免将本地的undefined覆盖后端本有值的情况(尤其对analysis_failed: false很重要)Map查找 O(1):对仓库列表的规模完全合理isBootstrapEmpty分支不受影响:首同步时空后端走 push 逻辑,不会误触发 merge- CI 三平台构建均通过:无回归
⚠️ Warnings (2)
-
subscribed_to_releases字段遗漏Repository类型中subscribed_to_releases?: boolean(L25) 是本地 UI 设置的订阅标记- 在
RepositoryList.tsx:775和ReleaseTimeline.tsx:507中由用户操作本地写入 - 但未列入
LOCAL_REPOSITORY_FIELDS,后端同步时会丢失 - 建议加入:
'subscribed_to_releases',
-
合并后
_lastHash.repos基于后端原始数据,但 store 中已混入本地字段autoSync.ts:144:_lastHash.repos = hashes.repos— 这里的hashes.repos是quickHash(backendRepos),即后端原始数据的哈希- 但实际写入 store 的是 merge 后的数据(含本地字段),下次
syncToBackend时_lastHash.repos = quickHash(state.repositories)用的是合并后的数据 - 场景:用户 A 完成分析 → push 到后端 → 后端存了
ai_summary→ 用户 B pull 时 merge 保留 → B push 时后端也有ai_summary→ 此时没问题 - 但如果后端不持久化这些本地字段(SQLite 可能 ignore unknown columns),pull 回来的数据永远不含本地字段 → hash 始终不同 → 每次 poll 都会触发
setRepositories→ 合并后的 store 引用变了 → 触发 push → 5s 后又 pull… 形成不必要的写循环 - 严重程度:中。数据不会丢(merge 每次都保护),但造成了多余的 store 更新和 push 操作。建议把 hash 改为对 merge 后的数据计算:
const merged = mergeRepositoriesPreservingLocalMetadata(backendRepos, localRepos); _lastHash.repos = quickHash(merged); state.setRepositories(merged);
💡 Suggestions (2)
-
starred_at字段是否需要保留?starred_at是从 GitHub API 返回的,后端fetchRepositories是否保留此字段取决于后端 SQLite schema。如果后端不存该字段,pull 后starred_at丢失,影响按 starred 时间排序(SearchBar.tsx:428)。建议确认后端是否持久化starred_at,如果不存则加入保留列表。
-
as Record<keyof Repository, unknown>类型断言可简化- 当前
mergedRepository已经是Repository类型,LOCAL_REPOSITORY_FIELDS是Array<keyof Repository>,直接赋值mergedRepository[field] = localValue在严格模式下会因类型不统一报错。断言合理,但可以改为:更直观,语义上是「可写的字典」,不需要const mergedRepository = { ...incomingRepository } as Record<string, unknown>;
Record<keyof Repository, unknown>那么精确。
- 当前
审计总结
| 类别 | 数量 |
|---|---|
| 🔴 Critical | 0 |
| 2 | |
| 💡 Suggestion | 2 |
结论:Comment — 两个 Warning 都不阻塞合并(数据不会丢失),但建议尽快补充 subscribed_to_releases 字段,并评估 hash 循环写问题。功能逻辑正确,代码整洁,CI 全绿。
Reviewed by Hermes Agent (z-ai/glm-5.1)
变更说明
修复后端同步仓库列表时,本地已有的仓库级元数据被覆盖的问题。
当前自动同步从后端拉取 repositories 后会直接调用
setRepositories(backendRepos),如果后端返回的仓库对象缺少本地已有字段,会导致已完成的 AI 分析信息丢失,例如:ai_summaryai_tagsai_platformsanalyzed_atanalysis_failed本次修改在后端仓库列表写入本地 store 前,对同一
repo.id的仓库进行合并:仍以后端返回的仓库信息为基础,但保留本地已有的 AI 分析字段和仓库级本地元数据。保留的本地字段
行为说明
验证
已在windows本地进行覆盖安装验证,由于mac不在身边,麻烦你来验证了
Summary by CodeRabbit