refactor(notes): remove legacy whole-document saves; all block changes go through sync
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 1m14s

Phase 5 of the collaboration plan:
- Remove PATCH /documents/{id}/blocks, PatchDocumentBlocks, the
  DOC_BLOCKS_PATCHED event and its types, FlushDocumentState and
  LoadDocumentState. PUT /documents/{id} rejects blocks (400) and only
  changes title, icon, folder and pin; editors may now change title/icon.
- The to-do overview ticks via a single operation on /docs/{id}/sync
  (new skipLog flag). Task links set the block tick with a targeted
  operation and notify open editors; creating a linked task needs edit
  rights.
- Keep the three share tables: DocRole already decides centrally, and
  rewriting the visibility queries would only add risk (documented in plan).
- Tests adapted to the new paths; share e2e test now also ticks a to-do in
  the overview.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
sandrodachandClaude Opus 5.5 committed 2026-10-28 14:35:59 +01:00
1 parent 8b7a53daab
commit aea4324c20
18 files changed
+155 -376

No files matched your search

+18
View File
@@ -0,0 +1,18 @@
// Sends a few operations for a note that is not open in an editor (e.g. ticking a to-do in the overview).
// Goes through the same sync endpoint and rules as the editor, so the change is logged and pushed to
// everyone who has the note open.
import type { Op, Result } from './model';
import { httpTransport } from './transport';
export async function sendDocOps(docId: string, ops: Omit<Op, 'opId'>[]): Promise<Result[]> {
const bytes = new Uint8Array(8);
crypto.getRandomValues(bytes);
const clientId = `once_${Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('')}`;
const res = await httpTransport.sync(docId, {
clientId,
lastSeq: 0,
ops: ops.map((op, i) => ({ ...op, opId: `${clientId}.${i}` }) as Op),
skipLog: true,
});
return res.results;
}
+1
View File
@@ -37,6 +37,7 @@ export interface SyncRequest {
lastSeq: number;
ops: Op[];
leases?: { hold: string[]; release: string[] };
skipLog?: boolean; // one-off changes do not need the log back
}
export interface SyncResponse {