Unit tests:
- shares-service: create, idempotent create, revoke, get, batch fetch
- ip-rate-limit: under/over limit, IP independence, window reset
E2E tests:
- Create public share link via UI
- Public page renders without auth
- Revoke share returns 404
- Trashed note share returns 404
- Globe icon on shared card
- Copy link to clipboard
Also fix sharing-indicator test-id in existing sharing.spec.ts
and add shared_notes table to test-helpers and db/index.ts init.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Concurrent edits to shared notes (e.g., one user checks a shopping list
item while another adds an item) were lost because the sync system used
whole-document Last-Write-Wins. This replaces it with a 3-way line-level
content merge using node-diff3, so changes to different lines are
preserved from both users.
Key changes:
- Add node-diff3 for 3-way line-level content merging
- Remove the timestamp gate in processSyncPush that rejected entire
offline sync pushes when another user had updated the note
- Add content merge to both the sync push path and the PATCH endpoint,
using version snapshots as the merge base
- Send baseVersion from the client so the server can find the correct
common ancestor for 3-way merge
- Protect pending local fields during client pull merge by reading
the sync queue and preserving queued-but-unpushed changes
- Add comprehensive tests for content merge, server sync, and CRDT merge
https://claude.ai/code/session_01FNpVBBjM6vKzfR8y9NM9Ci
Settings tests set defaultNoteMode to 'markdown' without resetting,
causing parallel sharing test to timeout when TiptapEditor wasn't
rendered (textarea shown instead). Two fixes:
- Reset preferences in settings tests after changing them
- Create note via API in sharing test (tests sharing, not note creation)
- Remove duplicate bold formatting test from notes-crud.spec.ts
- Trim formatting.spec.ts from 9 to 5 tests (remove italic, inline code,
toolbar bold, toolbar visibility — same mechanism as bold shortcut)
- Remove hardcoded waitForTimeout(500) from search.spec.ts (Playwright
assertions already retry with built-in timeouts)
- Restructure sharing.spec.ts: 9 serial tests → 5 parallel self-contained
tests using collabPage fixture and API-based setup
- Add collabPage fixture to helpers/fixtures.ts for sharing tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
getChangesSince was returning the owner's pinned/archived/sortOrder
for shared notes instead of the collaborator's per-user values from
noteUserState. Also filtered trashed notes from collaborator sync.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Serial test suite covering: owner shares note, collaborator sees it,
collaborator edits content, independent pin state, leave action shown
for non-owners, collaborator leaves and note disappears.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>