feat(draft): prevent conflicting autosave overwrites - #2776
Conversation
SafeDep Report SummaryNo dependency changes detected. Nothing to scan. This report is generated by SafeDep Github App |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a2621cff19
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (existing) { | ||
| throw createAppException(AppErrorCode.DRAFT_VERSION_CONFLICT, { |
There was a problem hiding this comment.
Avoid treating retained published drafts as concurrent creates
When editing a document that was previously published from a draft, markAsPublished() retains that draft row while findByRef() hides it whenever publishedVersion === version. The admin therefore receives no baseline, attempts createDraft() on its first autosave, and this branch reports a version conflict against the retained row. Consequently, every normal editing session for such a document presents a false conflict and requires the user to choose between discarding or forcibly keeping their changes even though no concurrent writer exists; distinguish an unchanged published draft from an actual competing create or expose it as the initial baseline.
Useful? React with 👍 / 👎.



Summary
expectedVersionand a database compare-and-swap update409 DRAFT_VERSION_CONFLICTresponse instead of silently overwriting a newer draftRoot cause
Draft updates previously used unconditional last-write-wins semantics. A browser retained no server revision in its save request, so a stale tab could overwrite a newer draft without either client observing a conflict.
Impact
Editors opened in multiple browsers now preserve non-overlapping changes automatically. Overlapping edits remain local and require an explicit resolution before autosave or publication can continue.
Validation
pnpm -C apps/admin exec vitest run src/api/http.test.ts src/features/write/utils/merge-draft-conflict.test.ts— 10 tests passedpnpm -C apps/core exec vitest run test/src/modules/draft/draft.service.spec.ts— 9 tests passedpnpm -C apps/admin typecheckgit diff --check