fix: prevent checklist state loss from sync race condition

Two issues caused checked items to revert after closing:

1. loadNotes() blindly overwrote the store with notes.set(), so a stale
   response from the periodic sync (every 30s) could replace a just-saved
   note with older server data. Now merges by version number, keeping the
   higher-versioned note.

2. Checklist component ignored external content prop changes (from sync or
   history restore). Added $effect that re-parses items when the content
   prop changes from an external source, using lastEmitted tracking to
   distinguish self-originated vs external updates.

https://claude.ai/code/session_01TdPpATUkmdY7DhBkmqrvWs
This commit is contained in:
Claude
2026-03-21 20:27:38 +01:00
committed by Fred Cabassut
parent 65b7a9fe36
commit ee017ab550
4 changed files with 140 additions and 3 deletions
+20
View File
@@ -60,6 +60,26 @@ test.describe('Checklist', () => {
await expect(page.getByTestId('checklist-done-checkbox').first()).toBeChecked();
});
test('Scenario: Multiple checked items persist after closing and reopening', async ({ authenticatedPage: page }) => {
// Given a checklist note with three items exists
await createChecklistNote(page, 'Groceries', ['Milk', 'Eggs', 'Bread']);
// When the user reopens and checks two items
await noteCard(page, 'Groceries').click();
await page.getByTestId('checklist-checkbox').nth(0).click(); // Milk → done
await page.getByTestId('checklist-checkbox').nth(0).click(); // Eggs (now first) → done
// Then the done section shows two checked items
await expect(page.getByTestId('checklist-toggle-done')).toContainText('2 done');
await page.getByTestId('close-editor-btn').click();
// And the checked state persists after reopening
await noteCard(page, 'Groceries').click();
await expect(page.getByTestId('checklist-toggle-done')).toContainText('2 done');
await expect(page.getByTestId('checklist-input')).toHaveCount(1); // Only Bread remains active
await expect(page.getByTestId('checklist-input').first()).toHaveValue('Bread');
});
test('Scenario: Enter key adds a new checklist item', async ({ authenticatedPage: page }) => {
// Given a checklist with one item
await page.getByTestId('new-note-btn').click();