Skip to content

fix(server): make Yjs sole writer of Document.content - #86

Merged
Alimedhat000 merged 2 commits into
developfrom
fix/47-yjs-sole-content-writer
Aug 25, 2026
Merged

fix(server): make Yjs sole writer of Document.content#86
Alimedhat000 merged 2 commits into
developfrom
fix/47-yjs-sole-content-writer

Conversation

@Alimedhat000

Copy link
Copy Markdown
Owner

Closes #47

Problem

Document.content had two competing writers:

  • Hocuspocus sync derived plaintext from Yjs state on every debounced store (dbPersistence.ts)
  • REST PUT /document/:id wrote body content straight to Prisma

Last-writer-wins silently discarded collaborative edits. createDoc had the same disease in reverse: it accepted initial content that no reader ever saw (the editor loads from Yjs only) and the first sync wiped it.

Fix — Option A: keep the mirror, single writer

  1. updateDoc: strips content; REST updates are metadata-only (title, isPublic). The dormant client autosave path (use-document.ts handleSave, Reconcile dead autosave hook #35) can be re-wired later without resurrecting the bug.
  2. createDoc: no longer accepts a content param; initializes to ''.
  3. dbPersistence.store(): snapshot + mirror writes now run in one prisma.$transaction (both branches) so they can't drift on partial failure.

Yjs is now the sole writer of content. Read-only consumers are tracked in #84 (search via tsvector, previews, export).

Verification

  • New failing-first test (server/test/document.test.ts) proves PUT cannot change content: red before, green after
  • Full server suite: 44/44 passed, including all 5 ws-auth.test.ts collaboration round-trips proving Yjs→content persistence still works
  • Server lint + typecheck clean
  • Client E2E not run locally

REST update/create could overwrite the Yjs-derived content mirror,
silently discarding collaborative edits (last-writer-wins). Strip
content from both endpoints; also write snapshot + mirror atomically
in dbPersistence.store so they cannot drift on partial failure.

Closes #47
Server ignores REST content writes since #47; align handleSave so a
future autosave re-wire (#35) cannot silently expect text persistence.
@Alimedhat000
Alimedhat000 merged commit 90f8a8e into develop Aug 25, 2026
2 checks passed
@Alimedhat000
Alimedhat000 deleted the fix/47-yjs-sole-content-writer branch August 25, 2026 18:45
Alimedhat000 added a commit that referenced this pull request Aug 25, 2026
Squash-merge of develop (15 commits) onto main:

Security/fixes:
- Yjs as sole writer of Document.content (#86)
- Scope collaboration request decisions to route document (#85)
- Accept email when adding collaborators (#80)
- Fix stale 'view' share link on permission switch (#78)
- Fix deleting shared documents (FK RESTRICT) (#77)
- Re-land WS authentication + exact-ID document resolution (#74)

Features/chore:
- Rate-limit auth endpoints (#79)
- Client quality passes a-f: infra, structure, rules, seams,
  stories, CI (#66-#73)
- Remove leftover debug console.log calls (#75)

Conflicts resolved in favor of develop's supersets
(collaborators dropdown/stories/toolbar, use-collaborators hook,
document tests); pnpm-lock.yaml regenerated.
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