Skip to content

编辑和合并不再覆盖期间别处的改动 - #203

Merged
JunieXD merged 4 commits into
masterfrom
stale-edit-fixes
Oct 31, 2026
Merged

JunieXD merged 4 commits into
masterfrom
stale-edit-fixes

Conversation

@JunieXD

@JunieXD JunieXD commented Oct 31, 2026 •

Copy link
Copy Markdown
Collaborator

为什么改

Codex 审查导师管理、材料、模板、统计和个人资料时,发现三处“旧内容覆盖新内容”:

  1. 编辑导师:编辑弹窗打开期间,这位导师在别处合并、导入或导师库更新拿到了新邮箱、别名、研究方向,旧表单只改姓名再保存,会把这些整份覆盖掉。合并时,被并入的导师已经永久删除,覆盖掉的资料找不回来。
  2. 合并导师:预览时另一位导师还没有草稿,预览之后另一处又给他写了一封首封草稿,再点“合并”时这封新草稿会被直接删掉,用户没看到过提示。
  3. 个人资料:页面开着时 Agent 改了意向研究方向,用户再改姓名,会把研究方向写回旧值。

改了什么

  • updateMentor 多带 before:打开编辑时读到的姓名、别名、邮箱、单位、主页和研究方向。核心用 BEGIN IMMEDIATE 拿到写锁,再拿当前资料和 before 比较;不同就不保存,提示“打开编辑之后,这位导师的资料在别处有了变化……关掉后重新打开,再改一次。”,界面等导师详情重新读取完再显示这条提示,重新打开就是新资料;合并冲突时也等新的预览读到才能再点“合并”。
  • mergeMentors 多带 discardedDrafts,即预览给出的那份。核心在写事务里、删草稿之前重新算一遍,不同就不合并,界面让预览重新读取,用户看过新的预览再合并。Agent 合并时,确认说明也先核对这份清单,确认的和执行时核对的是同一份。要删的草稿按种类排序。
  • ProfileForm 三个字段都改成可选,核心只改传了的字段,空字符串清空。界面每次保存只带这次输入的和还没保存上的字段,已经保存上的不再重发;保存上了的仍按输入的原样显示(行尾的换行和空格不会在输入中途消失),被别处改了就显示新的。ProfileFields 自己读个人资料,免得父组件传进来的资料和保存状态在同一次渲染里对不上。
  • Agent 的操作说明写明 before、discardedDrafts 怎么填,以及 updateProfile 只改传了的字段。
  • 文档:docs/ui.md(编辑资料冲突、个人资料自动保存)、docs/data-model.md(合并草稿)。

怎么验证的

  • 新测试:
    • an_edit_does_not_undo_what_changed_since_it_began:编辑期间别处加了邮箱时不保存;从新资料开始的编辑能保存。
    • a_draft_written_after_the_preview_is_not_discarded
    • blank_fields_are_cleared_and_missing_ones_stay
    • a_merge_is_confirmed_only_with_the_drafts_it_discards(Agent 合并)
    • 界面测试 saves only what is typed and not saved yet, and shows what an Agent saved
    • 界面测试 does not send a field again whose save finished before the page heard of it:拦住 TanStack Query 的通知,模拟保存刚成功、页面还没重新渲染时用户就输入;改之前会把已保存的字段一起重发。
  • 新测试能抓到问题:
    • 第一版的个人资料界面测试在旧的 profile.tsx 上失败;
    • 去掉 mentor::edit 的比较、merge 的草稿核对后,对应的两个测试各自失败;
    • 三个问题在旧代码上都用临时测试复现过(用旧接口写的,没提交)。
  • 本地通过:
    • mentor、profile、matching、writing、email、library、send、task、api、agent 的测试;
    • cargo fmt --check、clippy(tools/check-rust.mjs);
    • pnpm --dir ui check。
  • 本地没过的,都是连本机假邮件服务器的测试,机器负载高时超时:
    • receive 有 7 个,单独重跑 23 个全过;
    • task 有 5 个,用 2 个线程重跑 38 个全过;
    • onboarding 有 2 个、first_approval_previews_the_whole_letter_and_sends_the_dialog_rendering 1 个,单独重跑都过。
  • 完整的 pnpm check 本地太慢(这台机器要近 1 小时),以 CI 为准。

保存只带这次输入的和还没保存上的字段;Agent 合并的确认说明和执行时核对的是同一份要删的草稿;冲突后等新资料读到再提示;编辑改用 BEGIN IMMEDIATE。
上一次保存刚成功、页面还没重新渲染时,输入不再把已保存的字段一起重发。
@JunieXD
JunieXD merged commit 006c416 into master Oct 31, 2026
2 checks passed
@JunieXD
JunieXD deleted the stale-edit-fixes branch October 31, 2026 12:01
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