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 -4
View File
@@ -565,12 +565,26 @@ func (s *Store) IsDocShared(docID string) bool {
return n > 0
}
// --- Adapter for the existing whole-document API (PUT /documents/{id}) ---
// SetBlockChecked ticks or unticks a block through the log (server-side change, e.g. a linked task was
// completed). Returns true if the block changed.
func (s *Store) SetBlockChecked(userID, docID, blockID string, checked bool) bool {
a := collab.Actor{UserID: userID, ClientID: "server"}
results, _, err := s.applyDocChange(docID, a, nil, func(d *collab.Doc) []collab.Op {
b, ok := d.Blocks[blockID]
if !ok || b.Deleted || b.Props.Checked == checked {
return nil
}
return []collab.Op{{OpID: domain.NewID("op"), Kind: collab.OpSetProps, BlockID: blockID, Patch: &collab.PropsPatch{Checked: &checked}}}
})
return err == nil && len(results) > 0 && results[0].Seq > 0
}
// --- Writing a complete block list (new notes, imports) ---
const legacyClientID = "legacy"
// replaceDocBlocksInDB stores a complete flat block list by diffing it against the current tree and
// applying the difference as regular operations, so it shows up in the log like any other change.
// replaceDocBlocksInDB stores a complete flat block list (initial blocks of a new note, old blocks_json data)
// by diffing it against the current tree and applying the difference as regular operations.
func (s *Store) replaceDocBlocksInDB(docID, userID string, blocks []domain.DocumentBlock, _ string) {
blocks = s.renameForeignBlockIDs(docID, blocks)
a := collab.Actor{UserID: userID, ClientID: legacyClientID}
@@ -602,7 +616,7 @@ func (s *Store) renameForeignBlockIDs(docID string, blocks []domain.DocumentBloc
return out
}
// applyLegacyTitle records a title change from the whole-document API in the log.
// applyLegacyTitle records a title change made through PUT /documents/{id} in the log.
func (s *Store) applyLegacyTitle(docID, userID, title string) {
a := collab.Actor{UserID: userID, ClientID: legacyClientID}
if _, _, err := s.applyDocChange(docID, a, nil, func(d *collab.Doc) []collab.Op {