From b4efd4e4f2b47bf8891f23d77a8e3f173f147b7c Mon Sep 17 00:00:00 2001 From: Jinjing <6427696+AmethystLiang@users.noreply.github.com> Date: Wed, 12 Aug 2026 19:10:37 -0700 Subject: [PATCH] fix(persistence): prefer inline folder notes over a stale map entry Hydrate preferred a non-empty folderWorkspaceDiffComments entry over non-empty inline notes. A rollback to a notes-capable #14112 build writes notes inline and leaves the older map untouched, so re-upgrading deleted everything authored while rolled back. Inline now wins when present; the map only fills a stripped record. Co-authored-by: Orca --- src/main/persistence.test.ts | 31 ++++++++++++++++++++++++++----- src/main/persistence.ts | 13 +++++++------ 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/main/persistence.test.ts b/src/main/persistence.test.ts index 01b659cab8c..5e07b9da28e 100644 --- a/src/main/persistence.test.ts +++ b/src/main/persistence.test.ts @@ -5611,15 +5611,36 @@ describe('Store', () => { expect(restored.getFolderWorkspace('fw-1')?.diffComments).toEqual([note]) }) - it('prefers a non-empty map entry and never lets an empty one delete inline notes', async () => { - const inline = makeFolderNote('note-inline', 'Inline note') - const mapped = makeFolderNote('note-mapped', 'Mapped note') + it('keeps notes authored inline on a rolled-back #14112 build over a staler map entry', async () => { + const mapped = makeFolderNote('note-mapped', 'Note from the fixed build') + const authored = makeFolderNote('note-inline', 'Note authored while rolled back') writeFolderWorkspaceProfile({ - workspaces: [folderWorkspaceRecord({ diffComments: [inline] })], + workspaces: [folderWorkspaceRecord()], diffCommentsMap: { 'fw-1': [mapped] } }) - expect((await createStore()).getFolderWorkspace('fw-1')?.diffComments).toEqual([mapped]) + // #14112 persists notes inline and never learned about the top-level map, so a note authored + // there lands inline while the untouched map entry goes stale. Inline is the newer write. + const rolledBack = readDataFile() as PersistedState + writeDataFile({ + ...rolledBack, + folderWorkspaces: rolledBack.folderWorkspaces.map((workspace) => ({ + ...workspace, + diffComments: [authored] + })) + }) + + const store = await createStore() + expect(store.getFolderWorkspace('fw-1')?.diffComments).toEqual([authored]) + store.flush() + expect((readDataFile() as PersistedState).folderWorkspaceDiffComments).toEqual({ + 'fw-1': [authored] + }) + }) + + it('never lets an empty or unrelated map entry delete inline notes', async () => { + const inline = makeFolderNote('note-inline', 'Inline note') + const mapped = makeFolderNote('note-mapped', 'Mapped note') writeFolderWorkspaceProfile({ workspaces: [folderWorkspaceRecord({ diffComments: [inline] })], diff --git a/src/main/persistence.ts b/src/main/persistence.ts index 21551f6f54e..6f09f5ce025 100644 --- a/src/main/persistence.ts +++ b/src/main/persistence.ts @@ -2913,16 +2913,17 @@ export class Store { const stored = this.state.folderWorkspaceDiffComments let relocatedInline = false for (const workspace of this.state.folderWorkspaces ?? []) { + if (Array.isArray(workspace.diffComments) && workspace.diffComments.length > 0) { + // Inline wins: an intervening rollback to a #14112 build writes notes inline and leaves the + // older map untouched, so inline is the last notes-aware write. Also makes the relocation + // durable even if the user never edits anything this session. + relocatedInline = true + continue + } const comments = stored?.[workspace.id] // Not `??`: a degenerate `{ id: [] }` entry must not delete an intact inline value. if (Array.isArray(comments) && comments.length > 0) { workspace.diffComments = comments - continue - } - if (Array.isArray(workspace.diffComments) && workspace.diffComments.length > 0) { - // Legacy inline notes from an unreleased #14112 profile; make the relocation durable - // even if the user never edits anything this session. - relocatedInline = true } } if (relocatedInline) {